Ergebnis 1 bis 4 von 4

Thema: [NYC09] - 06 - Pure Virtual CrackMe

  1. #1
    Moderator
    Registriert seit
    Aug 2004
    Beiträge
    1.310
    Renommee
    1286

    [NYC09] - 06 - Pure Virtual CrackMe

    Pure Virtual CrackMe
    ======================

    Eure Aufgabe ist es das CrackMe von kopiluwak zu lösen. Der Schwerpunkt liegt dieses mal allerdings nicht auf dem Umgang mit dem Debugger. Es geht um eure Fähigkeit Details zu entdecken, Schlüsse daraus zu ziehen und um die Benutzung einer Suchmaschine eurer Wahl.
    Es wird für diese Challenge KEIN Binary geben. Das bedeutet, dass ihr euch alle Informationen, um diese Aufgabe zu lösen aus dem Netz suchen müsst.
    Wenn ihr Fragen habt, schickt mir eine PN oder nutzt diesen Thread. Achtet bitte darauf, dass ihr nichts postet was die Sache für andere weniger spanned macht. Falls es Ergänzungen oder Hinweise geben sollte, werde ich sie ebenfalls hier posten.

    Sshickt eure Lösung an pointer_9 a_mit_kringel hotmail.com


    Punkteverteilung:
    ~~~~~~~~~~~~~~~~~~~
    Code:
    1. Funktionierender Keygen            [ 3 Punkte ]
    2. Keygen Tutorial                    [ 2 Punkte ]
    3. Funktionierender Patcher/Loader    [ 3 Punkte ]
    4. Patcher/Loader Tutorial            [ 2 Punkte ]
    Wie auch letztes Jahr gibt es wieder einen einzigen Bonuspunkt unter den Teilnehmern dieser Challenge zu vergeben. Den bekommt derjenige mit dem optisch oder akustisch ansprechendsten Keygen/Patcher/Loader oder Tutorial.

    Hier zur Sicherheit nochmal der Link zu kopiluwaks Profil.


    Viel Spass,
    nait

  2. #2
    Moderator
    Registriert seit
    Aug 2004
    Beiträge
    1.310
    Renommee
    1286

    Re: [NYC09] - 06 - Pure Virtual CrackMe

    Es gibt natürlich auch Punkte auf Teillösungen und Ansätze. Also nur keine falsche Bescheidenheit falls ihr es nicht lösen könnt.

  3. #3
    Moderator
    Registriert seit
    Aug 2004
    Beiträge
    1.310
    Renommee
    1286

    Re: [NYC09] - 06 - Pure Virtual CrackMe

    Hi!

    Der Contest ist seit ein paar Stunden vorbei und eigentlich sollte jetzt die Auflösung kommen.
    In anbetracht der Tatsache, dass die Aufgabe sehr schwer war, biete ich euch zwei Möglichkeiten wie die Auflösung hier 'rein kommt.
    1. Ihr sagt, ich hab keine Lust mehr und möchte die Lösung sofort. Dann poste ich ein kurzes Tutorial mit der Lösung.
    2. Ihr postet das was ihr habt oder auf die schnelle finden könnt und findet zusammen eine Lösung. Oft steckt das Problem im Detail und dann ist es hilfreich wenn jemand mit einem anderen Blickwinkel drauf schaut. Ich werde, wenn es nötig ist, mit Tipps aushelfen.


    Eure Wahl. Wie wollt ihr es haben?

  4. #4
    Moderator
    Registriert seit
    Aug 2004
    Beiträge
    1.310
    Renommee
    1286

    Re: Selbstmodifizierendes CrackMe

    Damit die Aufgabe nicht ungelöst bleibt, ist hier eine kurz gefasste Lösung.

    kopiluwak's pure virtual crackme
    ----------------------------------

    Ein kurzer Walkthrough. Also gut, was haben wir? Es gibt einen link auf das Profil von kopiluwak.

    Das Profil
    ------------
    Auf seiner Profilseite können wir folgende Informationen finden:
    Code:
    Benutzername:   kopiluwak
    Signatur:       "Shall we play a game?"
    Vorname:        Joshua
    Fähigkeiten:    Windows-Programmierung, Grundlagen Assembler, Pascal/Delphi, Debugging
    Ausserdem stellen wir fest, dass Joshua 5 Beiträge erstellt hat. Die sollten wir uns mal ansehen.
    Alle Beiträge wurden zum Thema "Selbstmodifizierendes CrackMe" erstellt. Das bedeutet wohl, dass es nur einen Grund gab hier zu posten.
    Wenn wir den Thread aufmerksam lesen, finden wir folgende Details heraus:
    • Er benutzt Visual C++ 2008 Express Edition
    • Er hat die Code-Optimierung des Compilers abgeschaltet
    • Es gibt Code-Schnipsel die offensichtlich zur Prüfung der Eingabe gehören


    Aber die Aufgabenbeschreibung hat ja schon vorgegeben, dass es wo anders noch mehr Informationen geben kann.
    Dann machen wir uns mal auf die Suche.

    Die Suche
    -----------
    Wenn ich bei google nache kopiluwak suche, finde ich als erstes den Wikipedia-Eintrag über eine Kaffeesorte, die sich ähnlich schreibt und deren Bohnen aus dem Exkrement des Fleckenmusang gesammelt werden. Interessant was die Leute so trinken, aber nicht hilfreich. Also sage ich google erstmal, dass ich darauf bestehe das Wort so zu suchen wie ich es eingegeben habe. Das macht man indem man ein + vor das Wort stellt. Das gibt schon mal andere Ergebnisse aber immer noch nichts brauchbares. Dann erweitern wir unseren Suchbegriff einfach mal mit der Signatur. Die meisten Leute verwenden immer wieder den selben Nickname und in dem Zuge oft auch die gleiche Signatur. Mal sehen...
    Ich gebe die Signatur gleich in Anführungszeichen ein damit nach der vollständigen Signatur und nicht nach dem einzelnen Worten gesucht wird. Und siehe da nur zwei Treffer. Beide mit der Überschrift "[Habo] | Code Kitchen | Problem [C++/QT] Segmentation Fault".

    Das HaBo-Forum
    ----------------
    Die Antwort in diesem Thread sieht so aus als wäre sie auch von unserem kopiluwak, nur dass es dieses mal seinen Vornamen als Nick verwendet hat. Die Signatur ist gleich und auch hier taucht der Kaffee wieder auf. Allerdings gibt es in diesem Thread keine Informationen zu dem CrackMe. Aber schauen wir uns mal sein Profil an.
    Wir haben jetzt einen E-Mail-Adresse, ein Geschlecht (männlich) und ein Geburtsdatum (17.04.1984). Orwell läst Grüßen.
    Schauen wir mal was er sonst noch so geschrieben hat. Die Boardsuche gibt 3 Treffer zum Benutzer joshua.

    Problem [C++] Zeiger und Objekte
    Frage Speicher Handle und Pointer
    Problem [C++/QT] Segmentation Fault

    Das Seg-Fault-Thema kennen wir schon. Was geben die beiden anderen her?
    Er scheint den Großteil seiner Posts mit JKF zu unterschreiben. Vielleicht bezieht sich der Eintrag den er erstellt hat auch auf sein CrackMe, aber daraus könnten wir nur mitnehmen, dass er GetWindowText zum auslesen der Eingabe verwendet.

    Zurück zur Suchmaschine
    -------------------------
    Was haben wir noch? Da wir jetzt wissen, dass er auch seinen Vornamen als Nick verwendet, können wir ja mal nach seiner Signatur und seinem Namnen suchen. Erster Treffer bei google "WarGames (1983) - Memorable quotes". Ein bisschen was nostalgisches gefällig? Schaut euch den Wikipedia Artikel (oder besser den Fim) an.
    Na gut, es muss also anders gehen. Wenn die Signatur nicht hilft, dann bringt uns vielleicht seine Unterschrift weiter, er signiert öfters mit JKF.
    Benühen wir wieder google und suchen nach
    +kopiluwak jkf
    Den ersten Treffer kennen wir. Der zweite sieht interessant aus. Die beiden anderen scheinen von google dazu gekommen zu sein, weil angenommen wurde, dass wir statt jkf jfk schreiben wollten und damit Kennedy meinten.
    Also schauen wir uns doch mal bei GameDev.net um.

    GameDev
    ---------
    Was gibt es hier zu finden? Er möchte offensichtlich einen alten Effekt aus den C64 Zeiten nachempfinden. Der Effekt nennt sich FLD (Flexible Line Distance) und war zu 64'er Zeiten sehr beliebt für Laufschriften in Demos. Offensichtlich hat niemand auf das Post geantwortet. Allerdings hat er das Ergebnis seiner Arbeit gepostet. Die Sourcen nehmen wir erstmal mit.

    Bestandsaufnahme
    ------------------
    Was haben wir bis jetzt? Informationen über seine Entwicklungsumgebung, den Code zur Überprüfung der Benutzer-Passwort-Kombination und eine Klasse die einen alten Demo Effekt mit einem Text auf ein Fenster malt.
    Wenn ihr wissen wollt wie der Effekt aussieht könnt ihr bei google Bildersuche nach FLD "flexible line distance" suchen und findet dort zum Beispiel die Seite von shamedesigns, die unter anderem diesem Effekt in javascript und HTML nachgecodet haben.
    Wenn wir uns sein letztes Post bei BuHa ansehen, stellen wir fest, dass die Screenshots dem FLD-Effekt sehr nahe kommen. Wahrscheinlich gehört die Klasse zum CrackMe. Schauen wir uns doch mal die Sourcen an. Der Großteil des Codes dient dazu den Text als Laufschrift über den DeviceContext zu bewegen und dafür zu sorgen, dass das rein- und raus-laufen des Texts ordentlich abläuft. Was allerdings überhaupt nicht zu dieser ganzen Arbeit passt, ist die Methode
    Code:
    DWORD FLD_effect::get_sample_value(char* p_control_string)
    {
       int   offset            = 0;
       int   value             = 0;
       int   total                   = 0;
       unsigned char  sample_value   = 0;
       DWORD sample_combined         = 0;
       int   text_len                = strlen( p_control_string );
       DWORD color_ref               = 0;
       DWORD xor_value               = 0;
       char* p_end                   = NULL;
    
       if(10 <= text_len )
       {
          xor_value = strtoul( &(p_control_string[text_len - 8]), &p_end, 16);
          text_len -= 8;
       }
       else
       {
          //DO NOTHING HERE
       }
    
       text_len /= 2;
    
       for(int index = 0; index < text_len; ++index)
       {
          offset = *p_control_string;
          offset %= m_effect_width;
          ++p_control_string;
          value = *p_control_string;
          ++p_control_string;
    
          sample_combined = 0;
          for(int sample_divisor = 1; sample_divisor < 5; ++sample_divisor)
          {
             sample_value =  0;
    
             for(int line = 0 + 5; line < 8 + 5; ++line)
             {
                color_ref = GetPixel(m_anim_dc, offset/4 + 5*sample_divisor, line);
    
                sample_value <<= 1;
    
                if( 0 == color_ref )
                {
                   sample_value |= 1;
                }
                else
                {
                   //DO NOTHING HERE
                }
             }
             sample_combined <<= 8;
             sample_combined |= sample_value;
          }
    
          sample_combined *= y_coord_list[value % (sizeof(y_coord_list)/sizeof(y_coord_list[0]))];
    
          total += sample_combined;
       }
    
       total ^= xor_value;
    
       return total;
    }
    Scheinbar errechnet sie einen Wert anhand eines Control-Strings. Wenn der Text länger als 10 Zeichen ist, werden die letzten 8 Zeichen als Hex-Wert interpretiert und fallen damit (durch das textlen -= 8 ) aus dem Steuercode heraus.
    Anschliessend wird für jedes verbleibende Zeichen aus dem Control-String ein Offset in den DeviceContext des animierten Textes ermittelt, um an diesem in dem Buffer eine senkrechte Reihe von 8 Pixeln als Byte zu interpretieren. Schwarz ist ein gesetztes Bit, alles andere ein nicht gesetztes.
    Wenn dieses Byte ermittelt wurde, wird es mit dem Wert aus der y-Koordinate an der Stelle des ASCII-Wertes (mit wrap around falls die Zahl zu groß ist) multipliziert.
    Alle so ermittelten Werte werden auf-addiert und zum Schluss mit dem ganz zu Anfang erstellten xor-Wert ver-XOR-ed. Das ist der errechnete Rückgabewert.
    Wenn so eine komplizierte Berechnung gemacht wird, ohne den Wert für die Animation zu brauchen, dann ist es schon sehr wahrscheinlich, dass das der Wert der in "value" aus dem Post auf BuHa steht.
    Was folgt daraus? Dass das Ziel sein muss einen Keygen zu schreiben, der die obere Funktion so umsetzt, dass der Wert 1953063278 für den eingegebenen Namen herauskommt.

    Den Keygen hätten wir also schon. Wie können wir den Patch machen?


    Patching
    ----------
    Die Schwierigkeit ür dieses Programm einen Patcher zu schreiben ist, dass wir nicht wissen an welcher Adresse der Check liegt. Sonst wäre das Ganze eine einfacher one byte patch, da kopiluwak den klassischen Fehler begangen hat und eine einfache if-else kombination verwendet hat.
    Wie findet man die Adresse heraus? Relativ einfach. Wir haben den Code den wir patchen müssen den Compiler und die Einstellungen. Also können wir uns diesen Schnipsel vornehmen und ihn kompilieren und als assembler-Dump ausgeben (oder im Debugger ansehen). Dabei reicht es schon die Funktion
    Code:
    __declspec(naked) void detour()
    zu übersetzen. Dort finden wir nämlich eine Code-Signatur die den Wert 0x7469616E enthält. Das ist an der stelle wo im disassembly cmp eax, 7469616E (oder ein anderes Register) steht.
    Natürlich ist die Adresse nicht gleich, aber wir wissen jetzt, dass wir nach dem Wert 7469616E in dem Binary (genauer gesagt in der Code-Section) suchen können und das mit höchster Wahrscheinlichkeit genau vor dem jne liegt den wir patchen müssen.
    Hört sich doch einfach an oder? ;-)

    Nachtrag
    ----------
    Ich überlasse es dem geneigten Leser aus der Beschreibung funktionsfähige Programme zu erstellen.

    Viel Spass

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Ähnliche Themen

  1. Image in Virtual Server oder Virtual PC einbinden?
    Von brave_snoopy im Forum Windows
    Antworten: 0
    Letzter Beitrag: 22.04.2006, 13:45
  2. Pure-CSS-Menü
    Von Deever im Forum Web Development
    Antworten: 2
    Letzter Beitrag: 22.10.2004, 19:01
  3. pure-ftpd
    Von hoi_hoi im Forum UNIX/Linux
    Antworten: 1
    Letzter Beitrag: 25.07.2004, 16:55
  4. pure-ftpd funzt nur unkonfiguriert!
    Von Deever im Forum UNIX/Linux
    Antworten: 6
    Letzter Beitrag: 15.08.2003, 15:39
  5. Pure Virtual Function
    Von Jankey im Forum C / C++
    Antworten: 2
    Letzter Beitrag: 24.07.2002, 15:37

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •