david942j/seccomp-tools
GitHub: david942j/seccomp-tools
一个用于提取、反汇编与模拟 seccomp BPF 规则的安全分析工具,解决 Linux 进程沙箱策略的可见性与验证问题。
Stars: 1107 | Forks: 73
[](https://github.com/david942j/seccomp-tools/actions)
[](https://qlty.sh/gh/david942j/projects/seccomp-tools)
[](https://qlty.sh/gh/david942j/projects/seccomp-tools)
[](https://inch-ci.org/github/david942j/seccomp-tools)
[](https://www.rubydoc.info/github/david942j/seccomp-tools/)
[](http://choosealicense.com/licenses/mit/)
# Seccomp Tools
提供用于 seccomp 分析的强大工具。
该项目旨在(但不限于)分析 CTF pwn 挑战中的 seccomp 沙箱。
某些功能可能具有 CTF 特定性,但对分析真实场景的 seccomp 同样有用。
## 功能
* Dump - 自动转储执行文件的 seccomp BPF。
* Disasm - 将 seccomp BPF 转换为可读格式。
- 包含简单反编译。
- 尽可能显示系统调用名称和参数。
- 彩色输出!
* Asm - 使编写 seccomp 规则类似于编写代码。
* Emu - 模拟 seccomp 规则。
* 支持多架构。
## 安装
在 RubyGems.org 上可用!
```
$ gem install seccomp-tools
```
如果编译失败,请尝试:
```
sudo apt install gcc ruby-dev make
```
然后重新安装 seccomp-tools。
## 命令行接口
### seccomp-tools
```
$ seccomp-tools --help
# Usage: seccomp-tools [--version] [--help] []
#
# List of commands:
#
# asm Seccomp bpf assembler.
# disasm Disassemble seccomp bpf.
# dump Automatically dump seccomp bpf from execution file(s).
# emu Emulate seccomp rules.
#
# See 'seccomp-tools --help' to read about a specific subcommand.
$ seccomp-tools dump --help
# dump - Automatically dump seccomp bpf from execution file(s).
# NOTE : This function is only available on Linux.
#
# Usage: seccomp-tools dump [exec] [options]
# -c, --sh-exec Executes the given command (via sh).
# Use this option if want to pass arguments or do pipe things to the execution file.
# e.g. use `-c "./bin > /dev/null"` to dump seccomp without being mixed with stdout.
# -f, --format FORMAT Output format. FORMAT can only be one of .
# Default: disasm
# -l, --limit LIMIT Limit the number of calling "prctl(PR_SET_SECCOMP)".
# The target process will be killed whenever its calling times reaches LIMIT.
# Default: 1
# -o, --output FILE Output result into FILE instead of stdout.
# If multiple seccomp syscalls have been invoked (see --limit),
# results will be written to FILE, FILE_1, FILE_2.. etc.
# For example, "--output out.bpf" and the output files are out.bpf, out_1.bpf, ...
# -p, --pid PID Dump installed seccomp filters of the existing process.
# You must have CAP_SYS_ADMIN (e.g. be root) in order to use this option.
```
### dump
从执行文件中转储 seccomp BPF。
此操作通过利用 `ptrace` 系统调用完成。
注意:执行文件会被执行。
```
$ file spec/binary/twctf-2016-diary
# spec/binary/twctf-2016-diary: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=3648e29153ac0259a0b7c3e25537a5334f50107f, not stripped
$ seccomp-tools dump spec/binary/twctf-2016-diary
# line CODE JT JF K
# =================================
# 0000: 0x20 0x00 0x00 0x00000000 A = sys_number
# 0001: 0x15 0x00 0x01 0x00000002 if (A != open) goto 0003
# 0002: 0x06 0x00 0x00 0x00000000 return KILL
# 0003: 0x15 0x00 0x01 0x00000101 if (A != openat) goto 0005
# 0004: 0x06 0x00 0x00 0x00000000 return KILL
# 0005: 0x15 0x00 0x01 0x0000003b if (A != execve) goto 0007
# 0006: 0x06 0x00 0x00 0x00000000 return KILL
# 0007: 0x15 0x00 0x01 0x00000038 if (A != clone) goto 0009
# 0008: 0x06 0x00 0x00 0x00000000 return KILL
# 0009: 0x15 0x00 0x01 0x00000039 if (A != fork) goto 0011
# 0010: 0x06 0x00 0x00 0x00000000 return KILL
# 0011: 0x15 0x00 0x01 0x0000003a if (A != vfork) goto 0013
# 0012: 0x06 0x00 0x00 0x00000000 return KILL
# 0013: 0x15 0x00 0x01 0x00000055 if (A != creat) goto 0015
# 0014: 0x06 0x00 0x00 0x00000000 return KILL
# 0015: 0x15 0x00 0x01 0x00000142 if (A != execveat) goto 0017
# 0016: 0x06 0x00 0x00 0x00000000 return KILL
# 0017: 0x06 0x00 0x00 0x7fff0000 return ALLOW
$ seccomp-tools dump spec/binary/twctf-2016-diary -f inspect
# "\x20\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x01\x02\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x01\x01\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x01\x3B\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x01\x38\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x01\x39\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x01\x3A\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x01\x55\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x01\x42\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\xFF\x7F"
$ seccomp-tools dump spec/binary/twctf-2016-diary -f raw | xxd
# 00000000: 2000 0000 0000 0000 1500 0001 0200 0000 ...............
# 00000010: 0600 0000 0000 0000 1500 0001 0101 0000 ................
# 00000020: 0600 0000 0000 0000 1500 0001 3b00 0000 ............;...
# 00000030: 0600 0000 0000 0000 1500 0001 3800 0000 ............8...
# 00000040: 0600 0000 0000 0000 1500 0001 3900 0000 ............9...
# 00000050: 0600 0000 0000 0000 1500 0001 3a00 0000 ............:...
# 00000060: 0600 0000 0000 0000 1500 0001 5500 0000 ............U...
# 00000070: 0600 0000 0000 0000 1500 0001 4201 0000 ............B...
# 00000080: 0600 0000 0000 0000 0600 0000 0000 ff7f ................
```
### disasm
将原始 BPF 反汇编为 seccomp 规则。
```
$ xxd spec/data/twctf-2016-diary.bpf | head -n 3
# 00000000: 2000 0000 0000 0000 1500 0001 0200 0000 ...............
# 00000010: 0600 0000 0000 0000 1500 0001 0101 0000 ................
# 00000020: 0600 0000 0000 0000 1500 0001 3b00 0000 ............;...
$ seccomp-tools disasm spec/data/twctf-2016-diary.bpf
# line CODE JT JF K
# =================================
# 0000: 0x20 0x00 0x00 0x00000000 A = sys_number
# 0001: 0x15 0x00 0x01 0x00000002 if (A != open) goto 0003
# 0002: 0x06 0x00 0x00 0x00000000 return KILL
# 0003: 0x15 0x00 0x01 0x00000101 if (A != openat) goto 0005
# 0004: 0x06 0x00 0x00 0x00000000 return KILL
# 0005: 0x15 0x00 0x01 0x0000003b if (A != execve) goto 0007
# 0006: 0x06 0x00 0x00 0x00000000 return KILL
# 0007: 0x15 0x00 0x01 0x00000038 if (A != clone) goto 0009
# 0008: 0x06 0x00 0x00 0x00000000 return KILL
# 0009: 0x15 0x00 0x01 0x00000039 if (A != fork) goto 0011
# 0010: 0x06 0x00 0x00 0x00000000 return KILL
# 0011: 0x15 0x00 0x01 0x0000003a if (A != vfork) goto 0013
# 0012: 0x06 0x00 0x00 0x00000000 return KILL
# 0013: 0x15 0x00 0x01 0x00000055 if (A != creat) goto 0015
# 0014: 0x06 0x00 0x00 0x00000000 return KILL
# 0015: 0x15 0x00 0x01 0x00000142 if (A != execveat) goto 0017
# 0016: 0x06 0x00 0x00 0x00000000 return KILL
# 0017: 0x06 0x00 0x00 0x7fff0000 return ALLOW
```
### asm
将 seccomp 规则汇编为原始字节。
在需要编写自定义 seccomp 规则时非常有用。
支持用于跳转的标签,并直接使用系统调用名称。参见以下示例。
自 v1.6.0(尚未发布)起,`asm` 已切换为使用基于 yacc 的语法解析器,因此支持更灵活、更直观的语法!
```
$ cat spec/data/example.asm
# # An example of supported assembly syntax
# if (A == X)
# goto next # 'next' is a reserved label, means the next statement ("A = args[0]" in this example)
# else
# goto err_label # custom defined label
# A = args[0]
# if (
# A # put a comment here is also valid
# == 0x123
# ) goto disallow
# if (! (A & 0x1337)) # support bang in if-conditions
# goto 0 # equivalent to 'goto next'
# else goto 2 # goto $ + 2, 'mem[0] = A' in this example
# A = sys_number
# A = instruction_pointer >> 32
# mem[0] = A
# A = data[4] # equivalent to 'A = arch'
# err_label: return ERRNO(1337)
# disallow:
# return KILL
$ seccomp-tools asm spec/data/example.asm -f raw | seccomp-tools disasm -
# line CODE JT JF K
# =================================
# 0000: 0x1d 0x00 0x07 0x00000000 if (A != X) goto 0008
# 0001: 0x20 0x00 0x00 0x00000010 A = args[0]
# 0002: 0x15 0x06 0x00 0x00000123 if (A == 0x123) goto 0009
# 0003: 0x45 0x02 0x00 0x00001337 if (A & 0x1337) goto 0006
# 0004: 0x20 0x00 0x00 0x00000000 A = sys_number
# 0005: 0x20 0x00 0x00 0x0000000c A = instruction_pointer >> 32
# 0006: 0x02 0x00 0x00 0x00000000 mem[0] = A
# 0007: 0x20 0x00 0x00 0x00000004 A = arch
# 0008: 0x06 0x00 0x00 0x00050539 return ERRNO(1337)
# 0009: 0x06 0x00 0x00 0x00000000 return KILL
```
`seccomp-tools disasm --asm-able` 的输出是 `asm` 的有效输入:
```
$ seccomp-tools disasm spec/data/x32.bpf --asm-able
# 0000: A = arch
# 0001: if (A != ARCH_X86_64) goto 0011
# 0002: A = sys_number
# 0003: if (A < 0x40000000) goto 0011
# 0004: if (A == x32_read) goto 0011
# 0005: if (A == x32_write) goto 0011
# 0006: if (A == x32_iopl) goto 0011
# 0007: if (A != x32_mmap) goto 0011
# 0008: A = args[0]
# 0009: if (A == 0x0) goto 0011
# 0010: return ERRNO(5)
# 0011: return ALLOW
# disasm then asm then disasm!
$ seccomp-tools disasm spec/data/x32.bpf --asm-able | seccomp-tools asm - -f raw | seccomp-tools disasm -
# line CODE JT JF K
# =================================
# 0000: 0x20 0x00 0x00 0x00000004 A = arch
# 0001: 0x15 0x00 0x09 0xc000003e if (A != ARCH_X86_64) goto 0011
# 0002: 0x20 0x00 0x00 0x00000000 A = sys_number
# 0003: 0x35 0x00 0x07 0x40000000 if (A < 0x40000000) goto 0011
# 0004: 0x15 0x06 0x00 0x40000000 if (A == x32_read) goto 0011
# 0005: 0x15 0x05 0x00 0x40000001 if (A == x32_write) goto 0011
# 0006: 0x15 0x04 0x00 0x400000ac if (A == x32_iopl) goto 0011
# 0007: 0x15 0x00 0x03 0x40000009 if (A != x32_mmap) goto 0011
# 0008: 0x20 0x00 0x00 0x00000010 A = addr # x32_mmap(addr, len, prot, flags, fd, pgoff)
# 0009: 0x15 0x01 0x00 0x00000000 if (A == 0x0) goto 0011
# 0010: 0x06 0x00 0x00 0x00050005 return ERRNO(5)
# 0011: 0x06 0x00 0x00 0x7fff0000 return ALLOW
```
### Emu
根据给定的 `sys_nr`、`arg0`、`arg1` 等模拟 seccomp。
```
$ seccomp-tools emu --help
# emu - Emulate seccomp rules.
#
# Usage: seccomp-tools emu [options] BPF_FILE [sys_nr [arg0 [arg1 ... arg5]]]
# -a, --arch ARCH Specify architecture.
# Supported architectures are .
# Default: amd64
# -q, --[no-]quiet Run quietly, only show emulation result.
# -i, --ip=VAL Set instruction pointer.
$ seccomp-tools emu spec/data/libseccomp.bpf write 0x3
# line CODE JT JF K
# =================================
# 0000: 0x20 0x00 0x00 0x00000004 A = arch
# 0001: 0x15 0x00 0x08 0xc000003e if (A != ARCH_X86_64) goto 0010
# 0002: 0x20 0x00 0x00 0x00000000 A = sys_number
# 0003: 0x35 0x06 0x00 0x40000000 if (A >= 0x40000000) goto 0010
# 0004: 0x15 0x04 0x00 0x00000001 if (A == write) goto 0009
# 0005: 0x15 0x03 0x00 0x00000003 if (A == close) goto 0009
# 0006: 0x15 0x02 0x00 0x00000020 if (A == dup) goto 0009
# 0007: 0x15 0x01 0x00 0x0000003c if (A == exit) goto 0009
# 0008: 0x06 0x00 0x00 0x00050005 return ERRNO(5)
# 0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
# 0010: 0x06 0x00 0x00 0x00000000 return KILL
#
# return ALLOW at line 0009
```
## 截图
### Dump

### Emu


## 支持的架构
- [x] x86_64
- [x] x32
- [x] x86
- [x] arm64 (@saagarjha)
- [x] s390x (@iii-i)
欢迎提交 Pull Request 以添加更多架构支持!
## 开发
建议在 Ruby 环境中使用 [rbenv](https://github.com/rbenv/rbenv)。
### 设置
- 安装 bundler
- `$ gem install bundler`
- 克隆源码
- `$ git clone https://github.com/david942j/seccomp-tools && cd seccomp-tools`
- 安装依赖
- `$ bundle install`
### 运行测试
`$ bundle exec rake`
## 我需要你
欢迎提出任何建议或功能请求!
请随时提交问题或 Pull Request。
并且,如果你喜欢这项工作,我很乐意被 [加星](https://github.com/david942j/seccomp-tools/stargazers) :grimacing:
标签:Hakrawler, Pwn, Ruby, seccomp, Wayback Machine, 云安全监控, 云资产清单, 代码覆盖率, 仿真, 反汇编, 可维护性, 多架构, 安全测试, 工具, 开源, 攻击性安全, 沙箱分析, 漏洞分析, 目录遍历, 知识库, 系统调用过滤, 路径探测, 逆向工程, 静态分析