
A shellcode writing toolkit
Написание шеллкодов всегда было супер веселым, но некоторые части чрезвычайно скучны и чреваты ошибками. Сосредоточьтесь только на веселой части и используйте ShellNoob!
Для быстрого ознакомления посмотрите слайды доклада на Black Hat Arsenal: ссылка
Есть желание внести вклад? Предложить функцию? Сообщить об ошибке? Обругать? Любая обратная связь приветствуется!! (Но некоторые виды обратной связи приветствуются больше, чем другие :-)).
Не стесняйтесь пинговать меня в твиттере @reyammer или писать на email yanick[AT]cs.ucsb.edu с любыми вопросами!
01/21/2014 - Вышел ShellNoob 2.1! Включает полную поддержку Python 3 и множество исправлений ошибок. Вся заслуга принадлежит Levente Polyak!
07/29/2013 - Вышел ShellNoob 2.0!
06/08/2013 - ShellNoob был принят на Black Hat Arsenal! Объявление здесь: ссылка.
--intel.--64.-c.--to-strace и --to-gdb!--file-patch, --vm-patch, ! (все подробности ниже)$ ./shellnoob.py -h
shellnoob.py [--from-INPUT] (input_file_path | - ) [--to-OUTPUT] [output_file_path | - ]
shellnoob.py -c (prepend a breakpoint (Warning: only few platforms/OS are supported!)
shellnoob.py --64 (64 bits mode, default: 32 bits)
shellnoob.py --intel (intel syntax mode, default: att)
shellnoob.py -q (quite mode)
shellnoob.py -v (or -vv, -vvv)
shellnoob.py --to-strace (compiles it & run strace)
shellnoob.py --to-gdb (compiles it & run gdb & set breakpoint on entrypoint)
Standalone "plugins"
shellnoob.py -i [--to-asm | --to-opcode ] (for interactive mode)
shellnoob.py --get-const <const>
shellnoob.py --get-sysnum <sysnum>
shellnoob.py --get-errno <errno>
shellnoob.py --file-patch <exe_fp> <file_offset> <data> (in hex). (Warning: tested only on x86/x86_64)
shellnoob.py --vm-patch <exe_fp> <vm_address> <data> (in hex). (Warning: tested only on x86/x86_64)
shellnoob.py --fork-nopper <exe_fp> (this nops out the calls to fork(). Warning: tested only on x86/x86_64)
"Installation"
shellnoob.py --install [--force] (this just copies the script in a convinient position)
shellnoob.py --uninstall [--force]
Supported INPUT format: asm, obj, bin, hex, c, shellstorm
Supported OUTPUT format: asm, obj, exe, bin, hex, c, completec, python, bash, ruby, pretty, safeasm
All combinations from INPUT to OUTPUT are supported!
$ ./shellnoob.py --install
Это просто скопирует скрипт в /usr/local/bin/snoob. Вот и всё. (Запустите ./shellnoob.py --uninstall, чтобы отменить).
$ snoob --from-asm shell.asm --to-bin shell.bin
Некоторые эквивалентные альтернативы (инструмент попытается угадать, что вам нужно, по расширению файла..)
$ 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 для синтаксиса Intel. (см. раздел "Asm как выходной формат" для подробностей)--from-shellstorm принимает в качестве аргумента <shellcode_id>. ShellNoob загрузит выбранный шеллкод из базы шеллкодов shell-storm и преобразует его в выбранный формат.$ 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)
Или вы можете использовать новые ключи --to-strace и --to-gdb!
$ snoob open-read-write.asm --to-strace
Converting open-read-write.asm (asm) into /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
Converting open-read-write.asm (asm) into /tmp/tmpZdImWw (exe)
Reading symbols from /tmp/tmpZdImWw...(no debugging symbols found)...done.
(gdb) Breakpoint 1 at 0x8048054
(gdb)
Обратите внимание, как ShellNoob автоматически устанавливает точку останова на точке входа!
$ 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
>>
$ python
>>> from shellnoob import ShellNoob
>>> sn = ShellNoob(flag_intel=True)
>>> sn.asm_to_hex('nop; mov ebx,eax; xor edx,edx')
'9089c331d2'
>>> sn.hex_to_inss('9089c331d2')
['nop', 'mov ebx,eax', 'xor edx,edx']
>>> sn.do_resolve_syscall('fork')
i386 ~> 2
x86_64 ~> 57
Когда "asm" является выходным форматом, ShellNoob старается изо всех сил. Objdump используется как дизассемблер, но его вывод не является абсолютно надежным. ShellNoob пытается дополнить дизассемблированный код, добавляя байты (нотация .byte), и, когда уместно, отображает эквивалент в ASCII (нотация .ascii). Это полезно, когда вы хотите изменить/ассемблировать вывод objdump, но вам нужно быстро исправить.
Пример с нотацией .byte:
jmp 0x37 # .byte 0xeb,0x35
pop %ebx # .byte 0x5b
mov %ebx,%eax # .byte 0x89,0xd8
add $0xb,%eax # .byte 0x83,0xc0,0x0b
xor %ecx,%ecx # .byte 0x31,0xc9
Пример с нотацией .ascii:
das # .ascii "/"
je 0xac # .ascii "tm"
jo 0x70 # .ascii "p/"
jae 0xa8 # .ascii "se"
arpl %si,0x65(%edx) # .ascii "cre"
je 0xa0 # .ascii "tX
ShellNoob распространяется под лицензией MIT. Смотрите файл COPYRIGHT.
--fork-nopper