И снова привет хабру еще раз! Прошлый пост был по 7 главе, где я написал о том что сегодня выйдет 8 отрывок из 8 главы, соответственно вот он. Так, как 8 глава - глава о шеллкодах, то я выбрал по моему мнению наиболее подходящий отрывок:
Глава 8. Написание шеллкодов на Rust
Поскольку у моего первого компьютера был всего 1 ГБ оперативной памяти (Asus EeePC), мои хобби были очень низкоуровневыми и нетребовательными к ресурсам.
Одно из таких хобби было создание шеллкодов. Не ради наступательного взлома или чего-то подобного, а просто ради искусства написания ассемблера x86. Можно потратить огромное количество времени на создание шеллкодов: ASCII-шеллкоды (шеллкоды, финальное шестнадцатеричное представление которых состоит только из байтов ASCII-таблицы), полиморфные шеллкоды (шеллкоды, которые могут переписывать сами себя и тем самым снижают обнаружимость и замедляют реверс-инжиниринг…). Как и в поэзии, пределы ставит только ваше воображение.
8.1 Что такое шеллкод
Цель эксплойта — выполнить код. Шеллкод — это сырой код, выполняемый на эксплуатируемой машине.
Но есть проблема: написание шеллкодов обычно выполняется напрямую на ассемблере. Это даёт вам абсолютный контроль над тем, что вы создаёте, но недостаток в том, что это требует много знаний, трудно отлаживать, абсолютно не переносимо между архитектурами и является кошмаром для переиспользования и сопровождения с течением времени и командами из нескольких разработчиков.
Вот пример шеллкода:
488d35140000006a01586a0c5a4889c70f056a3c5831ff0f05ebfe68656c6c6f20776f726c640a
Не поняли? Это нормально. Это шестнадцатеричное представление не помогает.
Но, записав его в файл:
$ echo '488d35140000006a01586a0c5a4889c70f056a3c5831ff0f05ebfe68656c6c6f20776f726c640a' \
| xxd -r -p > shellcode.bin
и дизассемблировав:
$ objdump -D -b binary -mi386 -Mx86-64 -Mintel shellcode.bin
shellcode.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: 48 8d 35 14 00 00 00 lea rsi,[rip+0x14] # 0x1b
7: 6a 01 push 0x1
9: 58 pop rax
a: 6a 0c push 0xc
c: 5a pop rdx
d: 48 89 c7 mov rdi,rax
10: 0f 05 syscall # <- write(1, "hello world\n", 12)
12: 6a 3c push 0x3c
14: 58 pop rax
15: 31 ff xor edi,edi
17: 0f 05 syscall # <- exit
19: eb fe jmp 0x19
1b: 68 65 6c 6c 6f push 0x6f6c6c65 # <- hello world\n
20: 20 77 6f and BYTE PTR [rdi+0x6f],dh
23: 72 6c jb 0x91
25: 64 fs
26: 0a .byte 0xa
Это раскрывает реальный фрагмент кода, который по сути делает:
write(STOUDT, "hello world\n", 12);
exit(0);
Но, будучи сырым кодом intel x86_64, он не может быть выполнен операционной системой как есть. Его нужно обернуть в исполняемый файл.
Напоминаю главы, переводы и исходники лежат у пеня на гитхабе вот репо: https://github.com/smokeplay250-png/black-hat-ru
Если кому то код код не зашел или вы нашли ошибки скажем как в посте про 5 главу с инъекциями, то не спешите писать об этом в комментах. Напомню, что код в переводах я не трогаю необходимости пока нету.
Комментарии 0