
взлом cobaltstrike 4.5, удаление сигнатур checksum8, обход BeaconEye, исправление утечки stage по неверному пути, добавление двухфакторной аутентификации TOTP, исправление CVE-2022-39197 и др.
Взлом версии cobaltstrike4.5, удаление признака checksum8, обход BeaconEye, исправление утечки stage по неверному пути, добавление двухфакторной проверки TOTP, добавление шифрованного отображения имени пользователя, исправление бага наследования foreign в версии 4.5, изменение имени файла конфигурации клиента и т.д.
взлом cobalt strike 4.5
взлом cobaltstrike4.5
[TOC]
Данный инструмент и содержимое статьи предназначены только для исследований в области безопасности. Пользователь несёт всю юридическую и связанную с этим ответственность за использование данного инструмента и содержимого статьи! Автор не несёт никакой юридической ответственности! Если в процессе использования данного инструмента и содержимого статьи вы совершаете любые незаконные действия, вы самостоятельно несёте соответствующие последствия, и мы не несём никакой юридической или связанной ответственности. В противном случае, пожалуйста, не устанавливайте и не используйте данный инструмент. Ваше использование или любое иное явное или подразумеваемое выражение согласия с настоящим соглашением означает, что вы прочитали и согласны с его условиями. При использовании данного инструмента для исследований в области безопасности вы должны убедиться, что такие действия соответствуют законодательству и что у вас есть достаточные полномочия. Не используйте его против неавторизованных целей.
Да, я снова здесь, продолжаю оригинальный cobaltstrike4.4_cdf: https://github.com/lovechoudoufu/about_cobaltstrike4.4_cdf На этот раз версия 4.5. Предыдущий 4.4 был удалён GitHub'ом; вероятно, скоро этот проект тоже будет удалён~.
Рекомендуется вступить в группу Telegram, в дальнейшем, после удаления проекта и других обновлений, их можно будет скачать из группы:

Перед использованием внимательно сверьте хэш jar-пакета соответствующей версии.
Процесс проверки лицензии (на примере 4.3): в версии 4.5 в конце есть небольшие изменения.
Официальные ключи дешифрования для каждой версии:
4.0 1be5be52c6255c33558e8a1cb667cb06
4.1 80e32a742060b884419ba0c171c9aa76
4.2 b20d487addd4713418f2d5a3ae02a7a0
4.3 3a4425490f389aeec312bdd758ad2b99
4.4 5e98194a01c6b48fa582a6a9fcbb92d6
cobaltstrike.auth — файл ключа аутентификации, зашифрован RSA; после расшифровки содержимое:
4.3
-54, -2, -64, -45, //文件头
0, 77, //后续长度
1, -55, -61, 127, //证书时间限制29999999(永久)
0, 0, 0, 1, //watermark(水印)
43, //版本
16, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
16, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
16, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
16, 58, 68, 37, 73, 15, 56, -102, -18, -61, 18, -67, -41, 88, -83, 43, -103
С каждым обновлением версии соответствующая длина увеличивается на 17, ключ увеличивается на 17 байт.
В aggressor/Aggressor.class проверка лицензии начинается с License.checkLicenseGUI(new Authorization());:

В License.checkLicenseGUI методы isValid, isPerpetual, isExpired, isAlmostExpired определяют, действительна ли лицензия и не истекла ли она:

В классе Authorization обрабатывается файл cobaltstrike.auth: читается содержимое файла и вызывается AuthCrypto().decrypt для его обработки:

В конструкторе AuthCrypto() вызывается load(). Функция load() выполняет проверку MD5 для resources/authkey.pub, а затем получает открытый ключ RSA:

В decrypt() вызывается _decrypt, который расшифровывает содержимое файла cobaltstrike.auth с помощью открытого ключа RSA и присваивает результат массиву var2, затем преобразует его через DataParser в var3. Метод readInt() получает первые четыре байта из var3 для проверки заголовка файла (-889274181 — версия 3.x; -889274157 — версия 4.x). Затем readShort() из var3 получает два байта как длину и присваивает её var5, далее var6 = var3.readBytes(var5) читает содержимое этой длины, присваивает var6 и возвращает его:

Массив arrayOfByte2, полученный в классе Authorization, представляет собой содержимое после удаления первых шести байт. Обработка arrayOfByte2 продолжается: сначала считываются четыре числа в i, затем четыре числа в watermark, затем одно число в b1. Проверяется, что b1 меньше 43, и равно ли i значению 29999999. В common/ListenerConfig при watermark == 0 добавляется водяной знак антивирусного обнаружения:


После удаления первых 6 байт и затем 9 байт i, watermark, b1, оставшаяся часть — это ключи от 4.0 до 4.3, со структурой: 16, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20:
byte b2 = dataParser.readByte(); //获取1位,即16
byte[] arrayOfByte3 = dataParser.readBytes(b2); //获取16位,为4.0的key
byte b3 = dataParser.readByte(); //获取1位,即16
byte[] arrayOfByte4 = dataParser.readBytes(b3); //获取16位,为4.1的key
byte b4 = dataParser.readByte(); //获取1位,即16
byte[] arrayOfByte5 = dataParser.readBytes(b4); //获取16位,为4.2的key
byte b5 = dataParser.readByte(); //获取1位,即16
byte[] arrayOfByte6 = dataParser.readBytes(b5); //获取16位,为4.3的key赋值给arrayOfByte6
В классе Authorization вызывается метод SleevedResource.Setup для обработки arrayOfByte6. В SleevedResource ключ задаётся как ключ расшифровки AES и HmacSHA256, а в _readResource вызывается this.data.decrypt(arrayOfByte1); для расшифровки. Расшифровывается содержимое DLL-файлов из /sleeve/:

В SleeveSecurity задаётся ключ расшифровки AES и HmacSHA256: на основе переданного значения вычисляется дайджест длиной 256, затем байты 0–16 используются как ключ AES, а байты 16–32 — как ключ HmacSHA256:

Если не получить соответствующий ключ, невозможно расшифровать DLL из папки sleeve; при подключении к серверу появится ошибка [Sleeve] Bad HMAC:

Часть с расшифровкой HMAC можно посмотреть здесь: Взлом Cobaltstrike 4 — я сам себе выдаю лицензию
Таким образом, ключ к взлому — это наличие ключа соответствующей версии CS.
Согласно официальному описанию, в версии 4.5 повышена безопасность лицензии. Это действительно так:

Поэтому нужно расшифровать утёкший файл auth и посмотреть, что там добавилось:

После позиции ключа 4.5 появилась дополнительная строка — это новый watermarkHash данной версии:

watermarkHash связан с генерацией beacon и с DLL в папке sleeve. Без него или при его неверном значении невозможен онлайн (получение сессии). Вероятно, разработчики могут по этому watermarkHash отследить источник утечки.

Закомментируйте остальной код и жёстко пропишите параметры, присваиваемые после RSA-расшифровки в AuthCrypto().decrypt:

byte[] var4 = {1, -55, -61, 127, 0, 1, -122, -96, 45, 16, 27, -27, -66, 82, -58, 37, 92, 51, 85, -114, -118, 28, -74, 103, -53, 6, 16, -128, -29, 42, 116, 32, 96, -72, -124, 65, -101, -96, -63, 113, -55, -86, 118, 16, -78, 13, 72, 122, -35, -44, 113, 52, 24, -14, -43, -93, -82, 2, -89, -96, 16, 58, 68, 37, 73, 15, 56, -102, -18, -61, 18, -67, -41, 88, -83, 43, -103, 16, 94, -104, 25, 74, 1, -58, -76, -113, -91, -126, -90, -87, -4, -69, -110, -42, 16, -13, -114, -77, -47, -93, 53, -78, 82, -75, -117, -62, -84, -34, -127, -75, 66, 0, 0, 0, 24, 66, 101, 117, 100, 116, 75, 103, 113, 110, 108, 109, 48, 82, 117, 118, 102, 43, 86, 89, 120, 117, 119, 61, 61};
Принцип Javaagent: https://www.cnblogs.com/rickiyang/p/11368932.html
Инструмент для взлома можно посмотреть здесь: https://github.com/Twi1ight/CSAgent
Основа взлома по-прежнему — ключ соответствующей версии CS.
В beacon/BeaconData значение метода shouldPad жёстко задаётся равным false:

Новые скрытые ловушки в 4.4
(Ранее анализ проверки лицензии выполнялся на примере 4.3; после перехода на 4.4 обнаружилось, что при запуске происходит выход — есть новые скрытые ловушки.)
По сравнению с предыдущим выходом через this.shouldPad, в common/Helper добавлена проверка .class — просто закомментируйте:

В common/Starter добавлена проверка .class — закомментируйте:

В common/Starter2 добавлена проверка .class — закомментируйте:

В beacon/CommandBuilder добавлена проверка .class: (эта ловушка действительно подлая: после 4 часов непрерывного соединения между client и teamserver невозможно выполнять команды; я никогда не подключался так долго, поэтому и не замечал, ггг)

Новые скрытые ловушки в 4.5
В версии 4.5 добавлено множество скрытых ловушек, нацеленных на Javaagent. Тем, кто взламывает декомпиляцией jar, они не важны; просто найдите javaagent и исправьте каждое вхождение:

Убрав эти места, снова можно действовать сообща.
Подробно останавливаться на признаке checksum8 не буду; чтобы избежать обнаружения сканерами nmap и поисковыми системами интернет-пространства, всё же стоит его изменить.
В BeaconPayload измените значение XOR на новое:
Подойдёт любое десятичное число; затем в DLL измените его на соответствующее шестнадцатеричное число.

Расшифруйте DLL с помощью CrackSleeve: https://github.com/ca3tie1/CrackSleeve/
cobaltstrike.jar и CrackSleeve.java вместеjavac -encoding UTF-8 -classpath cobaltstrike.jar CrackSleeve.java)java -classpath cobaltstrike.jar;./ CrackSleeve decode) # выполнять в командной строке WindowsНажмите Alt+T для поиска ключевого слова: 2E


Непосредственно измените значение XOR: сначала найдите 2E через Change byte и измените его, затем примените изменения к входному файлу и сохраните. (Не забудьте сохранить.)

DLL, которые нужно изменить: beacon.dll, beacon.x64.dll, dnsb.dll, dnsb.x64.dll, pivot.dll, pivot.x64.dll, extc2.dll, extc2.x64.dll (в 4.5 добавлены несколько rl100k.dll, их тоже нужно изменить)
Затем зашифруйте DLL с помощью CrackSleeve. Наконец, переместите DLL из каталога encode в каталог проекта IDEA и перекомпилируйте/пересоберите пакет.
При тестировании URI-адрес по-прежнему доступен для запросов, но содержимое уже не может быть расшифровано скриптом nmap; аналогично можно избежать распознавания поисковыми системами интернет-пространства:

Помимо изменения значения XOR, можно также https://mp.weixin.qq.com/s?__biz=MzA3MDY2NjMxMA==&mid=2247484641&idx=1&sn=014f6c4ad5343e3f5034c33dffa66f26&chksm=9f3815c8a84f9cde1c7493ff29cfc89c0474fec48ede52be618727e7b9a5ab321c4743e1a44c&mpshare=1&scene=23&srcid=1202NA46yt71CvD3BMGKS10c&sharer_sharetime=1606892728447&sharer_shareid=ff83fe2fe7db7fcd8a1fcbc183d841c4#rd изменить алгоритм checksum8, но тогда URI становится фиксированным, использовать можно только с профилем, а при каждом изменении URI придётся пересобирать пакет. У каждого метода есть свои плюсы и минусы.
Идея удаления признаков BeaconEye взята из ссылки. На примере 4.3 и 4.4 байты, которые необходимо изменить, следующие.
Расшифруйте DLL с помощью CrackSleeve: https://github.com/ca3tie1/CrackSleeve/
Поместите cobaltstrike.jar и CrackSleeve.java вместе
Скомпилируйте (javac -encoding UTF-8 -classpath cobaltstrike.jar CrackSleeve.java)
Расшифруйте файл (java -classpath cobaltstrike.jar;./ CrackSleeve decode) # выполнять в командной строке Windows
4.3 key 58, 68, 37, 73, 15, 56, -102, -18, -61, 18, -67, -41, 88, -83, 43, -103 4.4 key 94, -104, 25, 74, 1, -58, -76, -113, -91, -126, -90, -87, -4, -69, -110, -42
Адрес: 10009FBB
6A 00 измените на 6A 09 (вместо 00 можно любое значение)

Адрес: 000000001800186C3
В beacon.x64.dll инструкция xor edx, edx заменяется на mov edx, esi

Адрес: 1000A0B9
6A 00 измените на 6A 09 (вместо 00 можно любое значение)

Адрес: 000000018001879B
В beacon.x64.dll инструкция xor edx, edx заменяется на mov edx, esi

Затем повторно зашифруйте: java -classpath cobaltstrike.jar;./ CrackSleeve encode


Адрес: 1000A65D

Адрес: 000000018000CA3F

(В 4.5 добавлены несколько rl100k.dll, их тоже нужно изменить)

Суть метода — добавить проверку / для URI: если URI не начинается с /, отвечать 404:
Изменение для 4.4

Изменение для 4.3

Чтобы избежать утечки пароля TOTP или имени входа в CS в Event Log, поле name отображается как MD5 с солью. После изменения выглядит так:

Добавлена двухфакторная проверка TOTP для усиления входа и защиты от подбора пароля (brute-force).
На стороне teamserver в его вывод добавлена ссылка на QR-код TOTP:

(Прежде чем удалить nohup.out, не забудьте скопировать QR-code. При каждом запуске teamserver генерируется новый QR-code, поэтому при каждом запуске teamserver нужно сканировать его заново.)
Откройте в браузере (нужен VPN) и отсканируйте QR-код с помощью Google Authenticator или TOTP-приложения. Также можно скопировать секрет после secret%3D и настроить его в приложении-аутентификаторе:

На стороне connect: host, port и password как раньше; в user последние шесть цифр — динамический код TOTP, и можно подключаться:

Если динамический код TOTP не указан или указан неверно, появится сообщение:

Примечание: если под рукой нет телефона, можно использовать браузерный плагин с поддержкой TOTP или написать простой TOTP-код на Python.
При использовании windows/foreign/reverse_http(s) для spawn возникает ошибка:

В этой версии в ScListener добавлена операция getScalar для Custom, но не учтён случай foreign, из-за чего var1.customDLL и customFileName оказываются пустыми и возникает ошибка:

Временное исправление: при определении, что payload — foreign, напрямую возвращать shellcode. Если этот метод вызывает другие баги, оставляйте заявки в issues:

После исправления всё работает нормально:

Чтобы конфигурацию нельзя было прочитать с помощью mysql-ханнипота, имя файла конфигурации клиента CS больше не является стандартным: генерируется имя из 11 символов (11 символов после MD5 MAC-адреса).
