pwn入门-sandbox(Seccomp)
pwn入门-sandbox(Seccomp)
pwn知识——ORW - Falling_Dusk - 博客园
Seccomp(secure computing mode)在2.6.12版本(2005年3月8日)中引入linux内核,将进程可用的系统调用限制为四种:read,write,_exit,sigreturn。最初的这种模式是白名单方式,在这种安全模式下,除了已打开的文件描述符和允许的四种系统调用,如果尝试其他系统调用,内核就会使用SIGKILL或SIGSYS终止该进程。Seccomp来源于Cpushare项目,Cpushare提出了一种出租空闲linux系统空闲CPU算力的想法,为了确保主机系统安全出租,引入seccomp补丁,但是由于限制太过于严格,当时被人们难以接受。
SECCOMP_SET_MODE_FILTER
- Seccomp-Berkley Packet Filter
- 允许用户使用可配置的策略过滤系统调用
- 使用BPF规则自定义测量
- 可对任意系统调用及其参数进行过滤
1 | apt install libseccomp-dev libseccomp2 seccomp |
1 |
|
未使用seccomp:hello world!hello world!
使用seccomp:hello world!Killed
初代的seccomp就是这样暴力,禁用白名单之外的所有函数!
Seccomp-BPF
尽管seccomp保证了主机的安全,但由于限制太强实际作用并不大。在实际应用中需要更加精细的限制,为了解决此问题,引入了Seccomp – Berkley Packet Filter(Seccomp-BPF)。Seccomp-BPF是Seccomp和BPF规则的结合,它允许用户使用可配置的策略过滤系统调用,该策略使用Berkeley Packet Filter规则实现,它可以对任意系统调用及其参数(仅常数,无指针取消引用)进行过滤。
Seccomp-BPF 的作用
- 减少攻击面:
- 限制进程只能使用必要的系统调用,降低攻击者利用不需要的系统调用发起攻击的可能性。
- 即使程序存在漏洞,也因为受限的系统调用而难以进一步利用。
- 隔离进程:
- 将高风险的代码(如处理不可信输入的模块)运行在受限的沙箱中。
- 防止这些模块对操作系统或其他进程造成威胁。
- 提升程序安全性:
- 通过定义允许的系统调用清单,降低因为内核或用户态程序漏洞导致的威胁。
- 常用于容器(如 Docker)、浏览器(如 Chrome)、网络服务和安全敏感的应用程序。
BPF 定义了一个伪机器这个伪机器可以执行代码有一个累加器,寄存器,赋值,算术,跳转
1 |
|
常见的沙箱绕过思路:ORW
Open /open Read /read Write /writev
seccomp在ctf中大多用于禁用execve函数,解决办法就是构造shellcode,用open->read->write的方式读flag
绕过不检查系统号
特殊的沙箱绕过思路-未检查范围
在x64下还可以直接使用x32-abi绕过X32为x86-64下的一种特殊的模式,使用64位的寄存器和32位的地址,只需直接加 __X32_SYSCALL_BIT(0X40000000)即原本的syscall number + 0x40000000
根据具体规则,结合syscall调用表找没被过滤的替代行数如execveat openv readv writev
- 泄露内存地址
- 找到libc中的open,read,write的地址
- 在内存中写入“flag”3.利用ORW读出flag
- ibc中的函数syscall
- syscall_ret pop_rax
read
(系统调用号 0)
write
(系统调用号 1)
open
(系统调用号 2)
exit
(系统调用号 60)
在禁用execve的情况下,我们需要经过以下操作来得到flag值
1 | open开flag文件 |
在知晓大概的流程之后,就得设置寄存器的参数了,我们得知道各个函数对应的参数分别代表什么意思open(file,oflag)
,read(fd,buf,n_bytes)
和write(fd,buf,n_bytes)
open
- file就是我们要读取的文件名,CTF中一般为flag,或者flag.txt。
- 而oflag则是我们以何种方式打开文件,如只读,只写,可读可写。一般来说我们都设置
oflag=0
,以默认方式打开文件,一般来说都是只读,我们并不需要对flag进行其它操作,所以只读的权限就够了
read和write
这两个是大同小异的。fd是文件描述符,通过设置它来决定函数的操作。在大多数时候,我们常常设置read的fd为0,代表标准输入,但在ORW中,我们需要设置read的fd为3,表示从文件中读取,buf就是我们读取出的flag值存放的地址,n_bytes就是能输入多少字节的数据。write的fd还是如常,依旧为1.