JA4+: находим скрытые C2-сервера через куки и заголовки

JA4+: находим скрытые C2-сервера через куки и заголовки

Ошибки хакеров в настройках C2-серверов позволяют находить их через анализ отпечатков JA4H, что значительно упрощает обнаружение других связанных угроз.

image

18 ноября Palo Alto Networks объявила об обнаружении двух критических уязвимостей в операционной системе PAN-OS, используемой в NGFW компании. На следующий день компания watchTowr опубликовала отчёт, в котором описано, как уязвимости можно объединить для выполнения удалённого кода.

Вскоре после публикации отчёта watchTowr, Arctic Wolf Labs зафиксировала серию вторжений, направленных на устройства Palo Alto Networks. Результаты исследования были опубликованы 22 ноября.

30 ноября Джон Алтаус из FoxIO сообщил, что несколько индикаторов компрометации (IoC), представленных Arctic Wolf, можно заменить на следующий отпечаток JA4H: po11cn050000_bb52516416a2_eb49a3237520_*. На основе отпечатка удалось подтвердить несколько жертв описанной активности, что подтверждает достоверность данных Arctic Wolf.

В данной статье представлен анализ отпечатка, представленного Джоном Алтаусом, а также два дополнительных отпечатка JA4H, обнаруженных в активности, описанной Arctic Wolf. Также сделан вывод о том, что более общий отпечаток po11cn050000_bb52516416a2_* позволяет выявить ту же активность с допустимым уровнем ложных срабатываний.

Понимание JA4H

26 ноября 2024 года Джон Алтаус опубликовал твит, поделившись отпечатком JA4H: po11cn050000_bb52516416a2_eb49a3237520_*.

В семействе отпечатков JA4+ технология JA4H отвечает за идентификацию HTTP-клиента, отправляющего запрос. Она анализирует метод запроса, заголовки, файлы cookie, их значения и другие переменные каждого HTTP-запроса, создавая отпечаток, читаемый как человеком, так и машиной.

Отпечаток JA4H состоит из четырёх частей: a, b, c и d:

  • JA4H_a описывает основные аспекты: метод HTTP, версию протокола, наличие cookies, заголовок Referrer и количество заголовков.
  • JA4H_b представляет собой усечённое значение SHA256 заголовков в порядке их следования, исключая Cookie и Referrer.
  • JA4H_c создаёт отпечаток полей cookie, которые будут одинаковы для одного сайта или приложения.
  • JA4H_d охватывает как поля cookie, так и их значения, что делает эту часть наиболее детализированной.

Такая структура позволяет отпечаткам JA4H быть динамичными с точки зрения обнаружения и охоты за угрозами. Специфичность отпечатка возрастает от части a к d, при этом важные артефакты запросов остаются читаемыми в части a, что делает отпечаток гибким и легко модифицируемым.

Пример анализа отпечатка JA4H

Данный анализ показывает, что, зная принципы формирования отпечатка, можно экспериментировать с кастомными правилами обнаружения. Например, можно искать схожие запросы с другим количеством заголовков (po11cn*0000_*_eb49a3237520_*) или запросы без установленных cookies (po11nn050000_bb52516416a2_*).

Три последние части отпечатка JA4H (_b, _c и _d) сложнее воспроизвести, так как они не читаемы человеком. Как и любые криптографические хэши, их нельзя просто изменить или использовать подстановочные символы для включения или исключения элементов.

Для воспроизведения JA4H_b и JA4H_c из отпечатка Альтхауса (bb52516416a2 и eb49a3237520) необходимо знать, какие заголовки использует вредоносное ПО. В данном случае, так как ПО связывается со своим C2 через HTTP, обратная разработка не требуется.

Запросы, полученные имплантом, о которых сообщает Arctic Wolf

На основании этих данных подтверждено, что вредоносное ПО устанавливает 5 заголовков: Host, User-Agent, Content-Length, Upgrade-Insecure-Requests и Accept-Encoding. Это соответствует первой части отпечатка JA4H: po11cn050000.

С помощью следующего скрипта CyberChef можно воспроизвести JA4H_b:

Воспроизведение JA4H_b с помощью CyberChef ( https://gchq.github.io/CyberChef/ )

 Find_/_Replace({'option':'Regex','string':'(Cookie\\:.+|Referer\\:.+)\\r\\n'},'',true,false,true,true)
Find_/_Replace({'option':'Regex','string':'(POST|PUT|GET|HEAD).+\\r\\n'},'',true,false,true,false)
Find_/_Replace({'option':'Regex','string':'\\:.+'},'',true,false,true,false)
Find_/_Replace({'option':'Regex','string':'\\r?\\n'},',',true,false,true,false)
SHA2('256',64,160)
Regular_expression('User defined','^.{0,12}',true,true,false,false,false,false,'List matches')

Скрипт CyberChef для предварительного изготовления отпечатка пальца

Мы также можем воспроизвести JA4H_c, который является усечённым SHA256 от куки SSID, устанавливаемого вредоносной программой:

import hashlib
hashlib.sha256("SSID".encode()).hexdigest()[:12]
# eb49a3237520

Мы также можем использовать скрипт CyberChef, чтобы передать другие сигнатуры вредоносного ПО, если мы подозреваем, что вирус может использовать другие заголовки или порядок заголовков. Чем больше мы знаем о вредоносном ПО и о том, как оно ведет себя в сети, тем лучше мы можем настроить отпечаток JA4H, чтобы сделать более сильные и более детальные обнаружения.

В данном случае хакер использовал популярный фреймворк C2 с открытым исходным кодом, Sliver. Такие фреймворки с открытым исходным кодом предлагают уникальные возможности обнаружения — нам не нужен образец, и нам не нужно быть опытными реверс-инженерами. Несмотря на то, что многие такие фреймворки предлагают обфускацию «из коробки», злоумышленники часто не меняют конфигурации по умолчанию. Например, HTTP сервер управления Sliver по умолчанию использует следующие заголовки ответа:

serverHeaders := []*clientpb.HTTPC2Header{
	{
		Method:      "GET",
		Name:        "Cache-Control",
		Value:       "no-store, no-cache, must-revalidate",
		Probability: 100,
	},
}

Стоит отметить, что в данном коде значения Cache-Control совпадают с теми, которые содержатся в образце, проанализированном Arctic Fox. Это совпадение само по себе является возможностью обнаружения.

Обнаружение дополнительных C2-серверов

Rjvgfybz Webscout использовала комплексный набор источников для сбора метаданных для обогащения и контекстуализации IP-адресов в больших масштабах, одним из которых является набор цифровых отпечатков JA4+. Перебирая различные вариации отпечатка JA4H в коллекции, специалисты обнаружили несколько жертв и других C2 в том же кластере активности, о котором сообщила Arctic Wolf.

Используя расширенные вариации отпечатка JA4H, удалось выявить ещё несколько активных C2-серверов, связанных с описанной активностью:

  • IP-адреса: 172.232.195[.]234, 194.182.164[.]149

Оба адреса — очевидные сервера управления Sliver, поскольку

1. Они открывают TCP-порт 31337;

2. Значение эмитента сертификата SSL: CN=operators;

3. Значение предмета SSL-сертификата: CN=multiplayer.

JA4H отпечатки po11cn050000_bb52516416a2_e1eae9e373ba_913d7ea84b88 и po11cn050000_bb52516416a2_a9f2370d1a00_3e59a4bec10d

Предположив, что имплант по умолчанию устанавливает только один cookie-файл, как показано в примере воспроизведения JA4H_b. Тогда быстрый перебор имен cookie-файлов привел к двум новым отпечаткам JA4H_c, которые ранее не наблюдались.

 cookies = [] # long ahh list of common cookie names
for cookie in cookies:
    hash = hashlib.sha256(cookie.encode()).hexdigest()[:12] # JA4H_c
    if hash == "e1eae9e373ba" or hash == "a9f2370d1a00":
        print(f"{hash}:{cookie}")
> e1eae9e373ba:refreshToken
> a9f2370d1a00:csrf-state

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

Возможность использования одного JA4H для выявления нескольких других вредоносных серверов с минимальными знаниями о базовом вредоносном ПО подчеркивает ключевое преимущество пакета JA4+: его способность обнаруживать вредоносных «соседей по отпечаткам пальцев» с помощью едва заметных изменений, cookie-файлов, заголовков и других артефактов HTTP-запросов.

Почему так происходит?

Злоумышленники продолжают использовать стандартные конфигурации серверов C2, что делает их уязвимыми для обнаружения. Разработчики вредоносного ПО прилагают значительные усилия, чтобы скрыть свои инструменты, однако ошибки операторов, которые не настраивают эти параметры, предоставляют возможности для их выявления. Например, Sliver может динамически изменять свой отпечаток JARM путём рандомизации наборов шифров TLS.

Пример кода для рандомизации шифров:

// Рандомизация наборов шифров

 allCipherSuites := []uint16{
    tls.TLS_RSA_WITH_RC4_128_SHA,                      // uint16 = 0x0005 1
    tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,                 // uint16 = 0x000a 2
    tls.TLS_RSA_WITH_AES_128_CBC_SHA,                  // uint16 = 0x002f 3
    tls.TLS_RSA_WITH_AES_256_CBC_SHA,                  // uint16 = 0x0035 4
    tls.TLS_RSA_WITH_AES_128_CBC_SHA256,               // uint16 = 0x003c 5
    tls.TLS_RSA_WITH_AES_128_GCM_SHA256,               // uint16 = 0x009c 6
    tls.TLS_RSA_WITH_AES_256_GCM_SHA384,               // uint16 = 0x009d 7
    tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,              // uint16 = 0xc007 8
    tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,          // uint16 = 0xc009 9
    tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,          // uint16 = 0xc00a 10
    tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,                // uint16 = 0xc011 11
    tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,           // uint16 = 0xc012 12
    tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,            // uint16 = 0xc013 13
    tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,            // uint16 = 0xc014 14
    tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,       // uint16 = 0xc023 15
    tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,         // uint16 = 0xc027 16
    tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,         // uint16 = 0xc02f 17
    tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,       // uint16 = 0xc02b 18
    tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,         // uint16 = 0xc030 19
    tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,       // uint16 = 0xc02c 20
    tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,   // uint16 = 0xcca8 21
    tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, // uint16 = 0xcca9 22
}

// CipherSuites игнорирует порядок шифров. Этот случайный порядок позволяет выбрать случайный набор шифров.

insecureRand.Shuffle(len(allCipherSuites), func(i, j int) {
    allCipherSuites[i], allCipherSuites[j] = allCipherSuites[j], allCipherSuites[i]
})
nCiphers := insecureRand.Intn(len(allCipherSuites)-8) + 8
tlsConfig.CipherSuites = allCipherSuites[:nCiphers]

Однако функции защиты от обнаружения бесполезны, если операторы их не используют. С точки зрения скрытности и возможности обнаружения, система защиты так же сильна, как её самое слабое звено — в данном случае это сам злоумышленник.

Ещё один важный момент — продолжение использования незашифрованного трафика во многих вредоносных фреймворках. Почему злоумышленники могут так делать? Потому что большинство организаций фиксируют только данные NetFlow, которые данные содержат информацию высокого уровня об IP-адресах, портах, длине сессий и объёме переданных данных, но редко включают детали уровня 7 (прикладного уровня OSI), что делает методы обнаружения бесполезными.

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

Заключение

Использование отпечатков JA4H показало свою эффективность для обнаружения и анализа вредоносной активности, особенно в контексте эксплуатации уязвимостей межсетевых экранов Palo Alto Networks. Разбор и понимание отпечатка, предоставленного Джоном Алтаусом (po11cn050000_bb52516416a2_eb49a3237520_*), позволили выявить дополнительные серверы управления и подтвердить активность, описанную Arctic Wolf.

Наш канал защищен лучше, чем ваш компьютер!

Но доступ к знаниям открыт для всех

Получите root-права на безопасность — подпишитесь