文章转载自:http://blog.sina.com.cn/s/blog_53fdf1590102xtg3.html
做pwn,用seccomp做沙箱保护很常见。有时候seccomp后面会跟一个结构体,趁此机会学习一把。
1、 简介
seccomp是一种内核中的安全机制,正常情况下,程序可以使用所有的syscall,这是不安全的,比如劫持程序流后通过execve的syscall来getshell.通过seccomp我们可以在程序中禁用掉某些syscall,这样就算劫持了程序流也只能调用部分的syscall了.
2、 使用seccomp
首先,调用seccomp的程序我们是能够直接运行的,但是我们不能直接编写调用seccomp的程序,因为我们缺少相应的头文件.通过apt安装
sudo apt install libseccomp-dev libseccomp2 seccomp
这样就有头文件了
#veritas @ ubuntu in /usr/include
$ find . -name seccomp.h
./seccomp.h
./linux/seccomp.h
先写一个简单的程序调用一下syscall,简单的输出后,会弹一个shell
//gcc -g simple_syscall.c -o simple_syscall
#include <stdio.h>
int main(void){
char * filename = "/bin/sh";
char * argv[] = {"/bin/sh",NULL};
char * envp[] = {NULL};
write(1,"i will give you a shell\n",24);
syscall(59,filename,argv,envp);//execve
return 0;
}
现在我们通过seccomp禁用掉execve的syscall
//gcc -g simple_syscall_seccomp.c -o simple_syscall_seccomp -lseccomp
#include <stdio.h>
#include <unisted.h>
#include <seccomp.h>
int main(void){
scmp_filter_ctx ctx;
ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0);
seccomp_load(ctx);
char * filename = "/bin/sh";
char * argv[] = {"/bin/sh",NULL};
char * envp[] = {NULL};
write(1,"i will give you a shell\n",24);
syscall(59,filename,argv,envp);//execve
return 0;
}
运行结果:
稍微解释一下上面几个函数:
ctx是Filter context/handle,其中typedef void *scmp_filter_ctx;
seccomp_init是初始化的过滤状态,这里用的是SCMP_ACT_ALLOW,表示默认允许所有的syscacll.如果初始化状态为SCMP_ACT_KILL,则表示默认不允许所有的syscall
3、How to reverse
可以使用现成的工具
https://github.com/david942j/seccomp-tools
我们测测看雪2017CTF第9题 Silence_Server,用seccomp-tools得到以下结果
在arch_x86_64下,只允许read, open, close, stat, fstat, lstat, poll, lseek, brk, execve