![](https://habrastorage.org/webt/3k/rh/jz/3krhjzsu21e9pm5nd3menzbisas.jpeg)
Lazarus привлекала своих жертв при помощи документов о вакансиях в таких компаниях, как LockHeed Martin, BAE Systems и Boeing. В данном конкретном случае злоумышленники привлекали жертв, ищущих работу в Boeing, при помощи документа Boeing BDS MSE.docx ( твит ShadowChasing1). Вредоносное ПО извлекает имя хоста, имя пользователя, информацию о сети, список процессов и другую информацию, которая затем должна была передаваться на один из четырёх серверов C2. Предназначенные для передачи данные сжимались, шифровались XOR, кодировались Base64 и отправлялись на сервер C2. Троян реализует четыре действия, в том числе скачивает и исполняет файл .exe или .dll, загружает PE (Portable Executable) в память процессов и исполняет шелл-код.
▍ Технический анализ
SHA256: 803dda6c8dc426f1005acdf765d9ef897dd502cd8a80632eef4738d1d7947269
Файл является DLL, имеющим 7 экспортов. Лишь одна из этих функций выполняет зловредное действие (DllGetFirstChild):
![](https://habrastorage.org/webt/ln/i0/2g/lni02gi77xzwmcrmde_58l0qzt0.jpeg)
Рисунок 1
Вредоносное ПО вызывает функцию ObtainUserAgentString для получения User Agent. Кроме того, в двоичном файле прописан User Agent «Mozilla / 5.0 (Windows NT 10.0; WOW64; Trident / 7.0; rv:11.0) li», то есть Internet Explorer в Windows 10:
![](https://habrastorage.org/webt/lo/ci/bp/locibppoz7zfoctenlt_cdzvwnm.jpeg)
Рисунок 2
Двоичный файл извлекает текущие системные дату и время при помощи GetSystemTimeAsFileTime API:
![](https://habrastorage.org/webt/lf/vm/oj/lfvmojg9sic_ooljdbcasx4ufpa.jpeg)
Рисунок 3
Для получения дескриптора модуля из ntdll.dll используется GetModuleHandleW:
![](https://habrastorage.org/webt/sd/qv/qe/sdqvqewrk6wbdwxorflkc-j5loo.jpeg)
Рисунок 4
Процесс при помощи подпрограммы GetProcAddress получает адрес следующих функций экспорта: "
RtlGetCompressionWorkSpaceSize
", "RtlCompressBuffer
", "RtlDecompressBuffer
", "RtlGetVersion
". Пример вызова функции показан на рисунке 5:![](https://habrastorage.org/webt/x5/rb/e_/x5rbe_ser7falqm-rzut9fzgguo.jpeg)
Рисунок 5
При помощи вызова функции
GetComputerNameW
получается название локального компьютера в NetBIOS:![](https://habrastorage.org/webt/bt/sq/34/btsq34en6flgvjiqni66lj9tkoi.jpeg)
Рисунок 6
GetAdaptersInfo API используется для получения информации об адаптере с локальной машины:
![](https://habrastorage.org/webt/zx/uj/rm/zxujrmw1bfxulnpqwemzauc0zyk.jpeg)
Рисунок 7
Извлечённый ранее MAC-адрес записывается в буфер:
![](https://habrastorage.org/webt/jf/mq/tk/jfmqtkld9cv8b91wjxylhuex6bs.jpeg)
Рисунок 8
Файл извлекает string командной строки текущего процесса:
![](https://habrastorage.org/webt/9a/vp/fm/9avpfmdieed3cyc9p3s0q9fnwew.jpeg)
Рисунок 9
CommandLineToArgvW
используется для извлечения массива указателей на аргументы командной строки и количества аргументов (аналогично argv и argc):![](https://habrastorage.org/webt/83/gu/rk/83gurkzaidm3xrzddfgy5kd8h7c.jpeg)
Рисунок 10
Согласно статье, зловредное ПО должно было запускаться со следующими параметрами:
NTPR P6k+pR6iIKwJpU6oR6ZilgKPL7IxsitJAnpIYSx2KldSSRFFyUIzTBVFAwgzBkI2PS/+EgASBik/GgYBwBbRNy7pP+Xq4uTsxOXU6NPmudaEz7Xy5fLQica6yKHvtu2XkYmnhfeC/4ythf9I6UbAdvxvy1K2Um5ppVrEQY9WiHdxKbolqiKgLMElwSiKJrcWrQ+cMpYy5cnc+s/hufap15LJmsVFwr7MlMWwiLCGgLZPr4uSk5KIqZiadYGOlkS3cml1ZZdiZmyzZVpovmZiVlNPNXJsck4JXzpPIWw2YBcqCRMFCQJBDG4FfchmxkL2fO8V0jbSTeko2u/BI9YA9zGpM6UWoiGsdaVdqAmmIpYHjzWyM7IOSQR6SGE4dilXB0lfRXtCOEwkRTAIMgYWNnsvVRJSEvQp/xryAdsW1Df76fjl3eIb7M7lIujH5vbW7c/e8tTy2on1uuGh+rbml5GJp4X3gv+MrYXwSOFGzHbxb9BSwFLLaaJau0FNVoh3sim4JZYi1Cz1JZYohya0FpEP9TKZMpTJgvqn4e72sdefyZrF4sI=&
Двоичный файл расшифровывает этот параметр при помощи алгоритма, показанного на рисунке 11. Список получившихся строк содержит несколько серверов C2:
![](https://habrastorage.org/webt/dq/bo/5n/dqbo5n4gf2qywajwn3tjqvttquy.jpeg)
Рисунок 11
![](https://habrastorage.org/webt/oi/lw/pp/oilwppskzpfbs-fzrc49v513tuc.jpeg)
Рисунок 12
В процессе реверс-инжиниринга расшифрованы следующие URL:
- https[:]//mante.li/images/draw.php
- https[:]//bmanal.com/images/draw.php
- https[:]//shopandtravelusa.com/vendor/monolog/monolog/src/Monolog/monolog.php
- https[:]//industryinfostructure.com/templates/worldgroup/view.php
Подпрограмма
GetNetworkParams
используется для получения сетевых параметров локального компьютера:![](https://habrastorage.org/webt/5k/8s/5m/5k8s5mjolnjxxrrcydctrzslcl8.jpeg)
Рисунок 13
Зловредный процесс извлекает имя DNS-домена, назначенного локальному хосту (0x2 = ComputerNameDnsDomain:
![](https://habrastorage.org/webt/gm/ul/og/gmulogdhlqpzihwgf3f5wc6mts0.jpeg)
Рисунок 14
Во временный буфер записывается следующая сетевая информация:
![](https://habrastorage.org/webt/bn/_8/u8/bn_8u8vead1olt9xbuxipmdjrxk.jpeg)
Рисунок 15
![](https://habrastorage.org/webt/eq/gv/on/eqgvon_uuoxyrqnssjbq3sunbmy.jpeg)
Рисунок 16
Вызывая функцию
GetUserNameW
, процесс получает имя пользователя, связанное с текущим потоком:![](https://habrastorage.org/webt/fg/g-/uj/fgg-uj59-cy_i0gjovtd8i6qkkk.jpeg)
Рисунок 17
Двоичный файл делает снэпшот всех процессов в системе при помощи CreateToolhelp32Snapshot API (0x2 = TH32CS_SNAPPROCESS):
![](https://habrastorage.org/webt/mj/sd/0i/mjsd0ilo4jjzkoiniip1va6278m.jpeg)
Рисунок 18
Файл извлекает информацию о первом процессе из снэпшота при помощи вызова
Process32FirstW
:![](https://habrastorage.org/webt/fn/4q/dj/fn4qdjjjy2vqoyngm_ialfmecle.jpeg)
Рисунок 19
Затем двоичный файл открывает объект процесса при помощи подпрограммы OpenProcess (0x410 = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ):
![](https://habrastorage.org/webt/rp/xh/vs/rpxhvsexbzbdt-tlewvnn8uudfy.jpeg)
Рисунок 20
Если у файла не хватает прав для открытия процесса, он копирует во временный буфер «Unknown» с именем процесса.
Далее он при помощи CreateToolhelp32Snapshot API (0x8 = TH32CS_SNAPMODULE) делает снэпшот текущего процесса со всеми его модулями:
![](https://habrastorage.org/webt/qb/bj/eg/qbbjeg7mxgnupk-amgchqlhimt4.jpeg)
Рисунок 21
Для получения информации о первом модуле, связанном с текущим процессом, используется
Module32FirstW
:![](https://habrastorage.org/webt/id/uf/t9/iduft9frmqmjihzzuvvkcwip-yo.jpeg)
Рисунок 22
Зловредный DLL получает информацию о следующем процессе, записанном в снэпшот:
![](https://habrastorage.org/webt/jm/ic/fh/jmicfhux3qab_mypx4k0lgd1hw0.jpeg)
Рисунок 23
Для открытия связанного с процессом токена доступа используется подпрограмма OpenProcessToken (0x8 = TOKEN_QUERY):
![](https://habrastorage.org/webt/p-/0q/qv/p-0qqvd76tejdwpmfq2yiqgmdq8.jpeg)
Рисунок 24
Для извлечения аккаунта пользователя токена используется GetTokenInformation (0x1 = TokenUser):
![](https://habrastorage.org/webt/n8/ox/el/n8oxelxab0fz7tskyhnwkr5mqlw.jpeg)
Рисунок 25
При помощи вызова функции
LookupAccountSidW
процесс получает имя аккаунта для SID и имя первого домена, в котором найден SID:![](https://habrastorage.org/webt/l-/my/6q/l-my6qva90wzg9gvpwti5csvpak.jpeg)
Рисунок 26
Для извлечения идентификатора связанной с токеном сессии Terminal Services используется GetTokenInformation (0xC = TokenSessionId):
![](https://habrastorage.org/webt/7w/yb/6u/7wyb6uroka82fuqpy1sgg8ecmy4.jpeg)
Рисунок 27
Чтобы определить нужный размер буфера WorkSpace для функции RtlCompressBuffer используется RtlGetCompressionWorkSpaceSize API (0x102 = COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM):
![](https://habrastorage.org/webt/v2/ax/fv/v2axfv6gcip8w7rjjxswkq9waie.jpeg)
Рисунок 28
При помощи функции
RtlCompressBuffer
процесс сжимает буферы, показанные на рисунках 15 и 16 (0x102 = COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM):![](https://habrastorage.org/webt/ik/pd/xm/ikpdxmylsz4zicpl-74phyxbkf4.jpeg)
Рисунок 29
DLL случайным образом выбирает один из четырёх серверов C2 в списке, а потом при помощи вызова
InternetOpenW
инициализирует использование приложением функций WinINet
:![](https://habrastorage.org/webt/ex/pt/o8/expto8nodxyol6dzg7ayz8pzqqo.jpeg)
Рисунок 30
Для приведения URL в каноничный вид используется
InternetCanonicalizeUrlW
:![](https://habrastorage.org/webt/vj/mk/hf/vjmkhfqe-qqihaosrbliy5vruq8.jpeg)
Рисунок 31
При помощи вызова InternetCrackUrlW API зловред разбивает URL на компоненты:
![](https://habrastorage.org/webt/df/hd/1w/dfhd1wftgitqjfw3b7usecirmbc.jpeg)
Рисунок 32
При помощи подпрограммы InternetSetOptionW устанавливаются таймауты подключения, отправки и получения на 150 с (0x2 = INTERNET_OPTION_CONNECT_TIMEOUT, 0x5 = INTERNET_OPTION_SEND_TIMEOUT, 0x6 = INTERNET_OPTION_RECEIVE_TIMEOUT):
![](https://habrastorage.org/webt/y0/rc/jw/y0rcjwdcxu9hureecy_bzlqvxyu.jpeg)
Рисунок 33
![](https://habrastorage.org/webt/q2/j4/kw/q2j4kw9fixajads2b3xyc5tj8ke.jpeg)
Рисунок 34
![](https://habrastorage.org/webt/ka/zy/4g/kazy4g-40-zu1wlm-egcap3noco.jpeg)
Рисунок 35
DLL открывает HTTP-сессию с сервером C2 через порт 443 (0x3 = INTERNET_SERVICE_HTTP):
![](https://habrastorage.org/webt/vi/co/te/vicote3ufn2r_aggzbv8ddoc_ao.jpeg)
Рисунок 36
Двоичный файл создаёт дескриптор POST-запроса к URI, извлечённому из указанного URL:
![](https://habrastorage.org/webt/ud/_t/sx/ud_tsxzswizpsxcinbqgwtw-7my.jpeg)
Рисунок 37
Флаги безопасности для дескриптора задаются при помощи InternetSetOptionW API (0x1F = INTERNET_OPTION_SECURITY_FLAGS, 0xF180 = SECURITY_FLAG_IGNORE_REVOCATION | SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTP | SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTPS):
![](https://habrastorage.org/webt/we/az/ec/weazec00y4tvbegtpnmoqnhmkeu.jpeg)
Рисунок 38
Ранее сжатый буфер (конкатенация двух буферов) шифруется при помощи XOR (ключ = 32-байтный массив):
![](https://habrastorage.org/webt/rq/zd/za/rqzdzaxjqmkpved_y3fzcza2-mc.jpeg)
Рисунок 39
![](https://habrastorage.org/webt/z4/fx/ev/z4fxevkezrbeoqrifoxnrqhxlgo.jpeg)
Рисунок 40
Далее зашифрованный буфер кодируется при помощи Base64:
![](https://habrastorage.org/webt/ha/vs/0o/havs0oau18hmqcox-kfkvbvfr08.jpeg)
Рисунок 41
![](https://habrastorage.org/webt/bp/98/vj/bp98vj-4v17md73keni9v3pokpm.jpeg)
Рисунок 42
Двоичный файл создаёт следующие параметры: «search=YOIPOUP&ei=6128&oq=<Base64-encoded buffer>»:
![](https://habrastorage.org/webt/ve/p-/qu/vep-quternrosazbqr-dzllpvpm.jpeg)
Рисунок 43
Извлечённый ранее User Agent добавляется к дескриптору HTTP-запроса при помощи подпрограммы HttpAddRequestHeadersW (0xA0000000 = HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD):
![](https://habrastorage.org/webt/zr/v7/uk/zrv7ukd_wldnydux5qm0wvawrps.jpeg)
Рисунок 44
Для передачи данных на сервер C2 используется HttpSendRequestW:
![](https://habrastorage.org/webt/aa/nu/93/aanu93ad_7pnecw2kbzritotbda.jpeg)
Рисунок 45
Стоит отметить, что на момент выполнения нашего анализа все серверы C2 уже были отключены. Мы эмулировали сетевые соединения при помощи FakeNet.
Размер ответа C2 получается при помощи вызова подпрограммы HttpQueryInfoW (0x5 = HTTP_QUERY_CONTENT_LENGTH):
![](https://habrastorage.org/webt/dd/bh/vd/ddbhvdy-devxnuq6ggxtcgznazo.jpeg)
Рисунок 46
Двоичный файл копирует ответ C2 в буфер при помощи вызова функции InternetReadFile:
![](https://habrastorage.org/webt/kc/19/j6/kc19j6rqaoickcbbfpf9mo913fk.jpeg)
Рисунок 47
Зловредный процес парсит данные между тэгами
<html></html>
и <div></div>
:![](https://habrastorage.org/webt/92/nh/ix/92nhixajf94b92qqk-m6-nzo3vc.jpeg)
Рисунок 48
Зловредное ПО выполняет похожий POST-запрос с другими значениями параметров: «search=DOWPANY&ei=6128»:
![](https://habrastorage.org/webt/g6/0g/ye/g60gyerq6xzwnfsf39rnymxblau.jpeg)
Рисунок 49
Ответ C2 декодируется при помощи Base64, а затем расшифровывается XOR. Зловредный код реализует четыре разных действия на основании значения регистра EAX:
![](https://habrastorage.org/webt/ta/8q/sq/ta8qsqkducxwuwn6bjser4-pk6e.jpeg)
Рисунок 50
EAX = 0 — загрузка PE в память текущего процесса
Для получения информации о текущей системе используется GetNativeSystemInfo:
![](https://habrastorage.org/webt/za/xu/a5/zaxua5zpvqosea3_r3anq5jz0w8.jpeg)
Рисунок 51
DLL выполняет несколько вызовов функции VirtualAlloc, выделяющих память под новый исполняемый файл (0x3000 = MEM_COMMIT | MEM_RESERVE, 0x4 = PAGE_READWRITE):
![](https://habrastorage.org/webt/dv/sh/9h/dvsh9hzv8ypcdc_dri3khmyicwa.jpeg)
Рисунок 52
Зловредный код в зависимости от сегмента меняет защиту памяти (например, защита памяти для сегмента кода установлена на 0x20 = PAGE_EXECUTE_READ):
![](https://habrastorage.org/webt/fi/zo/jx/fizojx-_xubaboargfrmaszyncy.jpeg)
Рисунок 53
Спустя ещё несколько операций процесс передаёт поток управления новому PE.
EAX = 1 — скачать и исполнить файл .exe
Двоичный файл получает путь к папке AppData, вызывая подпрограмму SHGetFolderPathW (0x1c = CSIDL_LOCAL_APPDATA):
![](https://habrastorage.org/webt/kf/v9/x1/kfv9x1hz1ydsud8wjgymedskvzg.jpeg)
Рисунок 54
Для получения количества секунд после запуска системы используется GetTickCount:
![](https://habrastorage.org/webt/ct/gt/-h/ctgt-hj7cs1lvqyszavxzvtkgx8.jpeg)
Рисунок 55
Зловредный код создаёт файл на основании указанного выше значения (0x40000000 = GENERIC_WRITE, 0x1 = FILE_SHARE_READ, 0x2 = CREATE_ALWAYS, 0x80 = FILE_ATTRIBUTE_NORMAL):
![](https://habrastorage.org/webt/pg/og/ia/pgogiazz5tvjfacam1qiqdew-mm.jpeg)
Рисунок 56
Созданный файл заполняется содержимым, который должен быть передан на сервер C2:
![](https://habrastorage.org/webt/8y/2t/9l/8y2t9lndrhra1evearpeytbv8dk.jpeg)
Рисунок 57
Зловредный двоичный код исполняет файл, вызывая CreateProcessW API:
![](https://habrastorage.org/webt/or/ds/x-/ordsx-nxc2tqh302sfsgqzchh-u.jpeg)
Рисунок 58
EAX = 2 — скачать и исполнить файл .dll
Поток исполнения схож с показанным выше, поэтому мы покажем только различия. Для исполнения файла DLL используется Rundll32.exe (также в командной строке может быть задана функция экспорта):
![](https://habrastorage.org/webt/ba/rx/fd/barxfdhd8vajut4vrwc7owonk7o.jpeg)
Рисунок 59
EAX = 3 — копировать и исполнить шелл-код
Процесс выделяет память при помощи подпрограммы VirtualAlloc (0x1000 = MEM_COMMIT, 0x40 = PAGE_EXECUTE_READWRITE):
![](https://habrastorage.org/webt/in/hp/ku/inhpkuv7uptyancaitwexbx__9y.jpeg)
Рисунок 60
DLL реализует проверку на антианализ. Она вызывает isProcessorFeaturePresent API, чтобы определить, доступен ли _fastfail(). Если эта функция не поддерживается, текущий процесс прекращается вызовом функций GetCurrentProcess и TerminateProcess (0x17 = PF_FASTFAIL_AVAILABLE):
![](https://habrastorage.org/webt/zo/u9/ts/zou9tsppepi3g1_vvgkrak0k0ec.jpeg)
Рисунок 61
Зловредный код переходит к шелл-коду, а затем освобождает выделенную ранее область памяти:
![](https://habrastorage.org/webt/ux/_m/yp/ux_mypawcaftqouxdugv29jyaji.jpeg)
Рисунок 62
Как говорилось в начале нашего анализа, злоумышленник добавил рассмотренную выше функцию экспорта, а все остальные вполне безобидны.
Мы изучили подлинное расширение оболочки Notepad++ (SHA256: f3e2e6f9e7aa065e89040a0c16d1f948489b3751e5eb5efac8106d5f7d65d98d 64-bit) и сравнили функции экспорта двух файлов. Как видно ниже, функции очень схожи:
![](https://habrastorage.org/webt/3k/rh/jz/3krhjzsu21e9pm5nd3menzbisas.jpeg)
Рисунок 63
![](https://habrastorage.org/webt/wt/ko/1r/wtko1rv2urpb4p06nslsw4a3phy.jpeg)
Рисунок 64
Справочные материалы
Признаки компрометации
Домены C2:
- mante.li
- bmanal.com
- shopandtravelusa.com
- industryinfostructure.com
SHA256: 803dda6c8dc426f1005acdf765d9ef897dd502cd8a80632eef4738d1d7947269
URL:
- https[:]//mante.li/images/draw.php
- https[:]//bmanal.com/images/draw.php
- https[:]//shopandtravelusa.com/vendor/monolog/monolog/src/Monolog/monolog.php
- https[:]//industryinfostructure.com/templates/worldgroup/view.php
![](https://habrastorage.org/webt/xb/o4/gm/xbo4gmrlicdllfwrmtuypqrlcgg.jpeg)