Статья ASM. Детект виртуальных машин и песочниц по артефактам

Marylin

Mod.Assembler
Red Team
05.06.2019
333
1 478
BIT
872
Logo.webp

Оглавление:

1. Вводная часть​
2. Список возможных мест​
• Аппаратные устройства
• Системный реестр
• Файлы в папке Windows
• Активные процессы
3. Практика​
4. Выводы​



1. Введение

В наш век бурно развивающейся ИТ-индустрии маскировка играет огромную роль. Малварь «с низкой социальной ответственностью» не хочет добровольно ложиться на операционный стол для трепанации кем-бы то нибыло своей тушки, а потому всеми силами пытается скрыть своё присутствие в системе. Инструментам статического и динамического анализа в виде дизассемблеров и отладчиков приходится воевать с довольно умным соперником – как показывает практика, зловредный код всегда идёт на шаг впереди. По этой причине, реверс-инженер должен распознавать в длинных листингах чужого кода последовательность действий, где просвечивается потенциальный обход виртуальных машин и песочниц.

Статический анализ вредоносного кода в IDA практически безопасен для исследователя, хотя в большинстве случаях профит от этого дела сомнителен и стремится к нулю. Обычно его используют на подготовительном этапе для просмотра взаимосвязей, перекрёстных ссылок, или списка импорта из системных DLL. А дальше приходится подключать уже тяжёлую артиллерию отладчиков, чтобы проследить ход событий в реальном времени. Если на данном этапе не оградить периметр своей хостовой системы, то вредоносный код выйдет из под контроля, что может привести к заражению ОС и потере конфиденциальных данных. Здесь и приходят на помощь виртуальные машины типа VirtualBox, VMware, или (менее производительные в данном контексте) эмуляторы Qemu, Bochs и иже с ними.

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

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


2. Координаты мест для раскопок

Вредоносные приложения используют различные методы для идентификации среды исполнения, а специфические её черты упрощают поиск. Как песочницы, так и вирт.машины обычно не могут на 100% точно эмулировать рабочую станцию пользователя – например ВМ имеют ограниченные системные ресурсы, свои драйверы и библиотеки DLL, часто используют жёстко прописанные имена пользователей и компьютеров, и т.д. Так почему-же не воспользоваться этим?

2.1. Аппаратные устройства

Сейчас типичная рабочая станция имеет как минимум: ЦП=2 ядра, ОЗУ=2 ГБ, и HDD=80/120 ГБ. Искусственный интеллект малвари может проверить, подчиняется ли среда этим ограничениям. Отметим, что в отличии от эмуляторов, вирт.машины и песочницы используют оригинальное имя вендора CPU, а потому делать на него ставку не имеет смысла. Частота процессора тоже отображается штатно, а вот ядро/core в большинстве случаях на ВМ одно, тонна оперативы, да динамически увеличивающийся хард примерно в 10..20 гигов. Это действительно только для вирт.машин, т.к. песочницы в этом плане полностью садятся на характеристики рабочей станции.

В дефолтных настройках ВМ девайсы имеют предсказуемые имена – например можно чекнуть модель HDD и DVDROM, производителя и название контроллера графики (включая разрешение дисплея в пикселях). Мы так-же можем искать определённые вирт.устройства, которых заведомо нет в типичной хостовой системе – это каналы Pipe и порты ALPC для связи гостя с хостом. Особое внимание нужно обратить и на MAC-адрес девайса сети, где первые три байта являются идентификатором производителя.

Скорость выполнения инструкций процессора сильно отличается от таковой на вирт.платформе, а потому, чтобы приблизить обстановку к реальной, любая ВМ перехватывает API системных таймеров. К примеру у функции Sleep() всего один аргумент в виде задержки в милли/сек – она останавливает активный поток, а по истечении указанного времени вновь пробуждает. Однако перехватив ВМ анализирует значение этого аргумента, и на выходе из функции возвращает в регистре EAX строго переданное нами время, хотя по вине относительно низкой частоты аппаратного таймера PIT=32.768 КГц, на реальной системе обязательно будут отклонения +/- 1%. Например если мы укажем Sleep(1000) для задержки в 1 сек, то на вирт.машине получим точно EAX=1000, а на реальной чуть меньше EAX=990, или наоборот больше EAX=1010. Данный факт с определённой долей вероятности позволяет выявить работу кода на вирт.машине.

Здесь нужно отметить, что малварь не лыком шита, и в запазухе у неё имеются масса других способов получения тиков системного времени. Она может узнать, перехвачена или нет пользовательская Sleep() или GetTickCount() – для этого достаточно прочитать несколько байт в прологе функции в памяти, после чего загрузить оригинал либы Kernel32.dll с диска, и найдя в ней нужную функцию сравнить два пролога. Если они отличаются, значит ВМ перехватила API сплайсингом и вредонос спускается на уровень ниже, чтобы отправить текущий поток в царство Морфея при помощи NtDelayExecution() из нативной библиотеки Ntdll.dll.

Код:
0: kd> u Sleep           Пролог
   kernel32!Sleep:    ------------
   00000000`7740efa8  ff2542e80700    jmp     qword [kernel32!_imp_Sleep (00000000`7748d7f0)]
   00000000`7740efae  90              nop
   00000000`7740efaf  90              nop
   00000000`7740efb0  90              nop

0: kd> u NtDelayExecution
   ntdll!ZwDelayExecution:
   00000000`77678e00  4c8bd1          mov     r10,rcx
   00000000`77678e03  b831000000      mov     eax,31h
   00000000`77678e08  0f05            syscall
   00000000`77678e0a  c3              ret

В малвари нового поколения встречается ещё один довольно хитрый приём – она вообще не обращается к API таймеров, а читает тики напрямую из доступной юзеру ядерной структуры KUSER_SHARED_DATA, которая проецируется Win всегда по одинаковому адресу 0x7ffe0000 как на х32, так и на х64. Поле TickCountQuad размером qword расположено в ней по смещению 0x320.

Код:
0: kd> dt _KUSER_SHARED_DATA 0x7ffe0000 Tick.
ntdll!_KUSER_SHARED_DATA
   +0x000 TickCountLowDeprecated  : 0
   +0x004 TickCountMultiplier     : 0xf99a027
   +0x320 TickCountQuad           : 0x1e2423
   +0x32c TickCountPad            : 0
0: kd>

Как видим, по смещению(4) лежит множитель – он решает проблему совместимости одной структуры на 2 системы разной разрядности х32/64. Таким образом вместо вызова API GetTickCount() (возвращает кол-во милли/сек с момента запуска системы), можно смело брать тики из KUSER_SHARED_DATA, поскольку судя по листингам дизассма, эта API под катом проделывает то-же самое:

Код:
0: kd> u GetTickCount
kernel32!GetTickCount:
00000000`7730ef40  ff25f2e90700      jmp     qword [kernel32!_imp_GetTickCount (00000000`7738d938)]
00000000`7730ef46  90                nop

0: kd> dps 00000000`7738d938 L5
00000000`7738d938  000007fe`fd101120 KERNELBASE!GetTickCount
00000000`7738d940  000007fe`fd108350 KERNELBASE!GlobalMemoryStatusEx
00000000`7738d948  000007fe`fd113730 KERNELBASE!GetVersion
00000000`7738d950  000007fe`fd13b560 KERNELBASE!GetWindowsDirectoryA
00000000`7738d958  00000000`00000000

;//--------------------------------- x64 ----------------------------
0: kd> u KERNELBASE!GetTickCount
KERNELBASE!GetTickCount:
000007fe`fd101120  8b0c250400fe7f    mov     ecx,dword [SharedUserData+0x004 (00000000`7ffe0004)]
000007fe`fd101127  488b04252003fe7f  mov     rax,qword [SharedUserData+0x320 (00000000`7ffe0320)]

000007fe`fd10112f  480fafc1          imul    rax,rcx   <------ перемножить 2 поля
000007fe`fd101133  48c1e818          shr     rax,18h   <------ поправка к 100 нано/сек блокам (см. MSDN)
000007fe`fd101137  c3                ret

;//--------------------------------- x32 ----------------------------
kd> uf GetTickCount
kernel32!GetTickCount:
7c80934a  ba0000fe7f      mov     edx,offset SharedUserData (7ffe0000)
7c80934f  8b02            mov     eax,dword ptr [edx]
7c809351  f76204          mul     eax,dword ptr [edx+4]
7c809354  0facd018        shrd    eax,edx,18h
7c809358  c3              ret
kd>

2.2. Системный реестр

Реестр Win – это вообще кладезь информации. Вот наиболее интересные ключи и их значения:

HKLM\HARDWARE\Description\System – можно прочитать версию BIOS, которая будет отличаться на реальной и вирт.машине
HKLM\SYSTEM\ControlSet001\Services – службы, среди которых много указывающих на ВМ и песочницу артефактов
HKLM\SYSTEM\CurrentControlSet\Enum\IDE – названия харда и CDROM


reg2.webp


reg3.webp


2.3. Файлы в папке Windows

При установки как песочницы, так и ВМ, они обязательно нагадят в системную папку Win и ProgramFiles. Так-что можно проверить их содержимое, где обнаружим библиотеки и драйвера гипервизора вирт.машины. В папке с программами хоста, VirtualBox создаёт каталог Oracle, но поскольку малварь мы будем пытать не на хосте, а на ВМ, то соответственно нужно чекать либы DLL именно в папке System32 виртуальной среды. Зоопарк там приличный, имена всех библиотек начинаются с префикса VBox***.dll. Организовать их поиск легко функцией FindFirst/NextFile(), которая способна искать файлы как-раз по маске со-звёздочкой(*).

Sys32.webp


reg1.webp


2.4. Активные процессы и модули

Особенностью наиболее распространённой из песочниц Sandboxie является то, что все её файлы имеют префиксы Sbie_xxx. Программное ядро включает в себя три файла – это драйвер SbieDrv.sys, служба SbieSvc.exe, и внедряемая во-все запускаемые из неё процессы Inject-библиотека SbieDll.dll. Таким образом, чтобы с вероятностью 99% поймать за хвост запуск кода из песочницы, достаточно перечислить все загруженные в нашу тушку модули DLL, и проверить среди них наличие либы SbieDll.dll.

В качестве контрольного выстрела можно использовать ещё один трюк. Дело в том, что для полной изоляции среды исполнения, песочницы создают себе отдельный рабочий стол «Desktop» внутри текущей станции. Узнать имя десктопа Sandboxie можно запустив софт «ProcessHacker» или «ProcExplorer» М.Руссиновича из пакета Sysinternals. На скрине ниже видно, что он называется «Default», в то время как на реальной чистой машине система обзывает его по имени раб.станции «WinSta0». Данный факт можно использовать в качестве вещдока.

SandDesktop.webp


3. Практическая часть

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

1. Вендора CPU берём инструкцией CPUID. Для этого нужен цикл начиная с EAX=0x80000002 и до EAX=0x80000004. На каждом шаге CPUID будет возвращать строку в 4-х регистрах общего назначения EAX,EBX,ECX,EDX. Просто сбрасываем их в буфер, и дампим на консоль.​
2. Самый простой способ узнать кол-во ядер процессора – это прочитать их из поля «NumberOfProcessors» по смещению(64) структуры РЕВ.​
Реальную (не заявленную вендором) частоту процессора на текущий момент можно вычислить запросив тики CPU инструкцией RDTSC, затем функцией Sleep(1000) сделать паузу на 1 сек, и повторно прочитать тики. Разница между вторым и первым запросом и будет представлять собой значение «Frequency».​
3. Объём установленной физ.памяти ОЗУ возвращает API GlobalMemoryStatusEx() – здесь всё штатно.​
4. Как упоминалось выше, вирт.машина хукает функцию GetTickCount(), поэтому заснув на 1 сек через Sleep(1000), можно вычислить её.​
5. В некоторых случаях можно прочитать имя машины GetComputerName() – если в ответ получим что-то несуразное, то делаем выводы.​
6. Строку с типом графического адаптера возвращает EnumDisplayDevices(), а разрешение дисплея GetSystemMetrics().​
7. Через RegOpenKeyEx() + RegQueryValueEx() заглянем в реестр Win, чтобы получить версию BIOS.​
8. Функциями из либы Setuapi.dll типа SetupDiEnumDeviceInfo() можно получить строки с именем харда и сидюка – сдают ВМ с потрохами.​
9. Открыв диск чз CreateFile() с последующим IOCTL_DISK_GET_DRIVE_GEOMETRY узнаем ёмкость диска в гигабайтах.​
10. МАС-адрес сетевой карты возвращает GetAdaptersInfo() из либы Iphlpapi.dll.​
11. FindFirst/NextFile() осуществляет поиск файлов по маске Vbox*.dll – остаётся сбросить их на консоль.​
12. В либе Dbghelp.dll имеется функция EnumerateLoadedModules(), которую доктор прописал для перечисления всех модулей в нашем процессе.​
13. И наконец EnumDesktops() возвращает в свой колбек имена всех рабочих столов в текущей станции.​

C-подобный:
format   pe console
include 'win32ax.inc'
include 'equates\iphlpapi.inc'
include 'equates\setupapi.inc'
entry    start
;//-----------
section '.data' data readable writeable
ai             IP_ADAPTER_INFO
devInfo        SP_DEVINFO_DATA
memStat        MEMORYSTATUS_EX
dispDev        DISPLAY_DEVICEA

align  16
struct DISK_GEOMETRY
  totalCyl    dd  0,0   ; - Цилиндров
  mediaType   dd  0     ; - Тип устройства
  trackCyl    dd  0     ; - Дорожек (треков) в цилиндре
  secTrack    dd  0     ; - Секторов в треке
  byteSec     dd  0     ; - Байт в секторе
ends
diskGeo        DISK_GEOMETRY
IOCTL_DISK_GET_DRIVE_GEOMETRY = 0x00070000

sizePointer    dd  0
hndl           dd  0
type           dd  0
mByte          dd  1024*1024
gByte          dd  1024*1024*1024
result         dq  0
buff           db  0
;//-----------
section '.text' code readable executable
start:   invoke  SetConsoleTitle,<'*** Virtual Machine & Sandbox Detect ***',0>

;//----- Инфа о процессоре -------------------------------
         mov     edi,buff
         mov     ecx,3
         mov     eax,0x80000002
@@:      push    eax ecx
         cpuid
         stosd
         xchg    eax,ebx
         stosd
         xchg    eax,ecx
         stosd
         xchg    eax,edx
         stosd
         pop     ecx eax
         inc     eax
         loop    @b
        cinvoke  printf,<10,' CPU name string.....: %s',0>,buff

         mov     eax,[fs:30h]
         mov     eax,[eax+64h]
        cinvoke  printf,<10,' CPU cores...........: %d',0>,eax

         rdtsc
         push    eax
         invoke  Sleep,1000
         rdtsc
         pop     ebx
         sub     eax,ebx
         shr     eax,20
        cinvoke  printf,<10,' CPU frequency.......: %d.0 MHz',0>,eax

;//----- Размер памяти -----------------------------------
         invoke  GlobalMemoryStatusEx,memStat
         push    dword[memStat.dqTotalPhys+4]
         push    dword[memStat.dqTotalPhys]
         fild    qword[esp]
         fidiv   [mByte]
         fstp    [result]
         add     esp,8
        cinvoke  printf,<10,' Physical memory.....: %.1f Mb',0>,\
                              dword[result],dword[result+4]

;//----- Тест по таймеру ---------------------------------
        cinvoke  printf,<10,' Check 1 sec delay...: ',0>
         invoke  GetTickCount
         push    eax
         invoke  Sleep,1000
         invoke  GetTickCount
         pop     ebx
         sub     eax,ebx
        cinvoke  printf,<'%4u.0 msec',0>,eax

;//----- NetBios имя компьютера --------------------------
         mov     [sizePointer],128
         invoke  GetComputerName,buff,sizePointer
         invoke  CharToOem,buff,buff
        cinvoke  printf,<10,10,' Computer name.......: %s',0>,buff

;//----- Графический адаптер -----------------------------
         invoke  EnumDisplayDevices,0,0,dispDev,1
         lea     ebx,[dispDev.DeviceString]
        cinvoke  printf,<10,' Display device......: %s',0>,ebx

         invoke  GetSystemMetrics,SM_CXSCREEN
         push    eax
         invoke  GetSystemMetrics,SM_CYSCREEN
         pop     ebx
        cinvoke  printf,<'. %d x %d',0>,ebx,eax

;//----- Версия биос из реестра --------------------------
         call    ClearBuff
         invoke  RegOpenKeyEx,HKEY_LOCAL_MACHINE,<'Hardware\Description\System',0>,0,KEY_ALL_ACCESS,hndl
         mov     [sizePointer],64
         invoke  RegQueryValueEx,[hndl],<'SystemBiosVersion',0>,0,type,buff,sizePointer
        cinvoke  printf,<10,' Bios Version........: %s',10,0>,buff

;//----- Имя харда и CD через SetupApi.dll ---------------
         call    ClearBuff
         invoke  SetupDiGetClassDevs,GUID_DEVCLASS_CDROM,0,0,DIGCF_PROFILE
         push    eax
         invoke  SetupDiEnumDeviceInfo,eax,0,devInfo
         pop     eax
         invoke  SetupDiGetDeviceRegistryProperty,eax,devInfo,SPDRP_FRIENDLYNAME,0,buff,128,0
        cinvoke  printf,<10,' CD/DVDROM  name.....: %s',0>,buff

         call    ClearBuff
         invoke  SetupDiGetClassDevs,GUID_DEVCLASS_DISKDRIVE,0,0,DIGCF_PRESENT
         push    eax
         invoke  SetupDiEnumDeviceInfo,eax,0,devInfo
         pop     eax
         invoke  SetupDiGetDeviceRegistryProperty,eax,devInfo,SPDRP_FRIENDLYNAME,0,buff,128,0
        cinvoke  printf,<10,' Hard drive name.....: %s',0>,buff

;//----- Размер диска ------------------------------------
         call    ClearBuff
         invoke  CreateFile,<'\\.\PhysicalDrive0',0>,0,FILE_SHARE_READ + FILE_SHARE_WRITE,\
                                 0,OPEN_EXISTING,0,0
         push    eax
         invoke  DeviceIoControl,eax,IOCTL_DISK_GET_DRIVE_GEOMETRY,\
                                 0,0,diskGeo,sizeof.DISK_GEOMETRY,type,0
         pop     eax
         invoke  CloseHandle,eax

         mov     eax,[diskGeo.byteSec]
         imul    eax,[diskGeo.secTrack]
         imul    eax,[diskGeo.trackCyl]
         mov     [type],eax

         fild    qword[diskGeo.totalCyl]
         fimul   [type]
         fidiv   [gByte]
         fstp    [result]
        cinvoke  printf, <10,' Hard drive size.....: %.1f Gb',10,0>,dword[result],dword[result+4]

;//----- МАС сетевой карты -------------------------------
         invoke  GetAdaptersInfo,ai,sizePointer
         invoke  GetAdaptersInfo,ai,sizePointer
         movzx   eax,[ai.Address+0]
         movzx   ebx,[ai.Address+1]
         movzx   ecx,[ai.Address+2]
         movzx   edx,[ai.Address+3]
         movzx   esi,[ai.Address+4]
         movzx   edi,[ai.Address+5]
        cinvoke  printf,<10,' NIC MAC address.....: %02x:%02x:%02x:%02x:%02x:%02x',\
                         10,'                       --------',\
                         10,'                       08:00:27: <----- VBox   v5.2',\
                         10,'                       00:21:f6:               v3.3',\
                         10,'                       52:54:00:               Vagrant or QEMU',\
                         10,'                       --------',\
                         10,'                       00:50:56: <----- VMware Workstation',\
                         10,'                       00:0c:29:               ESXi Host ',\
                         10,'                       00:05:69:               ESXi,GSX',\
                         10,'                       00:1c:14:               VMware',10,0>,\
                         eax,ebx,ecx,edx,esi,edi

;//----- Библиотеки в Windows\system32 -------------------
         call    ClearBuff
         invoke  FindFirstFile,<'C:\Windows\System32\VBox*.dll',0>,buff
         mov     [hndl],eax
        cinvoke  printf,<10,' VBox \System32 dll..: %s',0>,buff+44
         cmp     [hndl],0
         jz      @f
@next:   invoke  FindNextFile,[hndl],buff
         or      eax,eax
         jz      @f
        cinvoke  printf,<10,23 dup(' '),'%s',0>,buff+44
         jmp     @next
@@:      invoke  CloseHandle,[hndl]

;//----- Sandbox - загруженные в процесс библиотеки ------
        cinvoke  printf,<10,10,' Sandboxie dll test..: ',0>
         invoke  GetCurrentProcess
         invoke  EnumerateLoadedModules,eax,EnumCallback,0

;//----- Перечисление рабочих столов Desktop -------------
        cinvoke  printf,<10,' Sandboxie Desktop...: ',0>
         invoke  EnumDesktops,0,DesktopCallback,0

@exit:  cinvoke  _getch
        cinvoke  exit, 0

;//********************************************************
proc  ClearBuff
         mov     edi,buff
         mov     ecx,128/4
         xor     eax,eax
         rep     stosd
         ret
endp
proc  EnumCallback Name,Base,Size,Context
         mov     esi,[Name]
@@:      lodsb
         or      al,al
         jnz     @b
         sub     esi,12
         lodsd
         cmp     eax,'Sbie'
         jnz     @01
         sub     esi,4
        cinvoke  printf,<'%s <--- Found!',0>,esi
@01:     mov     eax,1
         ret
endp
proc  DesktopCallback Desktop,lParam
         push    esi
         mov     esi,[Desktop]
         cmp     dword[esi],'Defa'
         jnz     @02
        cinvoke  printf,<'%s <------- Found! ',0>,[Desktop]
@02:     pop     esi
         mov     eax,1
         ret
endp
;//********************************************************

section '.idata' import data readable writeable
library  msvcrt,'msvcrt.dll',kernel32,'kernel32.dll',\
         user32,'user32.dll',iphlpapi,'iphlpapi.dll',\
         advapi32,'advapi32.dll',setupapi,'setupapi.dll',dbghelp,'dbghelp.dll'
import   dbghelp, EnumerateLoadedModules,'EnumerateLoadedModules'
include 'api\msvcrt.inc'
include 'api\kernel32.inc'
include 'api\user32.inc'
include 'api\iphlpapi.inc'
include 'api\setupapi.inc'
include 'api\advapi32.inc'

Теперь посмотрим на табун подстреленных зайцев..
Вот что вернул код на моей реальной машине с Win7 на борту.
Обратите внимание на значение 1 сек задержки, которая в данном случае равна 998 м/сек (погрешность таймера PIT), хотя я запрашивал ровно 1000. А в остальном ничего особенного, с реально присутствующим железом на моём экспериментальном узле:

Win7.webp

А дальше лог кода, который я запустил уже в песочнице Sandboxie.
В принципе всё аналогично, если не считать без спроса заинжектенную в мой процесс левую библиотеку SbieDll.dll, а так-же рабочий стол «Default». Если-бы не этот нюанс, обнаружить песочницу было-бы весьма проблематично:

SBox.webp

Зато под VirtualBox хоть к гадалке не ходи – артефактов как грибов после дождя.
Во-первых, сколько-бы раз я не запускал этот код, Sleep(1000) в шапке всегда возвращает ровно переданное мною значение 1000 м/сек, что непременно вызывает подозрение. Ну и далее всё по нарастающей: графика, биос, диски, физ.адрес сети, и либы в системной папке. Такое впечатление, что разработчики вообще не ставили перед собой задачу что-то скрыть, хотя реализовать это не так-уж сложно было. С другой стороны, у вирт.машин совсем другое предназначение, с чем они отлично справляются.

VBox.webp


4. Выводы

Под занавес хотелось-бы сказать, что если малварь так боится виртуальных машин и песочниц, значит можно её обмануть, создав фиктивную обстановку тестовой среды. К примеру написать какую-нибудь безобидную либу обозвав её SbieDll.dll и поместить в автозагрузку, или набросать в системную папку кучу текстовых файлов переименовав их в VВox*.dll из списка выше, и далее в том-же духе. Тогда после своих тестов зловредный код может клюнуть на удочку, и добровольно отказаться от заражения системы посчитав, что попал в виртуальную среду отладки. Пусть и не на 100%, но это ещё более укрепит оборонную крепость системы.

В скрепку положил исполняемый файл для тестов. Эксперименты я гонял на вирт.машине VBox, а спец для этого дела ставить VMware было лень. Поэтому если у кого имеется варя с установленной на неё Win от XP до 10 любой разрядности, просьба показать реакцию машины на этот код. В частности интересует названия аппаратных устройств, в т.ч. диски, МАС-адрес, и да и всё остальное. Буду премного благодарен, всем удачи, пока!



Ссылки по теме:

Список малвари, и варианты её обхода вирт.машин:​
МАС-адреса виртуальных машин:​
 

Вложения

Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!