I've been struggling to understand a very strange piece of x86 assembly code from the IOLI crackme0x06 challenge.


But first of all, here is the context : I've successfully cracked the challenge, which by the way simply needs :

  1. An even number

  2. This number being in the range of 32-bit representation of signed integers, ie between -2^31 (INT32_MIN) and 2^31-1 (INT32_MAX) (due to the call to sscanf which apparently performs integer saturation on the input if it's greater than INT32_MAX)

  3. An environment variable - whose name shall begin by 'LOL' - being exported in the crackme process environment.

The issue

Now, for completeness purposes, I'm trying to grasp the purpose of every single instruction of this crackme, but so far, I'm struggling to understand how the following code (from ##loop beginning to ##loop end) from the sym.parell function is actually useful in anyway to the program :

    0804851a <parell>:    
     804851a:       push   ebp
     804851b:       mov    ebp,esp
     804851d:       sub    esp,0x18
     8048520:       lea    eax,[ebp-0x4]
     8048523:       mov    DWORD PTR [esp+0x8],eax
     8048527:       mov    DWORD PTR [esp+0x4],0x804873d
     804852f:       mov    eax,DWORD PTR [ebp+0x8]
     8048532:       mov    DWORD PTR [esp],eax
     8048535:       call   80483c8 <sscanf@plt>
     804853a:       mov    eax,DWORD PTR [ebp+0xc]
     804853d:       mov    DWORD PTR [esp+0x4],eax
     8048541:       mov    eax,DWORD PTR [ebp-0x4]
     8048544:       mov    DWORD PTR [esp],eax
     8048547:       call   80484b4 <dummy>
     804854c:       test   eax,eax
     804854e:       je     8048586 <parell+0x6c>
     8048550:       mov    DWORD PTR [ebp-0x8],0x0   # Initialization of i (see pseudo-code below)
     8048557:       cmp    DWORD PTR [ebp-0x8],0x9   ## loop beginning
     804855b:       jg     8048586 
     804855d:       mov    eax,DWORD PTR [ebp-0x4]   # Handling password's parity check
     8048560:       and    eax,0x1
     8048563:       test   eax,eax
     8048565:       jne    804857f <parell+0x65>
     8048567:       mov    DWORD PTR [esp],0x8048740
     804856e:       call   80483b8 <printf@plt>
     8048573:       mov    DWORD PTR [esp],0x0
     804857a:       call   80483e8 <exit@plt>
     804857f:       lea    eax,[ebp-0x8]
     8048582:       inc    DWORD PTR [eax]
     8048584:       jmp    8048557 <parell+0x3d>     ## loop end
     8048586:       leave
     8048587:       ret

It seems to be equivalent to the following pseudo-code :

    for (int i = 0; i <= 9; ++i)
            if LSB (password) is 0    // ie if password is an even number
                printf("Password OK!\n");

But the thing is, looping from 0 to 9 won't do anything relevant for the parity check of the number ...
And as far as the password testing is concerned, the computation taking place in the sym.parell function is never impacted by such a loop !

I've been scratching my head over that for hours, but I really couldn't figure out its exact purpose.

Had this challenge not been for beginners (by the way it's the first hands-on lab of the RPISEC academic course), I would have thought that this is just some silly obfuscation/junk code technique meant to deflect the attention of the attacker, which is obviously not the case.
This series of challenges is only aiming at helping newbies build strong basics in the field.

Am I wrong ?
So, seriously, what is the aforementioned code's purpose in this program ?

  • 1
    There is no loop in the disassembly you posted. Could you paste the complete loop code here? – bart1e May 31 '19 at 18:25
  • @bart1e My bad. Please see the edit now, I've added the whole function with appropriate comments, plus I got rid of the superfluous opcodes listing in disassembly. – programmersn May 31 '19 at 21:09
  • 1
    yes, it looks like a bug that's supposed to iterate over all characters of the password, but the index is never updated, so it's checking the first byte repeatedly for an odd value. – peter ferrie Jun 1 '19 at 2:19
  • Why would it need to iterate over the password's bytes ? It makes no sense knowing the validity requirements of the password, which I pointed out in the context section. No need for any other check, whatsoever. That's what is puzzling me. – programmersn Jun 1 '19 at 7:26
  • If every character in the password is required to be an even number then it needs to iterate over them all to ensure that. – peter ferrie Jun 10 '19 at 5:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.