Solution Ancient crackme
Solution Ancient crackme
Blush

[Image: Seven-23-21-09.png]

Allez, je me tente à faire un writeup.

Au début, j'ai voulu faire mon bonhomme et le faire en statique. (Je fais beaucoup de crackme en statique)
J'ai fait un script IDC vite fait pour essayer de l'unpacker, mais le résultat reste imbitable.

Code :
#include <ida.idc>
#define  SEGMENT "seg001"
#define  COUNT   0x0132
#define  PATCH   0x0D04

static segToAddr(segment, offset)
{
    auto base = SegByName(segment) * 0x10;
    return base + offset;
}

static applyPatch(base, offset, value)
{
    auto addr = base * 0x10 + offset;
    Message("%04X = %04X\n", addr, value);
    PatchWord(addr, value);
}

static main(void)
{
    auto addr;
    auto base;

    /* Set initial address */
    addr = segToAddr(SEGMENT, COUNT);

    /* For each es */
    for(base = 0x0000; base < 0xF000; base = base + 0x1000) {
        auto count;
        auto i;

        /* Read how many patches to apply for this es */
        count = Word(addr);
        addr  = addr + 2;

        /* Apply each patch */
        for(i = 0; i < count; i++) {
            applyPatch(base, Word(addr), PATCH);
            addr = addr + 2;
        }
    }
}
/* seg000:3CD8 sub_13CD8  */

Je sais pas s'il faut blâmer le binaire, le langage (VBA) ou les outils.
Bref, je suis passé en dynamique.

Le problème c'est que c'est pour un truc tellement vieux que je connais pas les bons outils.
J'ai commencé avec DEBUG.EXE sur Windows XP.
Citation :Q pour quitter
G pour aller à une adresse (breakpoint)
P pour aller à l'instruction suivante (step over)
U pour désassembler
D pour dumper (memory viewer)

Tant que le crackme me demande pas username/serial, je step over.
Si je vais trop loin, je quitte et je fais G XXXX:YYYY pour revenir où j'étais avant.
Le but étant de me trouver l'adresse juste après que le crackme me demande username/serial.

Code :
0D04:013B EB04 JMP 0141 ; after serial read()

On peut avoir un IDA ouvert à côté pour avoir une meilleure vue de ce qu'on fait.

[Image: Seven-23-35-50.png]
Au royaume des aveugles, les borgnes sont rois.

En débuggant un peu, on comprend que :
* 0023:3067 renvoie la taille de la chaîne en paramètre
* 0x3A fait référence au serial
* 0x36 fait référence à l'utilisateur

Comme DEBUG.EXE a une interface du tiers monde, j'ai cherché autre chose.
J'ai essayé Bochs, Freedos, et DOSBox.
DOSBox est vraiment bien, je vous le conseille si vous devez voyager dans le temps pour résoudre des crackmes.
URL: http://www.dosbox.com/download.php?main=1
Debugger: http://source.dosbox.com/dosbox-74-debug.exe
Guide: http://www.vogons.org/viewtopic.php?t=3944

Avec DOSBox, on a une sorte de débugger kernel, ça devient ridiculement simple :
On lance l'application, on rentre un login, un serial.
Comme c'est faux l'application nous dit "Sorry", "Press enter to quit?"
On appelle le debugger avec alt-pause
Dans la fenêtre du debugger on va voir la stack avec alt-s
Et là bam, on voit tout plein d'infos :

[Image: Seven-23-50-09.png]

L'algo est assez trivial :
Code :
seg000:0167 loc_10167:                              ; CODE XREF: seg000:0161j
seg000:0167                 mov     ax, 36h ; '6'
seg000:016A                 push    ax
seg000:016B                 call    far ptr 23h:3067h ; strlen(user)
seg000:0170                 add     ax, 1337
seg000:0173                 call    far ptr 3C1h:3C8h
seg000:0173 ; ---------------------------------------------------------------------------
seg000:0178                 db 0CDh ; -             ; INT 35
seg000:0179                 db  35h ; 5
seg000:017A ; ---------------------------------------------------------------------------
seg000:017A                 push    ds
seg000:017B                 db      3Eh
seg000:017B                 add     ch, cl
seg000:017E                 cmp     ax, 36FFh
seg000:0181                 inc     ax
seg000:0182                 add     bh, bh
seg000:0184                 db      36h
seg000:0184                 add     ds:[bp+si+3610h], bl
seg000:018A                 and     ax, [bx+si]
seg000:018C                 push    ax
seg000:018D                 mov     ax, 42h ; 'B'
seg000:0190                 push    ax
seg000:0191                 call    far ptr 23h:2F88h ; convert int to str (0x42) ?
seg000:0196                 mov     ax, 42h ; 'B'
seg000:0199                 push    ds
seg000:019A                 push    ax
seg000:019B                 xor     ax, ax
seg000:019D                 push    ax
seg000:019E                 mov     ax, 142h
seg000:01A1                 push    ax
seg000:01A2                 mov     ax, 1
seg000:01A5                 push    ax
seg000:01A6                 push    ax
seg000:01A7                 call    far ptr 23h:33DCh
seg000:01AC                 mov     ax, 148h
seg000:01AF                 push    ax
seg000:01B0                 mov     ax, 36h ; '6'
seg000:01B3                 push    ax
seg000:01B4                 call    far ptr 23h:2FC1h ; Concat "OLD-" and user
seg000:01B9                 push    ax
seg000:01BA                 mov     ax, 150h
seg000:01BD                 push    ax
seg000:01BE                 call    far ptr 23h:2FC1h ; Concat ret and -A
seg000:01C3                 push    ax
seg000:01C4                 mov     ax, 42h ; 'B'
seg000:01C7                 push    ax
seg000:01C8                 call    far ptr 23h:2FC1h ; concat ret and serial
seg000:01CD                 push    ax
seg000:01CE                 mov     ax, 3Ah ; ':'
seg000:01D1                 push    ax
seg000:01D2                 call    far ptr 23h:2FFEh ; strcmp ret with serial

Le serial est : "OLD-" + user + "-A" + (serial + 1337)

Solution Ancient crackme
gratzz, Wink

Le code pour les curieux:
Code :
'Xyl2k
COLOR 6, 9
1
CLS
PRINT ""
PRINT " ___ ___         __ __ __          __ "
PRINT "|   |   |.--.--.|  |__|  |_.-----.|  |"
PRINT "|-     -||  |  ||  |  |   _|  _  ||  |"
PRINT "|___|___||___  ||__|__|____|_____||__|"
PRINT "         |_____|   Ancient CrackMe    "
PRINT ""

INPUT "Name   : ", nom$
IF LEN(nom$) < 3 THEN
  GOTO 1
END IF

2
CLS
PRINT ""
PRINT " ___ ___         __ __ __          __ "
PRINT "|   |   |.--.--.|  |__|  |_.-----.|  |"
PRINT "|-     -||  |  ||  |  |   _|  _  ||  |"
PRINT "|___|___||___  ||__|__|____|_____||__|"
PRINT "         |_____|   Ancient CrackMe    "
PRINT ""
PRINT "Name   : "; nom$
INPUT "Serial : ", ser$
IF LEN(ser$) < 6 THEN
  GOTO 2
END IF
s = LEN(nom$) + 1337
final$ = STR$(s)
MID$(final$, 1, 1) = "AX"
IF ser$ = "OLD-" + nom$ + "-" + final$ THEN
  GOTO 3
ELSE
  GOTO 4
END IF
3
PRINT "Nice work"
GOTO 5
4
PRINT "Sorry"
GOTO 5
5
PRINT ""
INPUT "Press enter to quit"; nom$
SYSTEM

[Image: RINuJIe.png]
Le compilo a plus de 27 ans et ça tourne sur win7, c'est beau quand même la rétrocompatibilité.