• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Обзор Powershell бота Monad

Haunt

PWSH
Эксперт
Регистрация
07.11.2019
Сообщения
948
Решения
1
Реакции
1 266
Приветствую всех, ребятки. Попался мне из коммерса(https://xss.pro/threads/84127/) на обзор некий софт с кодовым названием Monad. Решил сделать на него обзор, по этому рассмотрим что это такой за зверь и почему я обратил на него внимание. Первопричина моего интереса это язык реализации клиентской части - powershell. Для нынешнего паблик рынка все же это в новинку, так как мы привыкли видеть C#/C/C++. В связи с тем, что это скрипт вектор, большинство моментов за ненадобностью, будут упущены, которые мы привыкли видеть в обзорах от Quake3, а именно, такие вещи как разбор того, шифруются ли строки, как резольвятся winapi ,декомпиляция софта в IDA, просмотр импортов, etc. Тут специфика совершенно иная. Сценарий powershell, по своей сути, это просто текст, который подается на исполнение в интерпретатор, который уже предустановлен в системе и имеет цифровую подпись MS.

Пару слов о деплоинге.
Собственно, думаю стоит начать с общих моментов. И первым моментом я бы хотел выделить тот факт, что каждый элемент проекта работает в докере(а этих элементов, заранее оговорюсь, несколько, некоторые вещи вынесены за пределы основного сервера для возможности масштабирования и оптимизации нагрузок, если забегать вперед) как бы, ну и что, какая разница, если проект арендуется, хостится на серверах разработчика и клиент не сталкивается с этим непосредственно, спросите вы? Это показывает серьезный подход к деплоингу, отвечу я. Достаточно громкий звоночек на самом старте, как по мне. Почему? Можем вспомнить обзоры Ареса, проблему когда у разработчика все работает, а у Ареса - не заводится ни в какую. Или же если мы сталкиваемся с каким-то софтом, где разработчик просит 100$ за деплой на сервер, вроде того же Азорульта..просто потому что обычный смертный без 100 грамм не разберется в установке.. Но да ладно... как я понимаю для клиентов этого коммерс предложения это будет несущественный бонус, поскольку разработчики хостят это дело на своих серверах, по этому, кроме оперативности накатывания сего - для конечного потребителя тут отметить нечего, однако, должен заметить, что обзор будет включать не только описание неких бенефитов для конечного потребителя, но еще и обзор с точки зрения разработки, а также мои комментарии, касательно некоторых решений.

На чем сделан проект?
Фронт - Vue и асинхронный бек - на Python. БД - NoSQL. Понятно, что маршрутизация запросов, компоненты - не пустой звук, оказался рад, что это понимают и разработчики этого софта. Что касаемо части кода, которая доставляется на тачки жертв, тут по большей мере был, как я понимаю, перенят опыт Powershell Empire, то есть код реализован для версии пш и дотнета, который соответствует версии установленной по дефолту на вин 7. То есть некоторые вещи, которые входят в более поздние версии дотнета - пришлось реализовывать самим. А некоторые - не использовать вовсе, вроде ООП, который, как раз таки, и появился в более поздних версиях пш. Этим и обусловлена заявленная поддержка и работа от вин7. Тому примером может служить реализация JSON де/сериалайзера, вместо использования встроенного. По внутрянке пш скриптов, что хочу заметить, местами используется CodeDomCompiler(Add-Type) для использования WinAPI путем декларации импортов в C# классе, либо же в некоторых модулях - прекомпилированные сборки либ, как мне объяснили - либо с целью оптимизации узких по скорости мест, либо с точки зрения использования готового функционала вроде Websocket(например в модуле, который предоставляет шелл, идет загрузка либы для работы с WS из блоба сразу в память)

Мое мнение по стеку: В принципе, это вполне нормальный подход, если обращать внимание на другие фреймворки постэксплуатации, которые можно увидеть в опенсорсе. Так делают и это нормальная практика для скрипт вектора. Что касаемо стека разработки - он вполне приличный. Не вызывает предвзятости и подозрительности к качеству, как фраза «Бек реализован на чистом PHP, на фронте максимум Jquery». (Привет админкам из 2000-х)

На чем основан фундамент бота?
Отвечу, но сначала, предлагаю кое-что посмотреть. Именно так выглядит эта игрушка дъявола, ежжи:

1.jpeg


Поглазели? Ну а теперь хочу вам рассказать про стейджинг и стартеры и что есть билд. Ведь из этого состоит фундамент и я считаю, что это очень важно в проектах подобного класса. Изначально, предлагается пользователю создать «Кампанию», тыкая на Campaigns -> Edit. Системой формируется пара: человекочитаемое название, которое берется из юзер инпута- и некий ID, который генерируется автоматически и ассоциируется с тем названием, которое вы ввели. Далее в билдере(а он, кстати, прямо в админке) вы можете задать, с какой кампанией ассоциировать билд. Под капотом же, происходит следующая магия. В билд вшивается ID, который ассоциируется с тем самым именем кампании, которое придумал юзер. Этот ID выступает частью урлы ip:port/ID, так называемый entry point гейта. Делая первичный отстук на этот entry point - выгружается основное тело бота(агент) которое выполняет задачи: - сбор начальных данных о PC - поллинг - менеджер потоков с тасками (в пш это ранспейсы) Поллинг организован таким образом, что на каждый следующий отстук, бекенд генерирует новую одноразовую ссылку. Далее, агент на следующую итерацию поллинга обращается уже по этой одноразовой ссылке. И процесс повторяется:

Код:
ip:port/ID (расшифрованный ответ содержит uniq_link1) ->
ip:port/uniq_link1 (расшифрованный ответ содержит uniq_link2) ->
ip:port/uniq_link2 (расшифрованный ответ содержит uniq_link_N) ->
ip:port/uniq_link_N


Соответственно, без дебага, не вмешиваясь в алгоритм работы, нельзя понять какой будет адрес гейта uniq_link_N, чтобы, например, считать с него ответ раньше, чем ссылка умрет и чем это сделает агент Monad. Благодаря такому подходу - гейт получается динамическим. И это связано вообще со всем, агент буквально не знает практически ничего о модуле, в теле агента модулей не присутствует. Агент их получает с сервера в момент выдачи задания оператором админки. Более того, ссылкой на модуль, откуда его подгружать с сервера - агент также не владеет. Когда сервер понимает, что в очереди есть задача, он помимо уже нам известного uniq_link_N - возвращает следующую информацию:

uniq_link_K - одноразовая ссылка для загрузки тела модуля,
uniq_link_A - одноразовая ссылка, куда модуль отправит результат своей работы.

А так же аргументы, непосредственно необходимые для работы модуля. Будь-то юзер настройки или еще чего. С этой информации можно сделать 4 вывода.

Первый вывод - лаунчер пш может получить агент только при живой ссылке ip:port/ID.

Второй вывод - эта ссылка жива, пока существует определенная «кампания» в админке. А кампании - сущность не только создаваемая, но и удаляемая!

Третий вывод, более практичный - если билд распространить, собрать урожай, а после удалить «кампанию», то entry point умрет и новых ботов подцепить билдом не выйдет, но уже добавленные ранее боты продолжат стучать. Получается некий механизм инвалидации билда. Приходит сразу же на ум следующий кейс: распространили софт по разным ресурсам, а после сбора необходимого урожая - нам желательно удалить отовсюду билд, чтобы он не попал в руки, кому не нужно. Но не все ресурсы позволяют удалить загруженное да и напряжно это. Все гениальное - просто. Инвалидируем билд, удаляя кампанию - превращаем разлетевшиеся по всей сети билды в фантики(поскольку лаунчеры попросту не смогут достучаться на ip:port/ID). Кейс номер 2: слитые билды на разные трекеры. Как вы понимаете, при мертвой кампании - реверсить кроме самого лаунчера там будет нечего. Если удалить кампанию, как же в таком случае на entry point смогут достучаться уже существующие боты, спросите вы. А я отвечу, что система проверяет условие: либо живая campaign ID, либо наличие ID зараженной машины в бд. То есть, если бота мы уже подцепили - системе Monad будет все равно, существует ли кампания - бот, если он уже есть в системе, сможет достучаться.


Помимо механизма инвалидации билда, разработчики убили еще одного зайца, под названием «размер файла». Поскольку билд не содержит в себе даже тело агента, а получает его по ссылке в рантайме, не говоря уже о модулях - имеем минимальный вес доставляемого файла. Но должен уточнить - размер билда плавающий, поскольку зависит от пресетов обфускатора, но с минимальными пресетами - ехе, dll - приблизительно выходит в 35кБ.
Прокладки Monadы.


Думаете со стейджингом это все? А вот и не угадали. Начну немного издалека. Вспомните времена стиллеров вроде Азорульта. Для того, чтобы ваши шареды не отлетали от абуз - было придумано использование прокладок. Грубо говоря, в то время арендовали еще один сервер, суть которого заключалась в проксировании(реверс прокси) запросов от бота к основному серверу. И если прокладка от абуз отлетит - то основной сервер оставался жив. То есть, для потенциального ресерчера или автоматики, который заразил свою машину билдом и анализирует траф - будет виден IP прокладки, IP основного сервера Monad - не видно - куда кидать абузы? Так вот в этом проекте разработчики воплотили это, плотно интегрируя этот механизм в систему. Дело в том , что настроить прокладку для обычного стиллера- не так сложно, там весь жизненный цикл умещается в 1+ запросов. Другое дело - система со стейджингом подобного уровня. Как я понял, ребята создали прокладки персонально под свою систему, впилили в отдельный докер образ. То есть арендовал впску, накатил туда прокладку командой docker-compose up —build. Зашел в админку монады, в settings->layers, ввел ip:port:token, прокладка подвязалась.

2.jpeg

Дальше создал кампанию, подвязал к кампании прокладку. И все, у тебя билды созданные с под этой кампании теперь роутятся на С2 через эту прокладку, а управляющий сервер избегает абузы. Пример. Берем 3 источника трафика, под каждый генерируем кампанию и вяжем разные прокладки. Если отлетает 1 источник от абуз, остальные остаются живы. Удобства…

Что есть билд или форматы билдов?

Для многих не секрет, особенно, если вы работали с фреймворками пост эксплуатации вроде Powershell Empire что pwsh скрипты являются сами по себе не исполняемыми файлами, то есть нужен дополнительный стартер, чтобы их запустить. Это может быть что угодно, exe, dll, hta, js, vbs, vba, lnk, etc… Разработчики предоставляют некие свои варианты стартера, но ничего не мешает запихнуть это дело в свои наработки. Например, в качестве полезной нагрузки в эксплоиты. На этом этапе можно уже изобразить схему запуска. Исполняемый контекст, обеспеченный одним из лаунчеров на выбор:


Код:
exe/DLL/js/vbs/vba/RCE exploit/etc -> 
powershell launcher Monad ->
Monad agent ->
Monad modules

В билдере Monad работает конвейер, собирающий из темплейтов пш лаунчер, затем, помещает этот лаунчер уже в нативный стартер (если смотреть на продажник, там указано, что билдер поддерживает создание ехе).

Мое мнение по вышеперечисленному: явно не каждый день встретишь подобное. Одним пунктом сразу 4 зайцев . Инвалидация, оптимизация размера билда, роутинг трафика с кампаний через прокладки и проработка защиты от составления сетевых сигнатур, уникализируя гейт систему, делая ссылки одноразовыми, постоянно сменяемыми, шифруя трафик… Слава богам, я не увидел тут статичного gate.php, ахаха. Подводный же камень, как и универсальность, скрывается в стартерах, поскольку каждый вариант стартера имеет свой скантайм/рантайм. Проще говоря, сабж может быть чист, а макрос для офиса, запускающий powershell лаучер Monad, допустим, вы сделали грязным. В таком случае, АВ может завалить макрос еще до старта лаунчера Monad. Важно понимать отличия, решил расписать этот пункт для тех, кто не работал с powershell вектором и не сталкивался с подобным, чтобы было понимание .

Система отслеживания хода выполнения тасок & debug.

В админке присутствует вкладка дебаггинга, в которой можем наблюдать сообщения 2 типов: I & E ( Info & Error). На основе этих сообщений можно понять, где в ходе выполнения скрипта, возникла ошибка, информационные же сообщения показывают на каком этапе сейчас задача. Удобно, что можно отфильтровать сообщения, либо по их типу, либо/и по названию скрипта, которое является родителем этих сообщений.

Выглядит это дело вот так:
3.jpeg


И когда заходишь посмотреть детали:

4.jpeg


Мое мнение по пункту: Пацаны вообще ребята, внатуре классно, четко. Без подобного функционала практически нереально в боевых условиях отлаживать проект.


Защита от внешних сканеров.

Знакома ли вам ситуация, когда ваша админка страницей логина торчит в интернет всем желающим, когда возможен пентестинг вебморды или брутфорс пароля? Но не это самое страшное. Самое страшное - веб сканеры. Что мешает создать сигнатуру html/css/js, просканировать все диапазоны ip адресов, в поисках этой сигнатуры и составить список серверов, где хостится админка? А дальше выложить это в списочки для исследователей и/или сразу кинуть абузу? И эту проблему решили разработчики Monad. И решили достаточно простым способом. На форуме когда-то обсуждался этот подход. На стороне бекенда ребята воткнули правило, что если User-Agent в HTTP заголовке не соответствует секретному значению - сервер прикидывается шлангом и отдаёт 404 вместо вебморды. Просто и эффективно. Таким образом, чтобы не получить пустую страницу - оператору, чтобы хотя бы увидеть форму для входа в Monad необходимо подменить у себя в браузере User-Agent любым из доступных способов на заданное разработчиками значение.


Система обфускации.
Во многом разработчики просили не афишировать конкретные методики в обзоре. Но я все же побуду плохим парнем и покажу кое-что. Обфускатор действительно работает с AST повершела, как заявленно в продажнике. Замена значений узлов дерева реализована посредством патчинга сорца, расчитывая смещения для каждой замены, а потом за один проход вносит изменения, примерно такой подход однажды показал нам DildoFagins в своей статье на конкурс по обфускации сорцов С.

Теперь пройдемся по общим моментам.

1)Обфускатор работает только с лаунчером/агентом/модулями powershell, он не распространяется на билды ехе/dll/etc. Ну оно и понятно, почему так.

2)Обфускатор работает на отдельном сервере. Аналогично в докере. Алгоритм взаимодействия с Monad следующий. У Monad имеется 2 папки, original, obfuscated - с original по API выкачивает с админки оригинальные скрипты и по интервалу обфусцирует, далее заливает обратно по API в obfuscated папку, перезаписывая старые обфусцированные скрипты. Инфицированным машинам Monad выдает модули из obfuscated папки. В этом подходе можно увидеть минусы такого характера, что всем присутствующим ботам выдается одна и та же версия скрипта в единый момент времени. То есть, если дать команду запустить модуль стиллера на 10 ботах - им всем полетит одна и та же обфусцироцанная версия . Если же дать 5 ботам запустить модуль стиллера и еще минуты через 3 после новой итерации обфускации дать остальным 5 ботам эту же задачу - они получат разное тело модуля после обфускации.
3) В обфускации можно наблюдать полиморфную обработку констант, то есть результаты не повторяются

4) в обфускации присутствует обход AMSI в качестве одного из слоев. Не тот, которым патчится память AMSI.dll, а тот, который через рефлексию меняет внутренние структуры ПШ.

5) явно видно, что обфускатор по техникам заточен под быстродействие, последовательность слоев статична(имеется ввиду автоматикой не вносится рандом в последовательность слоев, только руками) = задается из кода, апи интерфейсов для управления извне нет. То есть если вы захотите другой порядок слоев или например сделать пожирнее, отдавив педаль в пол, вам необходимо будет обращаться к разработчику ПО.

6) в случае ошибки, либо если обфускатор сильно ушел в глубину и выполняет обфускацию длительнее, чем отведенное ему время, которое вычислили эмпирически для конкретного набора обфусцирующих слоев - происходит тупо переход на новую итерацию обфускации, простыми словами перезапуск обфускации для конкретного пш сценария, на котором все стопорнулось.

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

Исходный скрипт, который подадим на вход обфускатору, выглядит так:

Код:
$some_ = 'Monad review for XSS'
Write-Host $some_

Тест одной из техник, морфящий строковые константы:
Генерация №1:
Код:
$some_ = 'eJUagGBMon MGzFicmVdjwiAreview for XREMLSlOPeJUa'.Trim('eJUa').Insert(36, 'YoHyxNkOzeavjSYb').Trim('lOP').Remove(11, 3).Remove(47, 2).Remove(29, 17).Trim('g').Remove(6, 10).Insert(5, 'ad').Trim('GB')
Write-Host $some_
Генерация №2:
Код:
$some_ = 'XRNJEpqzXtGbMeAor k'.Insert(18, 'XSSNG').Insert(11, 'mUa').Insert(2, 'CyDnuHMTfYFZl').Trim('XRC').Trim('Gk').Insert(28, 'onad review f').Trim('y').Remove(5, 22).Trim('N').Remove(0, 4)
Write-Host $some_
Генерация №3:
Код:
$some_ = 'TLcKjTgANMonadUSqzvtDAbmMkuYW relEbCPtsJqmyABIzLoFrgvhmnSiew for LcKjZc'.Remove(14, 15).Remove(17, 20).Trim('c').Insert(30, 'XSST').Trim('T').Trim('Z').Trim('LcKj').Trim('T').Trim('gAN').Remove(9, 4)
Write-Host $some_

Объясню, тем, кому интересно, как достигается такой эффект:
1) К исходной строке применяется в рандомном порядке один из методов: Insert, Remove, Trim, эти методы работают с рандомными аргументами, учитывая длину строки.
2) В самом обфускаторе также происходит эмуляция этого события и на следующем шаге, Remove, Trim,Insert уже работают с тем, что получилось в эмуляторе на предыдущем шаге.
3) Повторить N раз, тем самым достигая глубины, которая задается в виде параметра в этом пресете.
4) Применить все методы в обратном порядке к получившийся строке (то есть если мы делали Remove, то мы должны запомнить ту часть строки, которую удалили, чтобы в последствии, при восстановлении сделать Insert), таким образом восстанавливая строку 'Monad review for XSS'.
5) Какие плюсы? Без эмуляции невозможно получить значение переменной $some_. Как АВ эмулирует powershell - кто знает, тот знает :D

Покажу еще пресет, но который уже работает с треш кодом и флоу выполнения. Исходный код тот же, вот что на выходе:

Код:
$some_ = 'Monad review for XSS'
if((('JNlQwseLRI'.Remove(5,5).Remove(1,1).Trim('Q').ToUpper().ToUpperInvariant() -ge 'QdN'.Trim('j').Replace('OxCySsTwQ','xHiZo').ToUpper().Remove(1,0).Replace('pwBE','ZLFuxt').ToLowerInvariant()) -le $(@('CwzIF'.ToLowerInvariant().Replace('WBOiZEH','ZATtbIq').ToLowerInvariant().Remove(0,1).Replace('OS','G').ToLowerInvariant().Remove(1,0).ToUpperInvariant().ToLower(),626716000,2037764946,'ZqgoyExJLhFsTIYDPm'.Trim().Trim('l').ToUpperInvariant().Remove(13,0).Trim('x').ToLower(),1777106496)[3]))){
  if((((((($(@('LtHeUCAFQsudm'.ToLower().Trim().ToLowerInvariant().Replace('zY','suwIvohg'),'fSIBoLrWzvQKNpuE'.Insert(5,'scaMPou').ToUpperInvariant().Remove(6,5).ToUpper().Trim(),'HuRyrGbIZKJVCPW'.Replace('Vql','agJKU').Insert(13,'LjUoGhgSq').ToUpper().ToLowerInvariant().ToUpper().ToUpperInvariant().Insert(22,'ePa').ToUpper(),1623668340,700167852,413768315)[1]) -lt $(@('vBFnIMskQNAUKGbaqmCXeu'.ToUpper().Remove(2,18).ToUpperInvariant().Trim('K').ToLower().Trim().ToUpperInvariant().ToLower(),1440564809,266124595,869551463)[1])) -and $(@('AjsXOpUcoWYfMCuBxG'.Trim('n').ToLower().Trim().ToUpper().Replace('g','vl').ToUpper(),'VL'.Trim('q').ToLowerInvariant().Trim('O').Trim().ToLower().ToUpperInvariant().ToUpperInvariant().Trim('d').Trim('y').ToUpper(),788003384,2049332965,'zYxoXyWsAeMQUBtuicZDjpH'.Insert(15,'jmlcqsQG').Replace('jqSFehUd','rjY').ToLowerInvariant().Replace('yeDXIhUt','SbKyX').Replace('AwWaJd','sCwWT').ToLower().Insert(10,'GJ'))[0])) -lt $(@(878098808,'cEAtjFeo'.Trim().Trim().ToUpper().Replace('diUjmLsr','OTtsBMvy').Trim().Remove(1,5),'hpLEeXfi'.ToUpper().Insert(0,'OzrNU').Remove(11,2).Trim())[1])) -or 810612508) -ne $(@(1321887582,'ypJovjCHVUuTNdFz'.Insert(0,'XjwLlydiH').ToLowerInvariant().Insert(4,'OoPqLWG').Trim().ToLowerInvariant().ToLowerInvariant(),1054250701,292404851,'mpUhHNwvfBdTLI'.Insert(11,'B').ToLowerInvariant().Trim('G').ToUpper().Replace('WxGMXRPn','AhTPbjDoZ').Insert(10,'VWuJYo').Trim().ToLowerInvariant().Replace('Fk','jG'),1633747347)[1])) -ge 'aCxpvUScHnFtYlWD'.ToUpper().ToUpper().Trim('A').Trim())){
  $zYGTlCZxEgJyU = $(@(378472009,'CfjmIWOJZlDyiRGYEu'.Trim('K').ToUpper().ToUpper().Insert(12,'dxXmB').Replace('SOAYBH','WUv').Remove(2,1),'klebGpE'.Replace('rcIBxjp','EutqkD').Replace('Ekd','AUIF').ToLowerInvariant().ToUpperInvariant().Remove(4,3).ToUpper())[0])

$lZctMOSxpCdGBaP = 'sxqjQbl'.Replace('d','QymIkeWci').Trim('i').Remove(3,1).ToLowerInvariant().ToUpper()

$UuIaqgAHRJObjstP = 577747315

$HDiKuxZQjrmfX = 1536341182

$thiCFBNQoujXYpG = 2059196546

}
else {
  Write-Host $some_
}
}
else {
  $iOBXlWSrqw = 'IJZMKHnBLwOrdqkfaAD'.ToLowerInvariant().ToUpperInvariant().Remove(6,4).ToLower().ToUpperInvariant()

$nPzBQmThOs = 'kJpiXxu'.Remove(1,0).ToLowerInvariant().ToUpper().Replace('VeUGm','AVMQkcU').Remove(2,4)

$cBqkHCaKSplfd = 'EJvCDasIGoTZleQMuximX'.Replace('uLJZzC','tvUcisqba').Trim().ToLower().ToLower().Trim().Replace('QqBm','EfcjoQ').Replace('ZcvfRw','EWGYwF').ToLower().ToUpperInvariant()

$BtgDZdTLnYrHFO = $(@('YRmkwIbLzTelpfhsgVnHZxu'.ToUpper().Insert(19,'frhb').ToLower().ToUpper().ToLower().ToUpper(),'A'.Trim('M').ToLower().ToUpper().ToUpper(),1783905920,1432432797)[0])

$fyPFLbNVrEa = 'vNSFMJnzAujT'.Trim().Trim('A').ToLower().Trim('R').Remove(3,8).ToLowerInvariant()
 
}

Что тут происходит:

1) Обфускатор анализирует scriptblock, берет с него инструкции и оборачивает в конструкции if else. При чем он рандомно определяет, что будет истинно, if либо else. Сразу оговорюсь, что происходит с веткой, которая не выполнится - в нее будут помещены инструкции, которые сгенерируются кодогенератором. Из того, что я видел - он может генерировать декларацию функции, переменные со строками, числами. То есть примитивно подразбавить код.

2) Обфускатор генерирует условие, которое будет помещено в if, задача перед обфускатором стоит сгенерировать такое условие, чтобы оно удовлетворяло требованиям пункта 1. Другими словами, мы просим обфускатор нам сформировать условие, которое даст true либо false. Далее, обфускатор рандомно строит дерево этого выражения, используя -gt, -lt, -eq и тд. используя в качестве операндов сами видите что.

3) Возникает вопрос, каким тогда образом обфускатор выдает условие, нужное пункту 1? Ответ прост, он просто билдит условие, эмулирует и вычисляя его значение, смотрит, соответствует оно нужному нам или нет. Простыми словами - брутфорсит генерки до тех пор, пока они не дадут желаемое true/false.

4) Вложенность if else в глубину - аналогично разная, зависит от параметров пресета.

Думаю, на 2 пресетах и закончим, однако, должен заметить, пресетов в обфускаторе больше в разы. Из того, что еще особо понравилось - обфускатор парсит .NET классы и функции, парсит их аргументы и генерирует рандомные вызовы и рандомные аргументы для них, а дальше этим делом трешгенит в коде с заданной жирностью, оборачивая это в try catch, чтобы не дай бог не упало. Прикольно подошли к вопросу. Ну да ладно, давайте дальше.

Закрепление в системе.

Нужно сказать, что софт работает с под юзера, админ прав не требует на момент обзора. Закрепление так же с под юзера. Персистенс оформлен в виде модуля, по этому не идет в теле агента, в теории заменяем. Не сказать, что закрепление супер уникальное и 0day, но и не CurrentVersion/Run и не в тупую сунутый ванлайнер в шедуллер. Все хитрее. Скажу так - персистенс состоит из последовательности техник, каждая по отдельности описана на mitre attack. Именно комбинация техник дает желаемый эффект в виде лояльного отношения большинства АВ к этому закрепу. Происходит indirect execution пш скрипта, то есть интерпретатору его скармливают не с ванлайнера, все что могу сказать. Соответственно с PEB процесса анализирующие тулзы просто не вытянут аргументы, которые явно говорят, что стартанул некий сценарий. Рабочий принцип «разделяй и властвуй» наглядно.. Персистенс можно назвать достаточно уникальным, поскольку специфика рынка это С/С++/С# софт. Тут же - закрепление связано непосредственно с powershell вектором(т.е без powershell работать такой закреп не будет) и по этому это можно считать достаточно уникальным для этого рынка.

Стартап модули
Разработчики сообщают, что заложили при старте боте автоматический старт 2 модулей - персистенса(закрепления в системе, обсуждаемого ранее) и модуля стиллера. Таким образом в админке можем наблюдать такой эффект, что бот появился раньше, чем детальная сводка по нему. Разработчики сообщают, что вполне реально выключить на уровне кода автоматическое исполнение модуля стиллера и стартовать его только руками. Отчасти это имеет смысл при таргетной работе, так и в плане отвала софта из-за АВ, мол если работал и стучал - а после запуска бот ушел в офлайн - можно предполагать что самое время чистить от проактивки этот модуль.

Интерфейс админки и система фильтров.


Тут мы видим, что вместо 101 формы фильтров, была реализована минималистично всего 1 поисковая строка, которая призвана решить все вопросы по фильтрации.
1680333480980.png


Работает она по принципу

Ключ=значение&ключ=значение.

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

country=us&host=paypal&os=10 - получаем в выдаче всех USA ботов на вин 10, у которых есть линк палки в логах.

Добавляем online=1 (где 1 может быть любым значением, главное присутствие ключа по типу булевого true) - получаем к предыдущему фильтру еще и выборку только по тем ботам, которые в данный момент онлайн.

Что касается Dashboard вкладки, на нее аналогично распространяется действие этой поисковой строки, только в несколько ином ключе.
На Dashboard используется уже всем привычная карта заражений, а так же агрегации по ос, топ часто встречаемых линков и топ cookies.
Если мы в фильтре введем country=uk, получим топ линков и топ куков по этой стране. При этом на карте заражений останется только uk. Если мы введем host=paypal&online=1 и посмотрим на карту заражений - увидим агрегацию по странам, подсветит только те страны, в которых есть онлайн боты с палкой на борту.

Имеется индикатор загруженности CPU, RAM сервера где работает Monad. Присутствует возможность скачать офлайн репорт зараженной машины. Как по отдельности так и массово. В офлайн репорте имеется 2 представления txt и офлайн html репорт. Можно удалить выбранных ботов из системы, либо просто удалить, либо удалить с внесением в черный список(повторный запуск билда не добавит бот заново в систему после удаления, система запомнит идентификатор бота и не даст ему больше добавиться). При удалении агент получает команду удалиться и выпиливается из закрепа и завершает процесс(то есть чистка не только на сервере) Присутствует система тегов, благодаря которой можно группировать ботов по некому ключу, а дальше с поисковой строки - найти группу ботов: tag=ваш_тег Присутствует поле для ввода комментария по боту. Классика

Система выдачи тасок работает по такому принципу: Задачи можно классифицировать как массовые, либо одиночные. Отмечая ботов, вам система сообщит, какие таски вы можете запустить, проверяя ряд критериев, вида: онлайн ли бот, поддерживает ли система запуск конкретной задачи на >1 ботах. Если поддерживает - кнопка выдачи задания станет активна и когда вы ее прожмете, вас перекинет на соответствующий менеджер задачи, на котором вы уже сможете детализировано управлять параметрами.

Что умеет этот бот? Модули.


Модули так же реализованы в основном на powershell, иногда с примесью, но повторюсь, это вполне нормальная практика в мире powershell. Теперь более детально о модулях.

1) Модуль стиллера в системе Monad классифицируется как массовый модуль, не содержит в себе параметров, срабатывает автоматически при появлении бота, но можно в любой момент перезапустить и снять с машины актуальные данные. Касаемо реализации стиллера - декрипт фф выполнен на стороне сервера взаимодействием с линуксовой библиотекой nss3(профили у фф кроссплатформенны, сняв на винде, можно расшифровать на линуксе). По декрипту хромиум - все достаточно типично, естественно все переписано на powershell. Касаемо работы с sql - реализации SQL ридера не обнаружил, вместо этого происходит работа с белой dllкой, которую скрипт тянет с собой. В ходе общения я понял, что авторы вполне понимают что дроп даже белой dll - это потенциальный IOC. Осознание проблемы - уже 50% ее решения. Так что радует осознанность. Будем надеятся, что SQL ридер все же реализуют в ближайшее время. Что касаемо взаимодействия с файлами бд - оно происходит напрямую, что может потенциально спровоцировать проактивный детект на АВ, которые в принципе палят любое обращение к этим файлам практически всего, что не браузер.

В основном, я тестировал снятие chromium & ff логин:пассов, заявлена так же поддержка снятия других приколов, вроде Tunderbird, но сорян, обзор и так большой выходит и есть более важные моменты, о которых хотелось бы рассказать.

5.jpeg

(Это внутренний просмотр зараженного пк, после того как кликнул по боту в списке, который вы видели на самом первом скриншоте. Таблицей вывалены логин пассы)

А вот так выглядит вкладка Main с основной инфой по боту:
8.jpeg


2) модуль граббера. Граббер в системе Monad классифицируется как массовый модуль. Что можно отметить из особенностей: Граббер реализован в 2 стадии.
Первая стадия заключается в формировании критериев поиска файла по маске и пути, где искать.
Вторая стадия опирается на результаты первой стадии. Мы получаем список имен файлов и их размер, далее отмечаем файлы, которые хотим загрузить. Когда мы их отмечаем - происходит калькуляция свободного места на сервере и обьема файлов к загрузке. Условие, при котором кнопка выгрузки файлов будет активна - на сервере должно оставаться как минимум 100 Мб под другие нужды софта. Достаточно интересный подход к реализации граббера в персистенс софте, чтобы не засирать место на сервере ненужным хламом. После выгрузки файлов - они будут доступны в офлайн архиве, там же, где и отчет по боту.

6.jpeg


Дожидаемся пока модуль отработает и переходим на вкладку Grubber, видим список файлов к загрузке.

7.jpeg


3) Socks5 модуль. В системе Monad классифицируется как одиночный модуль. Выдаем таск, видим таблицу, в ней дается Socks5 адрес, вставляем в настройках фф этот адрес и видим, что мы получили на выходе IP адрес бота. Так же можем выдать команду отключить socks5 модуль на боте.
9.jpeg


Однако, если сунем в proxyfier - тут сокс не подхватывается. Вывод: лучше всего уточнять у разработчиков, какие сокс клиенты поддерживаются. В целом - вещь +- рабочая, сунул в Firefox - сокс завелся, серфинг пошел. Идем дальше.

4) модуль TV. Модуль TV является одиночным модулем. Перед запуском - позволяет выбрать, через какой синхронизированный 3rd party бекенд запустить модуль. Проще говоря, модуль TV обслуживает отдельный бекенд, снимает нагрузки с основного сервера Monad. Бекенды для TV можно добавить через глобальные настройки, введя ip port token от бекенда. После запуска - в таблице наблюдаем готовность для входа в комнату. То есть присутствует момент инспекции готовности к работе в реалтайме. С этих пор модуль TV и фронтенд комнаты будут работать через бекенд TV, а бекенд Monad выступает координатором и связующим звеном. После того, как вошли в комнату, попадаем на страницу настроек сессии TV. В ней можно настроить качество передаваемой картинки (кадры шлются обычными JPEG) по интервалу, который указывается вторым параметром, таким образом, имеется возможность дать пользователю выбрать между качеством/нагрузкой.

10.jpeg

11.jpeg


После установки настроек, нас перекидывает на вторую страницу комнаты, в которой идет наблюдение за десктопом инфицированной машины. Прямо в TV модуль интегрирован снизу терминал powershell (в простонародье этот функционал называется шеллом), который предоставляет возможность исполнения кастомных powershell сценариев на машине, под любые задачи. Все это выполняется в контексте байпаснутого AMSI (AMSI обходится попросту уровнем выше, еще на уровне работы обфусктора с модулем/агентами) Стилистически, терминал напоминает Cobalt Strike терминал для управления сессией.

12.jpeg


TV модуль не роутится через прокладки. Поскольку, разработчиками была заложена логика TV бекенда как stateless механизма, не хранящего чувствительных данных на долгосроке(только в момент работы модуля на инфицированной машине) , взаимозаменяемого/дополняемого расходника к основному серверу Monad. То есть если помрет - от абузы, ничего не теряем, берем новый, синхронизируем и вперед.

5) Hbr. Вот мы и добрались к вкуснятине. Новаторский модуль, призванный заменить частично HVNC технологию. Это модуль, заточенный под скрытое графическое управление установленным браузером на пк пользователя. В отличии от HVNC - работает не с окнами WIN, а напрямую с движком браузера посредством DevTools, запрашивая его напрямую отрисовать самого себя, после чего, укладывает кадры в видеострим, обработанный кодеками. Графическое управление осуществляется посредством Web интерфейса, прямо в фронтенде Monad.

13.jpeg


Давайте детальнее глянем, как это выглядит. Архитектурно имеем тот же механизм комнат и 3rd party бекендов, что и у TV модуля. Но помимо этого имеем дополнительные настройки для старта. Первым делом, нам предлагают выбрать с под какого профиля юзера начать hbr сессию. Видим параметр Persistent profile. Дело в том, что при выборе оригинального пользовательского профиля имеем 2 проблемы:
1) при каждом запуске с юзер профиля создается временная копия и с под нее происходит скрытый старт браузера. Тут проблема в том, что профиль по размерам может быть и 1+ Гб. Соответственно, ожидание готовности ко входу в комнату может быть продолжительным. Положительный момент: у вас всегда свежая копия профиля пользователя.
2) при завершении таски hbr - временная копия удаляется, соответственно весь ваш «прогресс» работы с под профиля браузера пользователя в виде собранных cookies - будет утерян.

Чтобы повлиять на эту ситуацию - разработчики решили создать Persistent режим, который призван решить эти 2 проблемы. При включенном Persistent - копия профиля не удаляется между запусками hbr тасок, таким образом, всегда можно продолжить работу «завтра», с теми же наработанными cookies, что насобирались «вчера», без нужды при повторном запуске ждать создания временной копии с актуального профиля пользователя. То есть у вас с момента запуска persistent режима - создается своя ветка профиля для работы. Если режим работы original - при каждом запуске работаем со свежеснятой копии профиля, выжидая время на создание временной копии, с полной потерей вашего «прогресса» после завершения hbr таски.


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


14.jpeg


Имеем кучу настроек:
1) FPS - это то количество кадров JPEGов, которое мы просим браузер нам отрисовать в секунду.
2) JPEG Quality - это то качество, тех самых JPEGов, которое нам отрисует браузер.
3) Bits per second - битрейт видео, эти самые ваши 1080р, 720р, 480р, 360р, если на простонародном. Это уже настройки видеопотока, которые получились из тех самых JPEGов.
4) Mime type - обработчику нужно указать, в каком контейнере это все будет и каким кодеком будет обработано. В дефолтном варианте это WebM/VP8. Но имеется возможность более серьезной настройки, за деталями - вам на Mozilla ресурсы.
5) Chunk size - порции видеопотока в миллисекундах, которые будут отправляться нам. В дефолт настройке каждые 100мс.
6) Video Resolution Ratio - насколько подрезать размеры видео по X,Y. Меньше точек кодировать - меньше размер видео - меньше пересылать - меньше нагрузка.
7) Viewport width & height - размеры экрана оператора Monad, «чтобы все подогнать». Подхватывается автоматически, но можно выставить свое.

Нажимаем Next и попадаем на следующую страницу комнаты, в которой видим интерфейс, повторяющий браузер. До оригинального функционала браузера далеко, однако многие базовые действия можно выполнить.
15.jpeg



ХЕ-ХЕ =)

16.jpeg


Отличительной особенностью в данном случае является то, что клиент hbr реализован в виде веб страницы, а не отдельного нативного клиента, как в классических клиентах HVNC, ничего дополнительного устанавливать не нужно.

Выводы про hbr модуль:
+ Хорошая замена HVNC, подойдет, если вы в своей работе опираетесь на браузеры. Авторы Monad на данный момент реализовали функционал только под chromium движки. Chrome, Edge +
+ веб-клиент
+ гибкая работа с профилями
+ Обработка кодеками видеоданных.
+ обслуживание hbr на отдельных серверах(возможность масштабирования). Не нагружает Monad сервера.
+ рисует без черных квадратов и прочих артефактов. (Мои тесты проводились на Chrome клиенте, на боте тестировались Chrome, Edge. Другие chromium-based не тестил)
+ даже через TOR взаимодействовать реально по быстродействию. + возможность настроить «под себя» балансировать на качестве показываемой картинки/быстродействии.
- не подойдет, если необходимо иметь графическое управление над десктоп программами на боте.
- не подойдет(либо нуждается в доработке), если вам важны какие то особые браузерные UI возможности в вашей работе.


Олним словом, работать через TOR и не биться в конвульсиях, ожидая отклика - велкам ту реалити. (Все тесты осуществлялись через TOR, при серфинге серьезных болей в области 5 точки не почувствовал).
Вот видео взаимодействия с сессией через TOR.


Решил проверить так же базовую работоспособность на некоторых системах, итого:

Проверка базовой работоспособности:
admin/user
Win7 + +
Win8 + +
Win10 + +
Win11 + +

Решил проверить билды на ав. По такому случаю - не на динчеке и прочих сервисах, а в живую на виртах со следующими установленными АВ: Windows Defender, Eset Nod32, Avast, Nortonю Суть теста - проверить ps1 лаунчер Monad. Почему не exe/DLL? Как я уже сказал ранее, любая доставка в виде ехе или офисного макроса - имеет свой рантайм/скантайм. Мы же преследуем цель проверить рантайм лаунчера, агента и модулей Monad. Результаты:

Деф - чистый рантайм всех модулей
Видео:


Нод - чистый рантайм всех модулей
Видео:

Аваст - чистый рантайм всех модулей
Видео:


Нортон. - алерт с продолжением выполнения.
Видео:

Как мы видим, словили алерт на нортоне, при запуске TV модуля, но процесс остался жив, после ребута бот восстановился.

Итого, вполне неплохой бот. Мне понравился. А что думаете вы? Пишите в комменты. Надеюсь вам зашло, это был мой первый обзор.

P.S АВТОР ОБЗОРА НЕ НЕСЕТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБОЙ ВОЗМОЖНЫЙ ПРИЧЕНЕННЫЙ УЩЕРБ ПРЯМО ИЛИ КОСВЕННО СВЯЗАННЫЙ С ЭТИМ ОБЗОРОМ. АВТОР ОБЗОРА НИ К ЧЕМУ НЕ ПРИЗЫВАЕТ, используйте полученные знания на свой страх и риск. А также не забывайте про гарант! Всем спасибо за внимание!
 
если взаимодействие с скрытой сессией браузерам происходит через Devtools protocol получается можно подключить скрипты js puppeteer и сделать аналог автозалива?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Haunt спасибо большое за обзор.
Бот этот - уникально пердложение ничего такого раньше публично не продавали.
Авторам успехов! Жаль что не дают серверную часть себе деплоить(покрайней мере я так понял) -
обязательно взял бы если бы панель и с2 хостилось на моей инфре, а так своих ботов не кому не доверю.

Anyway - работа проделана - оч хорошая. То что все по контейнерам пакованно, уже сильно удивило - обычно от авторов малвари такого - не дождешься
Однако, если сунем в proxyfier - тут сокс не подхватывается.
тут скорее всего проблема в проксифаеере, наверняка через proxychains все летает. (проксифаер то еще говнище)
Что касается скрытого браузера - его одного далеко не достаточно - если планируется использовать софт как банк бота - там нужен vnc\rdp потому что крадут щас - куда чаще с Sage \ SAP Business \
Microsoft Dynamics 365 Business Central и прочих приложений используемых для аккаунтинга. Monad вашим клиентам HRDP 100% будет интересно и интереснее чем - VNC -> имхо,
VNC ущербный протокол, который куда более тормозной по сравнению с RDP.
 
Последнее редактирование:
Приветствую всех, ребятки. Попался мне из коммерса(https://xss.pro/threads/84127/) на обзор некий софт с кодовым названием Monad. Решил сделать на него обзор, по этому рассмотрим что это такой за зверь и почему я обратил на него внимание. Первопричина моего интереса это язык реализации клиентской части - powershell. Для нынешнего паблик рынка все же это в новинку, так как мы привыкли видеть C#/C/C++. В связи с тем, что это скрипт вектор, большинство моментов за ненадобностью, будут упущены, которые мы привыкли видеть в обзорах от Quake3, а именно, такие вещи как разбор того, шифруются ли строки, как резольвятся winapi ,декомпиляция софта в IDA, просмотр импортов, etc. Тут специфика совершенно иная. Сценарий powershell, по своей сути, это просто текст, который подается на исполнение в интерпретатор, который уже предустановлен в системе и имеет цифровую подпись MS.

Пару слов о деплоинге.
Собственно, думаю стоит начать с общих моментов. И первым моментом я бы хотел выделить тот факт, что каждый элемент проекта работает в докере(а этих элементов, заранее оговорюсь, несколько, некоторые вещи вынесены за пределы основного сервера для возможности масштабирования и оптимизации нагрузок, если забегать вперед) как бы, ну и что, какая разница, если проект арендуется, хостится на серверах разработчика и клиент не сталкивается с этим непосредственно, спросите вы? Это показывает серьезный подход к деплоингу, отвечу я. Достаточно громкий звоночек на самом старте, как по мне. Почему? Можем вспомнить обзоры Ареса, проблему когда у разработчика все работает, а у Ареса - не заводится ни в какую. Или же если мы сталкиваемся с каким-то софтом, где разработчик просит 100$ за деплой на сервер, вроде того же Азорульта..просто потому что обычный смертный без 100 грамм не разберется в установке.. Но да ладно... как я понимаю для клиентов этого коммерс предложения это будет несущественный бонус, поскольку разработчики хостят это дело на своих серверах, по этому, кроме оперативности накатывания сего - для конечного потребителя тут отметить нечего, однако, должен заметить, что обзор будет включать не только описание неких бенефитов для конечного потребителя, но еще и обзор с точки зрения разработки, а также мои комментарии, касательно некоторых решений.

На чем сделан проект?
Фронт - Vue и асинхронный бек - на Python. БД - NoSQL. Понятно, что маршрутизация запросов, компоненты - не пустой звук, оказался рад, что это понимают и разработчики этого софта. Что касаемо части кода, которая доставляется на тачки жертв, тут по большей мере был, как я понимаю, перенят опыт Powershell Empire, то есть код реализован для версии пш и дотнета, который соответствует версии установленной по дефолту на вин 7. То есть некоторые вещи, которые входят в более поздние версии дотнета - пришлось реализовывать самим. А некоторые - не использовать вовсе, вроде ООП, который, как раз таки, и появился в более поздних версиях пш. Этим и обусловлена заявленная поддержка и работа от вин7. Тому примером может служить реализация JSON де/сериалайзера, вместо использования встроенного. По внутрянке пш скриптов, что хочу заметить, местами используется CodeDomCompiler(Add-Type) для использования WinAPI путем декларации импортов в C# классе, либо же в некоторых модулях - прекомпилированные сборки либ, как мне объяснили - либо с целью оптимизации узких по скорости мест, либо с точки зрения использования готового функционала вроде Websocket(например в модуле, который предоставляет шелл, идет загрузка либы для работы с WS из блоба сразу в память)

Мое мнение по стеку: В принципе, это вполне нормальный подход, если обращать внимание на другие фреймворки постэксплуатации, которые можно увидеть в опенсорсе. Так делают и это нормальная практика для скрипт вектора. Что касаемо стека разработки - он вполне приличный. Не вызывает предвзятости и подозрительности к качеству, как фраза «Бек реализован на чистом PHP, на фронте максимум Jquery». (Привет админкам из 2000-х)

На чем основан фундамент бота?
Отвечу, но сначала, предлагаю кое-что посмотреть. Именно так выглядит эта игрушка дъявола, ежжи:

Посмотреть вложение 53973

Поглазели? Ну а теперь хочу вам рассказать про стейджинг и стартеры и что есть билд. Ведь из этого состоит фундамент и я считаю, что это очень важно в проектах подобного класса. Изначально, предлагается пользователю создать «Кампанию», тыкая на Campaigns -> Edit. Системой формируется пара: человекочитаемое название, которое берется из юзер инпута- и некий ID, который генерируется автоматически и ассоциируется с тем названием, которое вы ввели. Далее в билдере(а он, кстати, прямо в админке) вы можете задать, с какой кампанией ассоциировать билд. Под капотом же, происходит следующая магия. В билд вшивается ID, который ассоциируется с тем самым именем кампании, которое придумал юзер. Этот ID выступает частью урлы ip:port/ID, так называемый entry point гейта. Делая первичный отстук на этот entry point - выгружается основное тело бота(агент) которое выполняет задачи: - сбор начальных данных о PC - поллинг - менеджер потоков с тасками (в пш это ранспейсы) Поллинг организован таким образом, что на каждый следующий отстук, бекенд генерирует новую одноразовую ссылку. Далее, агент на следующую итерацию поллинга обращается уже по этой одноразовой ссылке. И процесс повторяется:

Код:
ip:port/ID (расшифрованный ответ содержит uniq_link1) ->
ip:port/uniq_link1 (расшифрованный ответ содержит uniq_link2) ->
ip:port/uniq_link2 (расшифрованный ответ содержит uniq_link_N) ->
ip:port/uniq_link_N


Соответственно, без дебага, не вмешиваясь в алгоритм работы, нельзя понять какой будет адрес гейта uniq_link_N, чтобы, например, считать с него ответ раньше, чем ссылка умрет и чем это сделает агент Monad. Благодаря такому подходу - гейт получается динамическим. И это связано вообще со всем, агент буквально не знает практически ничего о модуле, в теле агента модулей не присутствует. Агент их получает с сервера в момент выдачи задания оператором админки. Более того, ссылкой на модуль, откуда его подгружать с сервера - агент также не владеет. Когда сервер понимает, что в очереди есть задача, он помимо уже нам известного uniq_link_N - возвращает следующую информацию:

uniq_link_K - одноразовая ссылка для загрузки тела модуля,
uniq_link_A - одноразовая ссылка, куда модуль отправит результат своей работы.

А так же аргументы, непосредственно необходимые для работы модуля. Будь-то юзер настройки или еще чего. С этой информации можно сделать 4 вывода.

Первый вывод - лаунчер пш может получить агент только при живой ссылке ip:port/ID.

Второй вывод - эта ссылка жива, пока существует определенная «кампания» в админке. А кампании - сущность не только создаваемая, но и удаляемая!

Третий вывод, более практичный - если билд распространить, собрать урожай, а после удалить «кампанию», то entry point умрет и новых ботов подцепить билдом не выйдет, но уже добавленные ранее боты продолжат стучать. Получается некий механизм инвалидации билда. Приходит сразу же на ум следующий кейс: распространили софт по разным ресурсам, а после сбора необходимого урожая - нам желательно удалить отовсюду билд, чтобы он не попал в руки, кому не нужно. Но не все ресурсы позволяют удалить загруженное да и напряжно это. Все гениальное - просто. Инвалидируем билд, удаляя кампанию - превращаем разлетевшиеся по всей сети билды в фантики(поскольку лаунчеры попросту не смогут достучаться на ip:port/ID). Кейс номер 2: слитые билды на разные трекеры. Как вы понимаете, при мертвой кампании - реверсить кроме самого лаунчера там будет нечего. Если удалить кампанию, как же в таком случае на entry point смогут достучаться уже существующие боты, спросите вы. А я отвечу, что система проверяет условие: либо живая campaign ID, либо наличие ID зараженной машины в бд. То есть, если бота мы уже подцепили - системе Monad будет все равно, существует ли кампания - бот, если он уже есть в системе, сможет достучаться.


Помимо механизма инвалидации билда, разработчики убили еще одного зайца, под названием «размер файла». Поскольку билд не содержит в себе даже тело агента, а получает его по ссылке в рантайме, не говоря уже о модулях - имеем минимальный вес доставляемого файла. Но должен уточнить - размер билда плавающий, поскольку зависит от пресетов обфускатора, но с минимальными пресетами - ехе, dll - приблизительно выходит в 35кБ.
Прокладки Monadы.


Думаете со стейджингом это все? А вот и не угадали. Начну немного издалека. Вспомните времена стиллеров вроде Азорульта. Для того, чтобы ваши шареды не отлетали от абуз - было придумано использование прокладок. Грубо говоря, в то время арендовали еще один сервер, суть которого заключалась в проксировании(реверс прокси) запросов от бота к основному серверу. И если прокладка от абуз отлетит - то основной сервер оставался жив. То есть, для потенциального ресерчера или автоматики, который заразил свою машину билдом и анализирует траф - будет виден IP прокладки, IP основного сервера Monad - не видно - куда кидать абузы? Так вот в этом проекте разработчики воплотили это, плотно интегрируя этот механизм в систему. Дело в том , что настроить прокладку для обычного стиллера- не так сложно, там весь жизненный цикл умещается в 1+ запросов. Другое дело - система со стейджингом подобного уровня. Как я понял, ребята создали прокладки персонально под свою систему, впилили в отдельный докер образ. То есть арендовал впску, накатил туда прокладку командой docker-compose up —build. Зашел в админку монады, в settings->layers, ввел ip:port:token, прокладка подвязалась.

Посмотреть вложение 53974
Дальше создал кампанию, подвязал к кампании прокладку. И все, у тебя билды созданные с под этой кампании теперь роутятся на С2 через эту прокладку, а управляющий сервер избегает абузы. Пример. Берем 3 источника трафика, под каждый генерируем кампанию и вяжем разные прокладки. Если отлетает 1 источник от абуз, остальные остаются живы. Удобства…

Что есть билд или форматы билдов?

Для многих не секрет, особенно, если вы работали с фреймворками пост эксплуатации вроде Powershell Empire что pwsh скрипты являются сами по себе не исполняемыми файлами, то есть нужен дополнительный стартер, чтобы их запустить. Это может быть что угодно, exe, dll, hta, js, vbs, vba, lnk, etc… Разработчики предоставляют некие свои варианты стартера, но ничего не мешает запихнуть это дело в свои наработки. Например, в качестве полезной нагрузки в эксплоиты. На этом этапе можно уже изобразить схему запуска. Исполняемый контекст, обеспеченный одним из лаунчеров на выбор:


Код:
exe/DLL/js/vbs/vba/RCE exploit/etc ->
powershell launcher Monad ->
Monad agent ->
Monad modules

В билдере Monad работает конвейер, собирающий из темплейтов пш лаунчер, затем, помещает этот лаунчер уже в нативный стартер (если смотреть на продажник, там указано, что билдер поддерживает создание ехе).

Мое мнение по вышеперечисленному: явно не каждый день встретишь подобное. Одним пунктом сразу 4 зайцев . Инвалидация, оптимизация размера билда, роутинг трафика с кампаний через прокладки и проработка защиты от составления сетевых сигнатур, уникализируя гейт систему, делая ссылки одноразовыми, постоянно сменяемыми, шифруя трафик… Слава богам, я не увидел тут статичного gate.php, ахаха. Подводный же камень, как и универсальность, скрывается в стартерах, поскольку каждый вариант стартера имеет свой скантайм/рантайм. Проще говоря, сабж может быть чист, а макрос для офиса, запускающий powershell лаучер Monad, допустим, вы сделали грязным. В таком случае, АВ может завалить макрос еще до старта лаунчера Monad. Важно понимать отличия, решил расписать этот пункт для тех, кто не работал с powershell вектором и не сталкивался с подобным, чтобы было понимание .

Система отслеживания хода выполнения тасок & debug.
В админке присутствует вкладка дебаггинга, в которой можем наблюдать сообщения 2 типов: I & E ( Info & Error). На основе этих сообщений можно понять, где в ходе выполнения скрипта, возникла ошибка, информационные же сообщения показывают на каком этапе сейчас задача. Удобно, что можно отфильтровать сообщения, либо по их типу, либо/и по названию скрипта, которое является родителем этих сообщений.

Выглядит это дело вот так:
Посмотреть вложение 53975

И когда заходишь посмотреть детали:

Посмотреть вложение 53976

Мое мнение по пункту: Пацаны вообще ребята, внатуре классно, четко. Без подобного функционала практически нереально в боевых условиях отлаживать проект.


Защита от внешних сканеров.

Знакома ли вам ситуация, когда ваша админка страницей логина торчит в интернет всем желающим, когда возможен пентестинг вебморды или брутфорс пароля? Но не это самое страшное. Самое страшное - веб сканеры. Что мешает создать сигнатуру html/css/js, просканировать все диапазоны ip адресов, в поисках этой сигнатуры и составить список серверов, где хостится админка? А дальше выложить это в списочки для исследователей и/или сразу кинуть абузу? И эту проблему решили разработчики Monad. И решили достаточно простым способом. На форуме когда-то обсуждался этот подход. На стороне бекенда ребята воткнули правило, что если User-Agent в HTTP заголовке не соответствует секретному значению - сервер прикидывается шлангом и отдаёт 404 вместо вебморды. Просто и эффективно. Таким образом, чтобы не получить пустую страницу - оператору, чтобы хотя бы увидеть форму для входа в Monad необходимо подменить у себя в браузере User-Agent любым из доступных способов на заданное разработчиками значение.


Система обфускации.
Во многом разработчики просили не афишировать конкретные методики в обзоре. Но я все же побуду плохим парнем и покажу кое-что. Обфускатор действительно работает с AST повершела, как заявленно в продажнике. Замена значений узлов дерева реализована посредством патчинга сорца, расчитывая смещения для каждой замены, а потом за один проход вносит изменения, примерно такой подход однажды показал нам DildoFagins в своей статье на конкурс по обфускации сорцов С.

Теперь пройдемся по общим моментам.

1)Обфускатор работает только с лаунчером/агентом/модулями powershell, он не распространяется на билды ехе/dll/etc. Ну оно и понятно, почему так.

2)Обфускатор работает на отдельном сервере. Аналогично в докере. Алгоритм взаимодействия с Monad следующий. У Monad имеется 2 папки, original, obfuscated - с original по API выкачивает с админки оригинальные скрипты и по интервалу обфусцирует, далее заливает обратно по API в obfuscated папку, перезаписывая старые обфусцированные скрипты. Инфицированным машинам Monad выдает модули из obfuscated папки. В этом подходе можно увидеть минусы такого характера, что всем присутствующим ботам выдается одна и та же версия скрипта в единый момент времени. То есть, если дать команду запустить модуль стиллера на 10 ботах - им всем полетит одна и та же обфусцироцанная версия . Если же дать 5 ботам запустить модуль стиллера и еще минуты через 3 после новой итерации обфускации дать остальным 5 ботам эту же задачу - они получат разное тело модуля после обфускации.
3) В обфускации можно наблюдать полиморфную обработку констант, то есть результаты не повторяются

4) в обфускации присутствует обход AMSI в качестве одного из слоев. Не тот, которым патчится память AMSI.dll, а тот, который через рефлексию меняет внутренние структуры ПШ.

5) явно видно, что обфускатор по техникам заточен под быстродействие, последовательность слоев статична(имеется ввиду автоматикой не вносится рандом в последовательность слоев, только руками) = задается из кода, апи интерфейсов для управления извне нет. То есть если вы захотите другой порядок слоев или например сделать пожирнее, отдавив педаль в пол, вам необходимо будет обращаться к разработчику ПО.

6) в случае ошибки, либо если обфускатор сильно ушел в глубину и выполняет обфускацию длительнее, чем отведенное ему время, которое вычислили эмпирически для конкретного набора обфусцирующих слоев - происходит тупо переход на новую итерацию обфускации, простыми словами перезапуск обфускации для конкретного пш сценария, на котором все стопорнулось.

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

Исходный скрипт, который подадим на вход обфускатору, выглядит так:

Код:
$some_ = 'Monad review for XSS'
Write-Host $some_

Тест одной из техник, морфящий строковые константы:
Генерация №1:
Код:
$some_ = 'eJUagGBMon MGzFicmVdjwiAreview for XREMLSlOPeJUa'.Trim('eJUa').Insert(36, 'YoHyxNkOzeavjSYb').Trim('lOP').Remove(11, 3).Remove(47, 2).Remove(29, 17).Trim('g').Remove(6, 10).Insert(5, 'ad').Trim('GB')
Write-Host $some_
Генерация №2:
Код:
$some_ = 'XRNJEpqzXtGbMeAor k'.Insert(18, 'XSSNG').Insert(11, 'mUa').Insert(2, 'CyDnuHMTfYFZl').Trim('XRC').Trim('Gk').Insert(28, 'onad review f').Trim('y').Remove(5, 22).Trim('N').Remove(0, 4)
Write-Host $some_
Генерация №3:
Код:
$some_ = 'TLcKjTgANMonadUSqzvtDAbmMkuYW relEbCPtsJqmyABIzLoFrgvhmnSiew for LcKjZc'.Remove(14, 15).Remove(17, 20).Trim('c').Insert(30, 'XSST').Trim('T').Trim('Z').Trim('LcKj').Trim('T').Trim('gAN').Remove(9, 4)
Write-Host $some_

Объясню, тем, кому интересно, как достигается такой эффект:
1) К исходной строке применяется в рандомном порядке один из методов: Insert, Remove, Trim, эти методы работают с рандомными аргументами, учитывая длину строки.
2) В самом обфускаторе также происходит эмуляция этого события и на следующем шаге, Remove, Trim,Insert уже работают с тем, что получилось в эмуляторе на предыдущем шаге.
3) Повторить N раз, тем самым достигая глубины, которая задается в виде параметра в этом пресете.
4) Применить все методы в обратном порядке к получившийся строке (то есть если мы делали Remove, то мы должны запомнить ту часть строки, которую удалили, чтобы в последствии, при восстановлении сделать Insert), таким образом восстанавливая строку 'Monad review for XSS'.
5) Какие плюсы? Без эмуляции невозможно получить значение переменной $some_. Как АВ эмулирует powershell - кто знает, тот знает :D

Покажу еще пресет, но который уже работает с треш кодом и флоу выполнения. Исходный код тот же, вот что на выходе:

Код:
$some_ = 'Monad review for XSS'
if((('JNlQwseLRI'.Remove(5,5).Remove(1,1).Trim('Q').ToUpper().ToUpperInvariant() -ge 'QdN'.Trim('j').Replace('OxCySsTwQ','xHiZo').ToUpper().Remove(1,0).Replace('pwBE','ZLFuxt').ToLowerInvariant()) -le $(@('CwzIF'.ToLowerInvariant().Replace('WBOiZEH','ZATtbIq').ToLowerInvariant().Remove(0,1).Replace('OS','G').ToLowerInvariant().Remove(1,0).ToUpperInvariant().ToLower(),626716000,2037764946,'ZqgoyExJLhFsTIYDPm'.Trim().Trim('l').ToUpperInvariant().Remove(13,0).Trim('x').ToLower(),1777106496)[3]))){
  if((((((($(@('LtHeUCAFQsudm'.ToLower().Trim().ToLowerInvariant().Replace('zY','suwIvohg'),'fSIBoLrWzvQKNpuE'.Insert(5,'scaMPou').ToUpperInvariant().Remove(6,5).ToUpper().Trim(),'HuRyrGbIZKJVCPW'.Replace('Vql','agJKU').Insert(13,'LjUoGhgSq').ToUpper().ToLowerInvariant().ToUpper().ToUpperInvariant().Insert(22,'ePa').ToUpper(),1623668340,700167852,413768315)[1]) -lt $(@('vBFnIMskQNAUKGbaqmCXeu'.ToUpper().Remove(2,18).ToUpperInvariant().Trim('K').ToLower().Trim().ToUpperInvariant().ToLower(),1440564809,266124595,869551463)[1])) -and $(@('AjsXOpUcoWYfMCuBxG'.Trim('n').ToLower().Trim().ToUpper().Replace('g','vl').ToUpper(),'VL'.Trim('q').ToLowerInvariant().Trim('O').Trim().ToLower().ToUpperInvariant().ToUpperInvariant().Trim('d').Trim('y').ToUpper(),788003384,2049332965,'zYxoXyWsAeMQUBtuicZDjpH'.Insert(15,'jmlcqsQG').Replace('jqSFehUd','rjY').ToLowerInvariant().Replace('yeDXIhUt','SbKyX').Replace('AwWaJd','sCwWT').ToLower().Insert(10,'GJ'))[0])) -lt $(@(878098808,'cEAtjFeo'.Trim().Trim().ToUpper().Replace('diUjmLsr','OTtsBMvy').Trim().Remove(1,5),'hpLEeXfi'.ToUpper().Insert(0,'OzrNU').Remove(11,2).Trim())[1])) -or 810612508) -ne $(@(1321887582,'ypJovjCHVUuTNdFz'.Insert(0,'XjwLlydiH').ToLowerInvariant().Insert(4,'OoPqLWG').Trim().ToLowerInvariant().ToLowerInvariant(),1054250701,292404851,'mpUhHNwvfBdTLI'.Insert(11,'B').ToLowerInvariant().Trim('G').ToUpper().Replace('WxGMXRPn','AhTPbjDoZ').Insert(10,'VWuJYo').Trim().ToLowerInvariant().Replace('Fk','jG'),1633747347)[1])) -ge 'aCxpvUScHnFtYlWD'.ToUpper().ToUpper().Trim('A').Trim())){
  $zYGTlCZxEgJyU = $(@(378472009,'CfjmIWOJZlDyiRGYEu'.Trim('K').ToUpper().ToUpper().Insert(12,'dxXmB').Replace('SOAYBH','WUv').Remove(2,1),'klebGpE'.Replace('rcIBxjp','EutqkD').Replace('Ekd','AUIF').ToLowerInvariant().ToUpperInvariant().Remove(4,3).ToUpper())[0])

$lZctMOSxpCdGBaP = 'sxqjQbl'.Replace('d','QymIkeWci').Trim('i').Remove(3,1).ToLowerInvariant().ToUpper()

$UuIaqgAHRJObjstP = 577747315

$HDiKuxZQjrmfX = 1536341182

$thiCFBNQoujXYpG = 2059196546

}
else {
  Write-Host $some_
}
}
else {
  $iOBXlWSrqw = 'IJZMKHnBLwOrdqkfaAD'.ToLowerInvariant().ToUpperInvariant().Remove(6,4).ToLower().ToUpperInvariant()

$nPzBQmThOs = 'kJpiXxu'.Remove(1,0).ToLowerInvariant().ToUpper().Replace('VeUGm','AVMQkcU').Remove(2,4)

$cBqkHCaKSplfd = 'EJvCDasIGoTZleQMuximX'.Replace('uLJZzC','tvUcisqba').Trim().ToLower().ToLower().Trim().Replace('QqBm','EfcjoQ').Replace('ZcvfRw','EWGYwF').ToLower().ToUpperInvariant()

$BtgDZdTLnYrHFO = $(@('YRmkwIbLzTelpfhsgVnHZxu'.ToUpper().Insert(19,'frhb').ToLower().ToUpper().ToLower().ToUpper(),'A'.Trim('M').ToLower().ToUpper().ToUpper(),1783905920,1432432797)[0])

$fyPFLbNVrEa = 'vNSFMJnzAujT'.Trim().Trim('A').ToLower().Trim('R').Remove(3,8).ToLowerInvariant()
 
}

Что тут происходит:

1) Обфускатор анализирует scriptblock, берет с него инструкции и оборачивает в конструкции if else. При чем он рандомно определяет, что будет истинно, if либо else. Сразу оговорюсь, что происходит с веткой, которая не выполнится - в нее будут помещены инструкции, которые сгенерируются кодогенератором. Из того, что я видел - он может генерировать декларацию функции, переменные со строками, числами. То есть примитивно подразбавить код.

2) Обфускатор генерирует условие, которое будет помещено в if, задача перед обфускатором стоит сгенерировать такое условие, чтобы оно удовлетворяло требованиям пункта 1. Другими словами, мы просим обфускатор нам сформировать условие, которое даст true либо false. Далее, обфускатор рандомно строит дерево этого выражения, используя -gt, -lt, -eq и тд. используя в качестве операндов сами видите что.

3) Возникает вопрос, каким тогда образом обфускатор выдает условие, нужное пункту 1? Ответ прост, он просто билдит условие, эмулирует и вычисляя его значение, смотрит, соответствует оно нужному нам или нет. Простыми словами - брутфорсит генерки до тех пор, пока они не дадут желаемое true/false.

4) Вложенность if else в глубину - аналогично разная, зависит от параметров пресета.

Думаю, на 2 пресетах и закончим, однако, должен заметить, пресетов в обфускаторе больше в разы. Из того, что еще особо понравилось - обфускатор парсит .NET классы и функции, парсит их аргументы и генерирует рандомные вызовы и рандомные аргументы для них, а дальше этим делом трешгенит в коде с заданной жирностью, оборачивая это в try catch, чтобы не дай бог не упало. Прикольно подошли к вопросу. Ну да ладно, давайте дальше.

Закрепление в системе.

Нужно сказать, что софт работает с под юзера, админ прав не требует на момент обзора. Закрепление так же с под юзера. Персистенс оформлен в виде модуля, по этому не идет в теле агента, в теории заменяем. Не сказать, что закрепление супер уникальное и 0day, но и не CurrentVersion/Run и не в тупую сунутый ванлайнер в шедуллер. Все хитрее. Скажу так - персистенс состоит из последовательности техник, каждая по отдельности описана на mitre attack. Именно комбинация техник дает желаемый эффект в виде лояльного отношения большинства АВ к этому закрепу. Происходит indirect execution пш скрипта, то есть интерпретатору его скармливают не с ванлайнера, все что могу сказать. Соответственно с PEB процесса анализирующие тулзы просто не вытянут аргументы, которые явно говорят, что стартанул некий сценарий. Рабочий принцип «разделяй и властвуй» наглядно.. Персистенс можно назвать достаточно уникальным, поскольку специфика рынка это С/С++/С# софт. Тут же - закрепление связано непосредственно с powershell вектором(т.е без powershell работать такой закреп не будет) и по этому это можно считать достаточно уникальным для этого рынка.

Стартап модули
Разработчики сообщают, что заложили при старте боте автоматический старт 2 модулей - персистенса(закрепления в системе, обсуждаемого ранее) и модуля стиллера. Таким образом в админке можем наблюдать такой эффект, что бот появился раньше, чем детальная сводка по нему. Разработчики сообщают, что вполне реально выключить на уровне кода автоматическое исполнение модуля стиллера и стартовать его только руками. Отчасти это имеет смысл при таргетной работе, так и в плане отвала софта из-за АВ, мол если работал и стучал - а после запуска бот ушел в офлайн - можно предполагать что самое время чистить от проактивки этот модуль.

Интерфейс админки и система фильтров.

Тут мы видим, что вместо 101 формы фильтров, была реализована минималистично всего 1 поисковая строка, которая призвана решить все вопросы по фильтрации.
Посмотреть вложение 53977

Работает она по принципу

Ключ=значение&ключ=значение.

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

country=us&host=paypal&os=10 - получаем в выдаче всех USA ботов на вин 10, у которых есть линк палки в логах.

Добавляем online=1 (где 1 может быть любым значением, главное присутствие ключа по типу булевого true) - получаем к предыдущему фильтру еще и выборку только по тем ботам, которые в данный момент онлайн.

Что касается Dashboard вкладки, на нее аналогично распространяется действие этой поисковой строки, только в несколько ином ключе.
На Dashboard используется уже всем привычная карта заражений, а так же агрегации по ос, топ часто встречаемых линков и топ cookies.
Если мы в фильтре введем country=uk, получим топ линков и топ куков по этой стране. При этом на карте заражений останется только uk. Если мы введем host=paypal&online=1 и посмотрим на карту заражений - увидим агрегацию по странам, подсветит только те страны, в которых есть онлайн боты с палкой на борту.

Имеется индикатор загруженности CPU, RAM сервера где работает Monad. Присутствует возможность скачать офлайн репорт зараженной машины. Как по отдельности так и массово. В офлайн репорте имеется 2 представления txt и офлайн html репорт. Можно удалить выбранных ботов из системы, либо просто удалить, либо удалить с внесением в черный список(повторный запуск билда не добавит бот заново в систему после удаления, система запомнит идентификатор бота и не даст ему больше добавиться). При удалении агент получает команду удалиться и выпиливается из закрепа и завершает процесс(то есть чистка не только на сервере) Присутствует система тегов, благодаря которой можно группировать ботов по некому ключу, а дальше с поисковой строки - найти группу ботов: tag=ваш_тег Присутствует поле для ввода комментария по боту. Классика

Система выдачи тасок работает по такому принципу: Задачи можно классифицировать как массовые, либо одиночные. Отмечая ботов, вам система сообщит, какие таски вы можете запустить, проверяя ряд критериев, вида: онлайн ли бот, поддерживает ли система запуск конкретной задачи на >1 ботах. Если поддерживает - кнопка выдачи задания станет активна и когда вы ее прожмете, вас перекинет на соответствующий менеджер задачи, на котором вы уже сможете детализировано управлять параметрами.

Что умеет этот бот? Модули.

Модули так же реализованы в основном на powershell, иногда с примесью, но повторюсь, это вполне нормальная практика в мире powershell. Теперь более детально о модулях.

1) Модуль стиллера в системе Monad классифицируется как массовый модуль, не содержит в себе параметров, срабатывает автоматически при появлении бота, но можно в любой момент перезапустить и снять с машины актуальные данные. Касаемо реализации стиллера - декрипт фф выполнен на стороне сервера взаимодействием с линуксовой библиотекой nss3(профили у фф кроссплатформенны, сняв на винде, можно расшифровать на линуксе). По декрипту хромиум - все достаточно типично, естественно все переписано на powershell. Касаемо работы с sql - реализации SQL ридера не обнаружил, вместо этого происходит работа с белой dllкой, которую скрипт тянет с собой. В ходе общения я понял, что авторы вполне понимают что дроп даже белой dll - это потенциальный IOC. Осознание проблемы - уже 50% ее решения. Так что радует осознанность. Будем надеятся, что SQL ридер все же реализуют в ближайшее время. Что касаемо взаимодействия с файлами бд - оно происходит напрямую, что может потенциально спровоцировать проактивный детект на АВ, которые в принципе палят любое обращение к этим файлам практически всего, что не браузер.

В основном, я тестировал снятие chromium & ff логин:пассов, заявлена так же поддержка снятия других приколов, вроде Tunderbird, но сорян, обзор и так большой выходит и есть более важные моменты, о которых хотелось бы рассказать.

Посмотреть вложение 53978
(Это внутренний просмотр зараженного пк, после того как кликнул по боту в списке, который вы видели на самом первом скриншоте. Таблицей вывалены логин пассы)

А вот так выглядит вкладка Main с основной инфой по боту:
Посмотреть вложение 53982

2) модуль граббера. Граббер в системе Monad классифицируется как массовый модуль. Что можно отметить из особенностей: Граббер реализован в 2 стадии.
Первая стадия заключается в формировании критериев поиска файла по маске и пути, где искать.
Вторая стадия опирается на результаты первой стадии. Мы получаем список имен файлов и их размер, далее отмечаем файлы, которые хотим загрузить. Когда мы их отмечаем - происходит калькуляция свободного места на сервере и обьема файлов к загрузке. Условие, при котором кнопка выгрузки файлов будет активна - на сервере должно оставаться как минимум 100 Мб под другие нужды софта. Достаточно интересный подход к реализации граббера в персистенс софте, чтобы не засирать место на сервере ненужным хламом. После выгрузки файлов - они будут доступны в офлайн архиве, там же, где и отчет по боту.

Посмотреть вложение 53979

Дожидаемся пока модуль отработает и переходим на вкладку Grubber, видим список файлов к загрузке.

Посмотреть вложение 53980

3) Socks5 модуль. В системе Monad классифицируется как одиночный модуль. Выдаем таск, видим таблицу, в ней дается Socks5 адрес, вставляем в настройках фф этот адрес и видим, что мы получили на выходе IP адрес бота. Так же можем выдать команду отключить socks5 модуль на боте.
Посмотреть вложение 53981

Однако, если сунем в proxyfier - тут сокс не подхватывается. Вывод: лучше всего уточнять у разработчиков, какие сокс клиенты поддерживаются. В целом - вещь +- рабочая, сунул в Firefox - сокс завелся, серфинг пошел. Идем дальше.

4) модуль TV. Модуль TV является одиночным модулем. Перед запуском - позволяет выбрать, через какой синхронизированный 3rd party бекенд запустить модуль. Проще говоря, модуль TV обслуживает отдельный бекенд, снимает нагрузки с основного сервера Monad. Бекенды для TV можно добавить через глобальные настройки, введя ip port token от бекенда. После запуска - в таблице наблюдаем готовность для входа в комнату. То есть присутствует момент инспекции готовности к работе в реалтайме. С этих пор модуль TV и фронтенд комнаты будут работать через бекенд TV, а бекенд Monad выступает координатором и связующим звеном. После того, как вошли в комнату, попадаем на страницу настроек сессии TV. В ней можно настроить качество передаваемой картинки (кадры шлются обычными JPEG) по интервалу, который указывается вторым параметром, таким образом, имеется возможность дать пользователю выбрать между качеством/нагрузкой.

Посмотреть вложение 53987
Посмотреть вложение 53988

После установки настроек, нас перекидывает на вторую страницу комнаты, в которой идет наблюдение за десктопом инфицированной машины. Прямо в TV модуль интегрирован снизу терминал powershell (в простонародье этот функционал называется шеллом), который предоставляет возможность исполнения кастомных powershell сценариев на машине, под любые задачи. Все это выполняется в контексте байпаснутого AMSI (AMSI обходится попросту уровнем выше, еще на уровне работы обфусктора с модулем/агентами) Стилистически, терминал напоминает Cobalt Strike терминал для управления сессией.

Посмотреть вложение 53989

TV модуль не роутится через прокладки. Поскольку, разработчиками была заложена логика TV бекенда как stateless механизма, не хранящего чувствительных данных на долгосроке(только в момент работы модуля на инфицированной машине) , взаимозаменяемого/дополняемого расходника к основному серверу Monad. То есть если помрет - от абузы, ничего не теряем, берем новый, синхронизируем и вперед.

5) Hbr. Вот мы и добрались к вкуснятине. Новаторский модуль, призванный заменить частично HVNC технологию. Это модуль, заточенный под скрытое графическое управление установленным браузером на пк пользователя. В отличии от HVNC - работает не с окнами WIN, а напрямую с движком браузера посредством DevTools, запрашивая его напрямую отрисовать самого себя, после чего, укладывает кадры в видеострим, обработанный кодеками. Графическое управление осуществляется посредством Web интерфейса, прямо в фронтенде Monad.

Посмотреть вложение 53991

Давайте детальнее глянем, как это выглядит. Архитектурно имеем тот же механизм комнат и 3rd party бекендов, что и у TV модуля. Но помимо этого имеем дополнительные настройки для старта. Первым делом, нам предлагают выбрать с под какого профиля юзера начать hbr сессию. Видим параметр Persistent profile. Дело в том, что при выборе оригинального пользовательского профиля имеем 2 проблемы:
1) при каждом запуске с юзер профиля создается временная копия и с под нее происходит скрытый старт браузера. Тут проблема в том, что профиль по размерам может быть и 1+ Гб. Соответственно, ожидание готовности ко входу в комнату может быть продолжительным. Положительный момент: у вас всегда свежая копия профиля пользователя.
2) при завершении таски hbr - временная копия удаляется, соответственно весь ваш «прогресс» работы с под профиля браузера пользователя в виде собранных cookies - будет утерян.

Чтобы повлиять на эту ситуацию - разработчики решили создать Persistent режим, который призван решить эти 2 проблемы. При включенном Persistent - копия профиля не удаляется между запусками hbr тасок, таким образом, всегда можно продолжить работу «завтра», с теми же наработанными cookies, что насобирались «вчера», без нужды при повторном запуске ждать создания временной копии с актуального профиля пользователя. То есть у вас с момента запуска persistent режима - создается своя ветка профиля для работы. Если режим работы original - при каждом запуске работаем со свежеснятой копии профиля, выжидая время на создание временной копии, с полной потерей вашего «прогресса» после завершения hbr таски.


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


Посмотреть вложение 53992

Имеем кучу настроек:
1) FPS - это то количество кадров JPEGов, которое мы просим браузер нам отрисовать в секунду.
2) JPEG Quality - это то качество, тех самых JPEGов, которое нам отрисует браузер.
3) Bits per second - битрейт видео, эти самые ваши 1080р, 720р, 480р, 360р, если на простонародном. Это уже настройки видеопотока, которые получились из тех самых JPEGов.
4) Mime type - обработчику нужно указать, в каком контейнере это все будет и каким кодеком будет обработано. В дефолтном варианте это WebM/VP8. Но имеется возможность более серьезной настройки, за деталями - вам на Mozilla ресурсы.
5) Chunk size - порции видеопотока в миллисекундах, которые будут отправляться нам. В дефолт настройке каждые 100мс.
6) Video Resolution Ratio - насколько подрезать размеры видео по X,Y. Меньше точек кодировать - меньше размер видео - меньше пересылать - меньше нагрузка.
7) Viewport width & height - размеры экрана оператора Monad, «чтобы все подогнать». Подхватывается автоматически, но можно выставить свое.

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


ХЕ-ХЕ =)

Посмотреть вложение 53994

Отличительной особенностью в данном случае является то, что клиент hbr реализован в виде веб страницы, а не отдельного нативного клиента, как в классических клиентах HVNC, ничего дополнительного устанавливать не нужно.

Выводы про hbr модуль:
+ Хорошая замена HVNC, подойдет, если вы в своей работе опираетесь на браузеры. Авторы Monad на данный момент реализовали функционал только под chromium движки. Chrome, Edge +
+ веб-клиент
+ гибкая работа с профилями
+ Обработка кодеками видеоданных.
+ обслуживание hbr на отдельных серверах(возможность масштабирования). Не нагружает Monad сервера.
+ рисует без черных квадратов и прочих артефактов. (Мои тесты проводились на Chrome клиенте, на боте тестировались Chrome, Edge. Другие chromium-based не тестил)
+ даже через TOR взаимодействовать реально по быстродействию. + возможность настроить «под себя» балансировать на качестве показываемой картинки/быстродействии.
- не подойдет, если необходимо иметь графическое управление над десктоп программами на боте.
- не подойдет(либо нуждается в доработке), если вам важны какие то особые браузерные UI возможности в вашей работе.


Олним словом, работать через TOR и не биться в конвульсиях, ожидая отклика - велкам ту реалити. (Все тесты осуществлялись через TOR, при серфинге серьезных болей в области 5 точки не почувствовал).
Вот видео взаимодействия с сессией через TOR.


Решил проверить так же базовую работоспособность на некоторых системах, итого:

Проверка базовой работоспособности:
admin/user
Win7 + +
Win8 + +
Win10 + +
Win11 + +

Решил проверить билды на ав. По такому случаю - не на динчеке и прочих сервисах, а в живую на виртах со следующими установленными АВ: Windows Defender, Eset Nod32, Avast, Nortonю Суть теста - проверить ps1 лаунчер Monad. Почему не exe/DLL? Как я уже сказал ранее, любая доставка в виде ехе или офисного макроса - имеет свой рантайм/скантайм. Мы же преследуем цель проверить рантайм лаунчера, агента и модулей Monad. Результаты:

Деф - чистый рантайм всех модулей
Видео:


Нод - чистый рантайм всех модулей
Видео:

Аваст - чистый рантайм всех модулей
Видео:


Нортон. - алерт с продолжением выполнения.
Видео:

Как мы видим, словили алерт на нортоне, при запуске TV модуля, но процесс остался жив, после ребута бот восстановился.

Итого, вполне неплохой бот. Мне понравился. А что думаете вы? Пишите в комменты. Надеюсь вам зашло, это был мой первый обзор.

P.S АВТОР ОБЗОРА НЕ НЕСЕТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБОЙ ВОЗМОЖНЫЙ ПРИЧЕНЕННЫЙ УЩЕРБ ПРЯМО ИЛИ КОСВЕННО СВЯЗАННЫЙ С ЭТИМ ОБЗОРОМ. АВТОР ОБЗОРА НИ К ЧЕМУ НЕ ПРИЗЫВАЕТ, используйте полученные знания на свой страх и риск. А также не забывайте про гарант! Всем спасибо за внимание!
Благодарю за настолько подробный обзор. Рад, что проект смог вызвать такой интерес.

если взаимодействие с скрытой сессией браузерам происходит через Devtools protocol получается можно подключить скрипты js puppeteer и сделать аналог автозалива?
В теории да, можно. Думали в эту сторону. Немного поработаем, соберем фидбек от пользователей, если будет спрос именно на это, то можно будет прикрутить что-то подобное.

Haunt спасибо большое за обзор.
Бот этот - уникально пердложение ничего такого раньше публично не продавали.
Авторам успехов! Жаль что не дают серверную часть себе деплоить(покрайней мере я так понял) -
обязательно взял бы если бы панель и с2 хостилось на моей инфре, а так своих ботов не кому не доверю.

Anyway - работа проделана - оч хорошая. То что все по контейнерам пакованно, уже сильно удивило - обычно от авторов малвари такого - не дождешься

тут скорее всего проблема в проксифаеере, наверняка через proxychains все летает. (проксифаер то еще говнище)
Что касается скрытого браузера - его одного далеко не достаточно - если планируется использовать софт как банк бота - там нужен vnc\rdp потому что крадут щас - куда чаще с Sage \ SAP Business \
Microsoft Dynamics 365 Business Central и прочих приложений используемых для аккаунтинга. Monad вашим клиентам HRDP 100% будет интересно и интереснее чем - VNC -> имхо,
VNC ущербный протокол, который куда более тормозной по сравнению с RDP.
Да, серверную часть поднимаем только у себя. А то услуга аренды превратится в продажу сорцев, пусть и частичную)
По проксифаеру, если совсем коротко, то он шлет немного другой набор байтов, который пш пока распарсить не может, тк изначально кодили это все под фф и антики, ну и тестили, соответственно, на них же. Но это все фиксится.
По остальным пожеланиям - учтем)
 
если взаимодействие с скрытой сессией браузерам происходит через Devtools protocol получается можно подключить скрипты js puppeteer и сделать аналог автозалива?
Если это вопрос ко мне - отвечу. Да, вполне реально такое сделать, однако лучше всего без использования js puppeteer. Он под капотом общается с DevTools по определенному протоколу, который вполне можно нагуглить. После чего - реализовать действия, автоматизирующие какие-то нужные тебе процессы с под профиля chromium прямо на инфицированной машине.
 
Если это вопрос ко мне - отвечу. Да, вполне реально такое сделать, однако лучше всего без использования js puppeteer. Он под капотом общается с DevTools по определенному протоколу, который вполне можно нагуглить. После чего - реализовать действия, автоматизирующие какие-то нужные тебе процессы с под профиля chromium прямо на инфицированной машине.
Хороший обзор и эта тема тоже отличная. Есть пару загвоздок и подводных камней, думаю автор встретиться в разработке типа такого (веб инжектов и заливов). По ответу - нужно искать там, где меньше всего ищешь :)
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Haunt спасибо большое за обзор.
Бот этот - уникально пердложение ничего такого раньше публично не продавали.
Авторам успехов! Жаль что не дают серверную часть себе деплоить(покрайней мере я так понял) -
обязательно взял бы если бы панель и с2 хостилось на моей инфре, а так своих ботов не кому не доверю.

Anyway - работа проделана - оч хорошая. То что все по контейнерам пакованно, уже сильно удивило - обычно от авторов малвари такого - не дождешься

тут скорее всего проблема в проксифаеере, наверняка через proxychains все летает. (проксифаер то еще говнище)
Что касается скрытого браузера - его одного далеко не достаточно - если планируется использовать софт как банк бота - там нужен vnc\rdp потому что крадут щас - куда чаще с Sage \ SAP Business \
Microsoft Dynamics 365 Business Central и прочих приложений используемых для аккаунтинга. Monad вашим клиентам HRDP 100% будет интересно и интереснее чем - VNC -> имхо,
VNC ущербный протокол, который куда более тормозной по сравнению с RDP.
Основная проблема HRDP заключается в том, что это палевная технология и она сводится либо к дропу компонентов на диск или же патчингу svchost в памяти, во втором случае будут ограничения при работе с домашними версиями винды. А чем плох метод с выносом окна приложения за пределы экрана?
 
Поддерживает ли HBR chrome autofills?
image.png

Если работа с браузером идёт через dev tools protocol, то, вероятнее всего нет, но мб автор придумал какой-нибудь обход?
 
Поддерживает ли HBR chrome autofills?
На моих тестах виден этот момент, глянь видос hbr_ который в теле статьи на ~1:30 минуте. Вход в дропбокс, автофилл сработал, я ничего не заполнял.
 
На моих тестах виден этот момент, глянь видос hbr_ который в теле статьи на ~1:30 минуте. Вход в дропбокс, автофилл сработал, я ничего не заполнял.
Я именно про сам селект с сохранёнными паролями для текущего сайта.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх