All writeups. Or maybe just CrackMe0x04?

This is a walkthrough for the CrackMe0x05 that was part of the Rensselaer Polytechnic Institute’s Binary Exploitation course in Spring 2015. You can follow along by downloading the challenges here. (mirror 1, mirror 2)

Not much point in running the binary seeing as nothing much changes – let’s get straight to our assembly dumps.

Hmmm – looks familiar? Time to dump <check>.

Looks more or less familiar. First thing that jumps out to me at <check+82> is that we are now comparing against 0x10 instead of 0xf. Could the answer be as something simple as numbers adding up to 16?

Close, but not quite – seems like they’ve added some other condition. Closer inspection reveals a new function on <check+94> – time for another dump. Note that this function is only called when the comparison on <check+82> is satisfied otherwise the subsequent jump skips the call to <parell>.

Now that is something interesting – an instruction we haven’t seen before on <parell+38>. ‘and’ is the assembly version of an AND bitwise operation. So we’re doing some sort of ‘sscanf’ ‘dissection’ and checking whether it is odd or even (since that’s what AND does with 0x1). Also a hard coded memory address at <parell+42> which seems to be going to be called in the following ‘printf’ call. Would be nice to see what it says so we can see the general logic of the function. (Again, radare2 would be great for this, but we’re using gdb ¯\_(ツ)_/¯)

Nice! This makes it pretty easy – seems like our program is doing a check for whether a number is odd or even as part of the password. If you don’t get what’s happening, here’s what should be the equivalent pseudocode.

void parell(info for sscanf){
    //Grab a single digit - check by breakpointing parell+32
    sscanf()
    if(digit &amp; 0x1){
        return;
    } else {
        printf("Password OK\n");
        exit();
    }
}

<check> seems to be pretty similar to CheckMe0x04 apart from this extra check and the changed comparison (to 0x10 instead of 0xf). So our theory now is that the rule for the password is a series of numbers that add up to 16, where the last number is even. Time to test our theory 🙂

Yep seems like it works – if the ‘total sum’ is equal to 16 and you’re already at the end of your input string, you’ll end up scanning the last digit again instead. Otherwise you’ll scan the next character/digit again – if it’s a character, it scans in as 64 for some reason which is even so it’s ok. But if the next number is odd such as in ‘9341’ you’ll fail the password check.

That was fun!