Seccomp Tools– Potentes herramientas de seccomp
Este proyecto está dirigido a (pero no limitado a) analizar la sandbox seccomp en competencias de hacking. Algunas características pueden ser específicas de estas competencias, pero aún útiles para analizar seccomp en un caso real.
Características
- Dump: recupera automáticamente seccomp-bpf de los archivos de ejecución.
- Disasm: convierte bpf a formato legible para humanos.
- Descompilación simple.
- Muestra nombres y argumentos de syscall cuando es posible.
- ¡Vistoso!
- Asm – ¡Escribir reglas seccomp es muy fácil!
- Emu: emula las reglas de seccomp.
- Admite arquitecturas múltiples.
Instalación
¡Disponible en RubyGems.org!
$ gem install seccomp-tools
Si falla al compilar, intenta lo siguiente:
sudo apt install gcc ruby-dev
e instala seccomp-tools nuevamente.
Interfaz de línea de comandos
seccomp-tools
$ seccomp-tools --help # Usage: seccomp-tools [--version] [--help] <command> [<options>] # # 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 <command> --help' to read about a specific subcommand. $ seccomp-tools dump --help # dump - Automatically dump seccomp bpf from execution file(s). # # Usage: seccomp-tools dump [exec] [options] # -c, --sh-exec <command> 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 <disasm|raw|inspect>. # 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, ...
dump
Recupera el seccomp bpf de un archivo de ejecución. Este trabajo lo realiza la ptrace syscall.
Advertencia: cuidado con el archivo que se ejecutará.
$ 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 001 1 # 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
Desmonta el seccomp de bpf sin procesar.
$ 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
Ensambla las reglas de seccomp en bytes sin formato. Es muy útil cuando uno quieres escribir reglas de seccomp personalizadas.
Admite etiquetas para saltar y usa los nombres de syscall directamente. Ver ejemplos a continuación.
$ seccomp-tools asm # asm - Seccomp bpf assembler. # # Usage: seccomp-tools asm IN_FILE [options] # -o, --output FILE Output result into FILE instead of stdout. # -f, --format FORMAT Output format. FORMAT can only be one of <inspect|raw|c_array|c_source|assembly>. # Default: inspect # -a, --arch ARCH Specify architecture. # Supported architectures are <amd64|i386>. # Input file for asm $ cat spec/data/libseccomp.asm # # check if arch is X86_64 # A = arch # A == ARCH_X86_64 ? next : dead # A = sys_number # A >= 0x40000000 ? dead : next # A == write ? ok : next # A == close ? ok : next # A == dup ? ok : next # A == exit ? ok : next # return ERRNO(5) # ok: # return ALLOW # dead: # return KILL $ seccomp-tools asm spec/data/libseccomp.asm # " \x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\b>\x00\x00\xC0 \x00\x00\x00\x00\x00\x00\x005\x00\x06\x00 \x00\x00\x00@\x15\x00\x04\x00\x01\x00\x00\x00\x15\x00\x03\x00\x03\x00\x00\x00\x15\x00\x02\x00 \x00\x00 \x00\x15\x00\x01\x00<\x00\x00\x00\x06\x00\x00\x00\x05\x00\x05\x00\x06\x00\x00\x00\x00\x00\xFF\x7F\x06 \x00\x00\x00\x00\x00\x00\x00" $ seccomp-tools asm spec/data/libseccomp.asm -f c_source # #include <linux/seccomp.h> # #include <stdio.h> # #include <stdlib.h> # #include <sys/prctl.h> # # static void install_seccomp() { # static unsigned char filter[] = {32,0,0,0,4,0,0,0,21,0,0,8,62,0,0,192,32,0,0,0,0,0,0,0,53,0,6,0,0,0, 0,64,21,0,4,0,1,0,0,0,21,0,3,0,3,0,0,0,21,0,2,0,32,0,0,0,21,0,1,0,60,0,0,0,6,0,0,0,5,0,5,0,6,0,0,0,0,0, 255,127,6,0,0,0,0,0,0,0}; # struct prog { # unsigned short len; # unsig ned char *filter; # } rule = { # .len = sizeof(filter) >> 3, # .filter = filter # }; # if(prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { perror("prctl(PR_SET_NO_NEW_PRIVS)"); exit(2); } # if(prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &rule) < 0) { perror("prctl(PR_SET_SECCOMP)"); exit(2); } # } $ seccomp-tools asm spec/data/libseccomp.asm -f assembly # install_seccomp: # push rbp # mov rbp, rsp # push 38 # pop rdi # push 0x1 # pop rsi # xor eax, eax # mov al, 0x9d # syscall # push 22 # pop rdi # lea rdx, [rip + _filter] # push rdx /* .filter */ # push _filter_end - _filter >> 3 /* .len */ # mov rdx, rsp # push 0x2 # pop rsi # xor eax, eax # mov al, 0x9d # syscall # leave # ret # _filter: # .ascii "\040\000\000\000\004\000\ 000\000\025\000\000\010\076\000\000\300\040\000\000\000\000\000\000\000\065\000\006\000\000\000\000\100\025\000\004\000\001\000\000\000\025\000\003\000\003\000\000\000\025\000\002\000\040\000\000\000\025\000\001\000\074\000\000\000\006\000\000\000\005\000\005\000\006\000\000\000\000\000\377\177\006\000\000\000\000\000\000\000" # _filter_end: # let's asm then disasm! $ seccomp-tools asm spec/data/libseccomp.asm -f raw | seccomp-tools disasm - # 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 # 00 07: 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
Emu
Emula el Seccomp dado sys_nr, arg0, arg1, etc.
$ 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 <amd64|i386>. # -q, --[no-]quiet Run quietly, only show emulation result. $ 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 # 0 007: 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
Capturas de pantalla
Dump
Emu
Desarrollo
Te recomiendo usar rbenv para tu entorno Ruby.
Preparación
- Instalar paquete
-
$ gem install bundler
- Clonar la fuente
-
$ git clone https://github.com/david942j/seccomp-tools && cd seccomp-tools
- Instalar dependencias
-
$ bundle install
Ejecutar pruebas
$ bundle exec rake
Te necesitan
¡Cualquier sugerencia o solicitud de función es bienvenida! No dudes en informar un problema o enviar una solicitud push. Y, si te gusta este trabajo, estarás feliz de ser protagonista.