PicoCTF Writeup – asm2

# Information:

CTF Name: PicoCTF

CTF Challenge: asm2

Challenge Category: Reverse Engineering

Challenge Points: 250

PicoCTF 2019.

# Challenge Description:

What does asm2(0xb,0x2e) return? Submit the flag as a hexadecimal value (starting with ‘0x’). NOTE: Your submission for this question will NOT be in the normal flag format. Source

Hint: assembly conditions

# Writeup

In this challenge, we have the source code of an assembly code snippet. The file name is test.S and below you can see the code snippet:

asm2:
	<+0>:	push   ebp
	<+1>:	mov    ebp,esp
	<+3>:	sub    esp,0x10
	<+6>:	mov    eax,DWORD PTR [ebp+0xc]
	<+9>:	mov    DWORD PTR [ebp-0x4],eax
	<+12>:	mov    eax,DWORD PTR [ebp+0x8]
	<+15>:	mov    DWORD PTR [ebp-0x8],eax
	<+18>:	jmp    0x509 <asm2+28>
	<+20>:	add    DWORD PTR [ebp-0x4],0x1
	<+24>:	sub    DWORD PTR [ebp-0x8],0xffffff80
	<+28>:	cmp    DWORD PTR [ebp-0x8],0x63f3
	<+35>:	jle    0x501 <asm2+20>
	<+37>:	mov    eax,DWORD PTR [ebp-0x4]
	<+40>:	leave  
	<+41>:	ret    

As I said this is assembly code, I already solved a similar challenge regarding assembly, it might be similar, let’s try it.

To understand the program I decided to go line by line.  

	<+0>:	push   ebp
	<+1>:	mov    ebp,esp

We know that the asm1(0xb,0x2e) is being put into the stack. This happens due to these two first lines. The first line pushes asm2 into ebp and then this value is moved into esp.  

After these two instructions, the current stack state is as such:

0xc0x2ewhich is equal to saying: ebp+0xc           
0x80xbwhich is equal to saying: ebp+0x8           
0x4retwhich is equal to saying: ebp+0x4           
0x0ebp                    

  Knowing this helps us a lot. Now the next instruction:  

	<+3>:	sub    esp,0x10

In this instruction, we are simply allocating space for local variables, and the new stack is:

0xc0x2ewhich is equal to saying: ebp+0xc           
0x80xbwhich is equal to saying: ebp+0x8           
0x4retwhich is equal to saying: ebp+0x4           
0x0ebp                    
-0x4 local1which is equal to saying: ebp-0x4           
-0x8local2which is equal to saying: ebp-0x8           
-0xclocal3which is equal to saying: ebp-0xc           
-0x10local4which is equal to saying: ebp-0x10           

Next we have:

	<+6>:	mov    eax,DWORD PTR [ebp+0xc]
	<+9>:	mov    DWORD PTR [ebp-0x4],eax
	<+12>:	mov    eax,DWORD PTR [ebp+0x8]
	<+15>:	mov    DWORD PTR [ebp-0x8],eax
	<+18>:	jmp    0x509 <asm2+28>

Let’s go over each instruction of this block of code one at a time:

  1. First, we are assigning to the eax register the value in ebp+0xc which is 0x2e, according to the stack.
  2. Next, we move the value in the eax register to ebp-0x4, which in our case is local1, making it equal to 0x2e.
  3. Afterward, we move the contents ebp+0x8 to eax, making it equal to 0xb.
  4. In line +15 we move the contents of the eax register to ebp-0x8, which is the local2 variable, making it equal to 0xb.
  5. Finally, we jump to asm2+28.

The current stack state is:

0xc0x2ewhich is equal to saying: ebp+0xc           
0x80xbwhich is equal to saying: ebp+0x8           
0x4retwhich is equal to saying: ebp+0x4           
0x0ebp                    
-0x4 0x2ewhich is equal to saying: ebp-0x4           
-0x80xbwhich is equal to saying: ebp-0x8           
-0xc  local3which is equal to saying: ebp-0xc           
-0x10local4which is equal to saying: ebp-0x10           

Let’s move on to the next instruction:

	<+28>:	cmp    DWORD PTR [ebp-0x8],0x63f3
	<+35>:	jle    0x501 <asm2+20>

As you know, the previous instruction made us jump to asm2+28, which is a comparison, followed by a jump if less or equals to. In this case, we have a comparison between ebp-0x8, (which we know is local2 and it is equal to 0xb) and 0x63f3. We know that 0xb is less than 0x63f3 so we take the jump to asm2+20.  

	<+20>:	add    DWORD PTR [ebp-0x4],0x1
	<+24>:	sub    DWORD PTR [ebp-0x8],0xffffff80

In line +20 we have an add instruction, we are adding 1 to ebp-0x4, making it 0x2f.

In line +24 we have a sub instruction, we are subtracting 0xffffff80 to ebp-0x8. This is 0x86 architecture so we have to truncate the result, to do so I simply performed this operation in python:

local2 = (local2 - 0xffffff80) & 0xffffffff

The new value for local2 is: 0x8b

Moving on to the next line we are once again in +28, and we know that 0x8b is less than 0x63f3, therefore we will take the jump was again. To facilitate the process I created a python 3 script that is a translation to python 3 of this assembly code, see below:  

'''
Stack:
[  local4 ]  <--- ebp-0x10
[  local3 ]  <--- ebp-0xc
[  local2 ]  <--- ebp-0x8
[  local1 ]  <--- ebp-0x4
[   ebp   ]
[   ret   ]  <--- ebp+0x4
[   arg1  ]  <--- ebp+0x8
[   arg2  ]  <--- ebp+0xc
'''
#We know that asm2 receives two arguments
def asm2(arg1, arg2):
#asm2:
    #<+0>:  push   ebp
    #<+1>:  mov    ebp,esp
    #<+3>:  sub    esp,0x10

    #<+6>:  mov    eax,DWORD PTR [ebp+0xc]
    eax = arg2

    #<+9>:  mov    DWORD PTR [ebp-0x4],eax
    local1 = eax

    #<+12>: mov    eax,DWORD PTR [ebp+0x8]
    eax = arg1

    #<+15>: mov    DWORD PTR [ebp-0x8],eax
    local2 = eax

    #<+18>: jmp    0x509 <asm2+28>
    #<+20>: add    DWORD PTR [ebp-0x4],0x1
    #<+24>: sub    DWORD PTR [ebp-0x8],0xffffff80
    #<+28>: cmp    DWORD PTR [ebp-0x8],0x63f3
    #<+35>: jle    0x501 <asm2+20>
    while(local2 <= 0x63f3):
        local1 = (local1 + 1) & 0xffffffff              #This truncates the result to 32 bits.
        local2 = (local2 - 0xffffff80)  & 0xffffffff    #This truncates the result to 32 bits.           
    '''
       It is necessary to truncate the restuls because in python does not have
       buffer overflow but 0x86 can have so we have to truncate it.
       '''

    #<+37>: mov    eax,DWORD PTR [ebp-0x4]
    #<+40>: leave
    #<+41>: ret
    return hex(local1)

print(asm2(0xb, 0x2e))

To  create the script I simply translated as I did before but to the python 3 syntax. After running the code we get the flag:  

Show flag
0xf6

The Python 3 script source code can be found here.

Thank you very much for reading!

Cheers,

MRegra


Share this post:

Popular posts

Leave a Reply

Your email address will not be published. Required fields are marked *