
Un kit de herramientas para escribir shellcode
Escribir shellcodes siempre ha sido muy divertido, pero algunas partes son extremadamente aburridas y propensas a errores. ¡Concéntrate solo en la parte divertida y usa ShellNoob!
Para una visión rápida, consulta las diapositivas de la charla en Black Hat Arsenal: link
¿Quieres contribuir? ¿Solicitud de funcionalidad? ¿Reporte de error? ¿Insultos? Todo comentario es bienvenido! (Pero algunos tipos de comentarios son más bienvenidos que otros :-)).
No dudes en contactarme en twitter @reyammer o enviarme un correo a yanick[AT]cs.ucsb.edu si tienes alguna pregunta!
21/01/2014 - ¡ShellNoob 2.1 está disponible! Incluye soporte completo para Python 3 y muchas correcciones de errores. ¡Todo el crédito es para Levente Polyak!
29/07/2013 - ¡ShellNoob 2.0 está disponible!
08/06/2013 - ¡ShellNoob fue aceptado en Black Hat Arsenal! Ver anuncio aquí: link.
--intel.--64.-c.--to-strace y --to-gdb!--file-patch, --vm-patch, --fork-nopper! (todos los detalles abajo)$ ./shellnoob.py -h
shellnoob.py [--from-INPUT] (input_file_path | - ) [--to-OUTPUT] [output_file_path | - ]
shellnoob.py -c (añadir un breakpoint (Advertencia: solo pocas plataformas/OS están soportadas!)
shellnoob.py --64 (modo de 64 bits, por defecto: 32 bits)
shellnoob.py --intel (modo sintaxis Intel, por defecto: att)
shellnoob.py -q (modo silencioso)
shellnoob.py -v (o -vv, -vvv)
shellnoob.py --to-strace (lo compila y ejecuta strace)
shellnoob.py --to-gdb (lo compila y ejecuta gdb y establece breakpoint en el punto de entrada)
Plugins "independientes"
shellnoob.py -i [--to-asm | --to-opcode ] (para modo interactivo)
shellnoob.py --get-const <const>
shellnoob.py --get-sysnum <sysnum>
shellnoob.py --get-errno <errno>
shellnoob.py --file-patch <exe_fp> <file_offset> <data> (en hex). (Advertencia: probado solo en x86/x86_64)
shellnoob.py --vm-patch <exe_fp> <vm_address> <data> (en hex). (Advertencia: probado solo en x86/x86_64)
shellnoob.py --fork-nopper <exe_fp> (esto nopea las llamadas a fork(). Advertencia: probado solo en x86/x86_64)
"Instalación"
shellnoob.py --install [--force] (esto solo copia el script en una ubicación conveniente)
shellnoob.py --uninstall [--force]
Formato INPUT soportado: asm, obj, bin, hex, c, shellstorm
Formato OUTPUT soportado: asm, obj, exe, bin, hex, c, completec, python, bash, ruby, pretty, safeasm
¡Todas las combinaciones de INPUT a OUTPUT están soportadas!
$ ./shellnoob.py --install
Esto solo copiará el script a /usr/local/bin/snoob. Eso es todo. (Ejecuta ./shellnoob.py --uninstall para deshacerlo).
$ snoob --from-asm shell.asm --to-bin shell.bin
Algunas alternativas equivalentes (la herramienta intentará adivinar lo que quieres dada la extensión del archivo..)
$ snoob --from-asm shell.asm --to-bin
$ snoob shell.asm --to-bin
$ snoob shell.asm --to-bin - > shell.bin
$ cat shell.asm | snoob --from-asm - --to-bin - > shell.bin
--intel para usar sintaxis Intel. (ver sección "asm como formato de salida" para más detalles)--from-shellstorm toma como argumento un <shellcode_id>. ShellNoob obtendrá el shellcode seleccionado de la base de datos de shellcodes de shell-storm, y lo convertirá al formato seleccionado.$ snoob -c shell.asm --to-exe shell
$ gdb -q shell
$ run
Reading symbols from ./shell...(no debugging symbols found)...done.
(gdb) run
Starting program: ./shell
Program received signal SIGTRAP, Trace/breakpoint trap.
0x08048055 in ?? ()
(gdb)
O puedes usar los nuevos modificadores --to-strace y --to-gdb!
$ snoob open-read-write.asm --to-strace
Convirtiendo open-read-write.asm (asm) a /tmp/tmpBaQbzP (exe)
execve("/tmp/tmpBaQbzP", ["/tmp/tmpBaQbzP"], [/* 97 vars */]) = 0
[ Process PID=12237 runs in 32 bit mode. ]
open("/tmp/secret", O_RDONLY) = 3
read(3, "thesecretisthedolphin\n", 255) = 22
write(1, "thesecretisthedolphin\n", 22thesecretisthedolphin
) = 22
_exit(0)
$ snoob open-read-write.asm --to-gdb
Convirtiendo open-read-write.asm (asm) a /tmp/tmpZdImWw (exe)
Reading symbols from /tmp/tmpZdImWw...(no debugging symbols found)...done.
(gdb) Breakpoint 1 at 0x8048054
(gdb)
¡Observa cómo ShellNoob establece automáticamente un breakpoint en el punto de entrada!
$ snoob --get-sysnum read
i386 ~> 3
x86_64 ~> 0
$ snoob --get-sysnum fork
i386 ~> 2
x86_64 ~> 57
$ snoob --get-const O_RDONLY
O_RDONLY ~> 0
$ snoob --get-const O_CREAT
O_CREAT ~> 64
$ snoob --get-const EINVAL
EINVAL ~> 22
$ snoob --get-errno EINVAL
EINVAL ~> Invalid argument
$ snoob --get-errno 22
22 ~> Invalid argument
$ snoob --get-errno EACCES
EACCES ~> Permission denied
$ snoob --get-errno 13
13 ~> Permission denied
$ ./shellnoob.py -i --to-opcode
asm_to_opcode selected
>> mov %eax, %ebx
mov %eax, %ebx ~> 89c3
>>
./shellnoob.py -i --to-asm
opcode_to_asm selected
>> 89c3
89c3 ~> mov %eax,%ebx
>>