CrackMe® Practices for Newbies
Project 9: CrackMe 2 by Cronos

Re: Re: Re: KeyGen
Thursday, 08-Apr-99 14:14:24

    OK. Some spoilers. I'll up the sourcecode if anyone has somewhere for it to go.

    First the program itself:
    It is a FORTH interpreter. I used to be into FORTH quite a lot at one time, and wrote several TILs. This was knocked up in a couple of hours. Basically in FORTH each word of the language is compiled into either ASM or a set of pointers to other FORTH words. The inner interpreter is taking the outermost definition, and working through the list of routines. Each of those is either an ASM routine or a different FORTH word. Hence the pointer 'at the start of each routine'. This either points to a routine which says 'this is an asm definition, so jump to it' or it says 'this is an upper level definition, so interpret it in terms of other definitions'. The subset I have used is fairly small, and I have obviously cut out a lot of the FORTH overhead and things like keywords. Once you learn to ignore the inner interpreter and just look at the individual definitions it all becomes a lot clearer. It also helps if you know something about FORTH, which is also a bit of an unusual language. Firstly all computations are in reverse Polish, so 3+4 is performed as 3 4 + for example. Secondly all computations are mostly done on the stack, and I strived to do this here to make the crackme conceptually harder. I suspect that Joseph has some knowledge of FORTH ? The concepts were soon flattened into discussions on the algorithm. So yes, a side effect of all of this is that the program is difficult to disassemble as well with the mix of code/data.

    As an example of some definitions:

    ;----------------------------------------------------------
    ; :0 # --> 0 ;
    ;----------------------------------------------------------
    zero: dw $+2
    push 0
    jmp next

    which is a low level FORTH word to push zero onto the stack.
    And:

    ;----------------------------------------------------------
    ; :strlen # strptr --> length
    ; 0 swap
    ; begin{ dup c@ }while{ swap ++ swap ++ }repeat
    ; drop
    ; ;
    ;----------------------------------------------------------
    strlen: dw offset docol
    dw offset zero
    dw offset swap
    @1: dw offset dup_
    dw offset cat
    dw offset while_
    dw @2-$
    dw offset swap
    dw offset plusone
    dw offset swap
    dw offset plusone
    dw offset repeat
    dw @1-$
    @2: dw offset drop
    dw offset exit

    This is a much more complex higher level FORTH word. I have also written it in FORTH so you can examine this in more detail. Now you can see how difficult the asm is to follow, and yet to me it is very easy :P
    You need a good disassembler to attack this, when you finally realise just what the program is doing. So you both did well to get this far.

    Now the algorithm:
    Well, the algorithm was actually quite unusual although I didn't think too much about it at the time. I wanted to do several things with it. The main thing I wanted was an algorithm which didn't just do a simple check, but which needed to be understood and reversed. Secondly I wanted the algorithm to ENCODE length. What I mean by that was that without length checks the algorithm would impose a minimal length check anyway. I think I had this achieved quite well with something along the lines of summing 3*difference in username and access code. Unfortunately I then decided to add a few more bits which made it harder to crack and lost some of the simplicity of the original. I retained the minimal length, which is around 5 characters but lost some other properties I had wanted to keep (like the ability to move from an access code for one username to the access code of a different username in a simple way). My generator for codes is actually an Excel macro which uses a double ended approach to approximate an answer and then search for the final one. You might think that an access code isn't guaranteed but for a sufficient length username (6 characters - maybe 5, but I haven't done the analysis for 5) it is. I think the difficulty which people found with this detracted a lot from the original intention of the crackme, and this is certainly something I'll bear in mind when writing future ones.

    I think the only spoiler left may be the source code, primer (used to initially obscure strings), and key generators of Andy (which looks better than mine) and my own Excel generator (which is based on 6 chars but easily extendible).

    Cronos.




    Cronos


Message thread:

Andy's Thread (Andy) (29-Mar-99 07:03:39)

Back to main board