david942j/seccomp-tools

GitHub: david942j/seccomp-tools

一个用于提取、反汇编与模拟 seccomp BPF 规则的安全分析工具,解决 Linux 进程沙箱策略的可见性与验证问题。

Stars: 1107 | Forks: 73

[![Build Status](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/d1a8f2e78b000304.svg)](https://github.com/david942j/seccomp-tools/actions) [![Maintainability](https://qlty.sh/gh/david942j/projects/seccomp-tools/maintainability.svg)](https://qlty.sh/gh/david942j/projects/seccomp-tools) [![Code Coverage](https://qlty.sh/gh/david942j/projects/seccomp-tools/coverage.svg)](https://qlty.sh/gh/david942j/projects/seccomp-tools) [![Inline docs](https://inch-ci.org/github/david942j/seccomp-tools.svg?branch=master)](https://inch-ci.org/github/david942j/seccomp-tools) [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/github/david942j/seccomp-tools/) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](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 ![dump](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/65f496f1db000307.png) ### Emu ![emu](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/871db704ad000311.png) ![emu](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/a516d43a3c000314.png) ## 支持的架构 - [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, 云安全监控, 云资产清单, 代码覆盖率, 仿真, 反汇编, 可维护性, 多架构, 安全测试, 工具, 开源, 攻击性安全, 沙箱分析, 漏洞分析, 目录遍历, 知识库, 系统调用过滤, 路径探测, 逆向工程, 静态分析