PicoCTF 작성 - 리버스 엔지니어링(asm2)
정보:
Nombre de la plataforma: PicoCTF
Nombre del reto: asm2
카테고리: Ingeniería Inversa
푼토스: 250
피코CTF 2019.
설명:
¿Qué retorna asm2(0xb, 0x2e)? Envía la bandera como un valor 16진수(comienza con '0x'). 참고: El envío para este reto NO será en el formato normal de las banderas. Código .
피스타: Condiciones 앙상블라도르
Writeup(Inicio)
En este reto, tenemos el código fuente en ensamblador. El archivo se llama test.S y acontinuación puedes ver el código en cuestion:
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
Como dige anteriormente, esto es código en ensamblador, ya solucioné un reto sobre ensamblador por lo que podría ser parecido, vamos a probar.
Para entender el programa decidí ir línea por línea.
<+0>: push ebp
<+1>: mov ebp,esp
Como ya sabemos asm2(0xb, 0x2e) está siendo puesto en el stack. Esto pasa en las primeras dos líneas. La primera hace push de asm2 hacia ebp y después se mueve dicho valor hacia esp.
Después de estas dos instrucciones, el estado del stack es el siguiente:
방향
용기
지침
0xc
0x2e
ebp+0xc
0x8
0xb
ebp+0x8
0x4
레트
ebp+0x4
0x0
썰물
Sabre esto nos ayuda bastante. Ahora vamos a ver la siguiente 지침:
<+3>: sub esp,0x10
En esta instrucción, simplemente estamos a asignando espacio para algunas variables locales, por lo que el stack quedaría así:
방향
용기
지침
0xc
0x2e
ebp+0xc
0x8
0xb
ebp+0x8
0x4
레트
ebp+0x4
0x0
썰물
-0x4
로컬1
ebp-0x4
-0x8
로컬2
ebp-0x8
-0xc
local3
ebp-0xc
-0x10
로컬4
ebp-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>
Vamos instrucción por instruccion:
En este reto, tenemos el código fuente en ensamblador. El archivo se llama test.S y acontinuación puedes ver el código en cuestion:
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
Como dige anteriormente, esto es código en ensamblador, ya solucioné un reto sobre ensamblador por lo que podría ser parecido, vamos a probar.
Para entender el programa decidí ir línea por línea.
<+0>: push ebp
<+1>: mov ebp,esp
Como ya sabemos asm2(0xb, 0x2e) está siendo puesto en el stack. Esto pasa en las primeras dos líneas. La primera hace push de asm2 hacia ebp y después se mueve dicho valor hacia esp.
Después de estas dos instrucciones, el estado del stack es el siguiente:
방향
용기
지침
0xc
0x2e
ebp+0xc
0x8
0xb
ebp+0x8
0x4
레트
ebp+0x4
0x0
썰물
Sabre esto nos ayuda bastante. Ahora vamos a ver la siguiente 지침:
<+3>: sub esp,0x10
En esta instrucción, simplemente estamos a asignando espacio para algunas variables locales, por lo que el stack quedaría así:
방향
용기
지침
0xc
0x2e
ebp+0xc
0x8
0xb
ebp+0x8
0x4
레트
ebp+0x4
0x0
썰물
-0x4
로컬1
ebp-0x4
-0x8
로컬2
ebp-0x8
-0xc
local3
ebp-0xc
-0x10
로컬4
ebp-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>
Vamos instrucción por instruccion:
El estado actual del stack es:
방향
용기
지침
0xc
0x2e
ebp+0xc
0x8
0xb
ebp+0x8
0x4
레트
ebp+0x4
0x0
썰물
-0x4
0x2e
ebp-0x4
-0x8
0xb
ebp-0x8
-0xc
local3
ebp-0xc
-0x10
로컬4
ebp-0x10
Pasemos a la siguiente 지침:
<+28>: cmp DWORD PTR [ebp-0x8],0x63f3
<+35>: jle 0x501 <asm2+20>
Como sabrás, la anterior instrucción nos hizo saltar hacia asm2+28, la cual es una comparación seguida de un salto si el resultado es menor o igual que. 예를 들어, ebp-0x8(es decir, la variable local2 que tiene el valor 0xb) y 0x63f3을 비교합니다. Sabemos que 0xb es menor que 0x63f3 por lo que hacemos el salto hacia asm2+20.
<+20>: add DWORD PTR [ebp-0x4],0x1
<+24>: sub DWORD PTR [ebp-0x8],0xffffff80
En la linea +20 tenemos una istrucción add, añadimos 1 a ebp-0x4, convirtiéndolo en 0x2f.
En la linea +24 tenemos una instrucción sub, restamos 0xffffff80 a ebp-0x8. Esto es x86 por lo que tenemos que truncar el resultado, para ello simplemente realizamos esta operation en Python:
local2 = (local2 - 0xffffff80) & 0xffffffff
local2 es: 0x8b의 가치
Continuando con la siguiente linea nos encontramos nuevamente en la +28 y sabemos que 0x8b es menor que 0x63f3 por lo que volvemos a dar el salto. Para facilitar el proceso creé un script en Python que no es más que una "traducción"de este código en ensamblador. El script en cuestión es el siguiente:
'''
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))
이전 버전의 스크립트는 Python 3에서 "전통적인"방식으로 시작되었습니다. Después de ejecutar el código obtendremos la bandera.
Espero les haya sido de tanta utilidad como a mí, cualquier duda no duden en enviarme un mensaje.
링크 델 포스트 원본: https://mregraoncyber.com/picoctf-writeup-asm2/
Reference
이 문제에 관하여(PicoCTF 작성 - 리버스 엔지니어링(asm2)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rooyca/picoctf-writeup-reverse-engineering-asm2-1659텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)