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

Статья BendyBear: Китайский шелл-код связанный с группой BlackTech

Azrv3l

win32kfull
Эксперт
Регистрация
30.03.2019
Сообщения
215
Реакции
539
Bendybear-3-illustration_black.png

Вступление
Высокая гибкость, сложность и машинный код более 10 000 байт. Именно с этим столкнулись исследователи Unit 42 во время анализа кода этого файла. Поведение кода и функции сильно коррелируют с семейством вредоносных программ WaterBear, которое было активным еще с 2009 года. Анализ, проведенный Trend Micro и TeamT5, показал, что WaterBear представляет собой многогранный имплант второго этапа, способный передавать файлы, доступ к оболочке и т. Д. снимок экрана и многое другое. Вредоносное ПО связано с кибершпионажной группой BlackTech, которая, по оценке многих представителей более широкого сообщества исследователей угроз, связана с правительством Китая, и, как полагают, несет ответственность за недавние атаки на несколько правительственных организаций Восточной Азии. Из-за сходства с WaterBear и полиморфной природы кода Unit 42 назвал этот новый китайский шелл-код «BendyBear». Он стоит в собственном классе с точки зрения того, что является одним из самых сложных, хорошо спроектированных и трудно обнаруживаемых образцов шелл-кода, используемых APT.

Образец BendyBear был определен как шелл-код x64 для имплантата нулевой стадии, единственной функцией которого является загрузка более надежного имплантата с сервера управления и контроля (C2). Шелл-код, несмотря на свое название, используется для описания небольшого фрагмента кода, загружаемого в цель сразу после эксплуатации, независимо от того, порождает ли он на самом деле командную оболочку или нет. При размере более 10 000 байт BendyBear заметно больше, чем большинство других, и использует его для реализации расширенных функций и методов антианализа, таких как модифицированное шифрование RC4, проверка блока подписи и полиморфный код.

Образец, проанализированный в этом блоге, был идентифицирован по его связям с вредоносным доменом C2, опубликованным Бюро расследований Министерства юстиции Тайваня в августе 2020 года. Было обнаружено отсутствие дополнительной информации о векторе эксплойта, потенциальных жертвах или предполагаемом использовании.

Новый класс шелл-кода

На макроуровне BendyBear уникален следующим:
  • Передает полезные данные в модифицированных фрагментах, зашифрованных RC4. Это усиливает шифрование сетевой связи, поскольку один ключ RC4 не расшифрует всю полезную нагрузку.
  • Попытки оставаться скрытыми от анализа кибербезопасности путем явной проверки своей среды на наличие признаков отладки.
  • Использует существующий раздел реестра Windows, который включен по умолчанию в Windows 10 для хранения данных конфигурации.
  • Очищает кеш DNS хоста каждый раз, когда он пытается подключиться к своему серверу C2, тем самым требуя, чтобы хост каждый раз разрешал текущий IP-адрес для вредоносного домена C2.
  • Создает уникальные сеансовые ключи для каждого подключения к серверу C2.
  • Скрывает свой протокол подключения, подключаясь к серверу C2 через общий порт (443), тем самым смешиваясь с обычным сетевым трафиком SSL.
  • Использует полиморфный код, изменяя его след во время выполнения кода, чтобы помешать анализу памяти и избежать подписания.
  • Шифрует или дешифрует функциональные блоки (блоки кода) во время выполнения по мере необходимости, чтобы избежать обнаружения.
  • Использует позиционно-независимый код (PIC), чтобы избавиться от инструментов статического анализа.
В следующих разделах мы дадим подробное техническое описание каждой из этих возможностей.

Технические детали
Выполнение шеллкода
Шелл-код (SHA256: 64CC899EC85F612270FCFB120A4C80D52D78E68B05CAF1014D2FE06522F1E2D0) считается стейджером или загрузчиком, функция которого заключается в загрузке имплантата с сервера C2. Во время выполнения код использует рандомизацию байтов, чтобы скрыть свое поведение. Это достигается за счет использования текущего времени хоста в качестве начального числа для генератора псевдослучайных чисел, а затем выполнения дополнительных операций с этим выводом. Полученные значения используются для перезаписи блоков ранее выполненного кода. Эта манипуляция с байтами - первый метод антианализа, наблюдаемый в коде, поскольку любая попытка сбросить сегмент памяти приведет к незаконным или неправильным операциям. На рисунке 1 показан пример основной точки входа в шелл-код до и во время выполнения.

word-image-15.png


WaterBear на основе атрибутов, определенных в этом примере. Более подробную информацию об этих загрузчиках можно найти в разделе приложения «Загрузчики x86 WaterBear».

Шелл-код начинается с поиска целевого блока среды процесса (PEB), чтобы проверить, отлаживается ли он в данный момент. Однако код написан таким образом, что он извлекает значения «BeingDebugged» и «BitField» из PEB, что приводит к логике кода, которая делает недействительной проверку отладчика. Из-за этого шелл-код всегда не распознает присоединенный отладчик. Эта процедура выполняется 52 раза в цикле while.

Затем шелл-код просматривает список модулей загрузчика PEB в поисках базового адреса Kernel32.dll. Это типично для шелл-кода, поскольку базовый адрес Kernel32.dll необходим для разрешения любых файлов зависимостей, требуемых шелл-кодом для запуска. С этим адресом шелл-код загружает свои модули зависимостей и разрешает все необходимые вызовы Windows Application Programming Interface (API), используя стандартное хеширование API шелл-кода. Загружены следующие модули:
  • Advapi32.dll
  • Kernel32.dll
  • Msvcrt.dll
  • User32.dll
  • Ws2_32.dll
После завершения инициализации шелл-кода он переходит к своей основной функции. Он начинается с запроса реестра цели по следующему ключу:
HKEY_CURRENT_USER\Console\QuickEdit

Этот раздел реестра используется командной строкой Windows для включения режима быстрого редактирования. Режим быстрого редактирования позволяет копировать и вставлять из командной строки в буфер обмена. По умолчанию этот ключ содержит REG_DWORD, 32-битное число: 1 для включения или 0 для выключения. BendyBear считывает это значение, умножает его на 1000 и выполняет следующие вычисления над результатом:

Если результат меньше 1 000 или больше 3 300 000, конфигурация шелл-кода (QuickEdit) равна 4 000 (0xFA0), в противном случае это результат вычисленного значения.

См. Выделенное голубым цветом значение на рисунке 2 Конфигурация шелл-кода.

Эта проверка выполняется каждый раз при выполнении шелл-кода. Одно из объяснений использования этого ключа состоит в том, что значение записывается загрузчиком шелл-кода (в значение, отличное от 0 или 1), и оно используется шелл-кодом для получения параметров конфигурации.

Затем он расшифровывает свою внутреннюю структуру конфигурации, которая составляет 1152 байта. Пример показан на рисунке 2.

word-image-16.png


Разбивка структуры конфигурации, показанной на Рисунке 2, приведена ниже (сверху вниз):
  • Неоново-зеленым цветом выделены два 16-байтовых ключа, используемых для XORing значений во всем шеллкоде.
    • 7D 38 BA FD E1 C8 D2 DF B6 EE 33 F9 14 BF 52 96
    • 71 17 DF E4 AE 3B A9 F2 D5 3D 75 CC D3 0D 57 72
  • олубым цветом выделены два байта, вычисленные на основе ключа быстрого редактирования реестра хоста.
    • E8 03
  • Оранжевым цветом выделены четыре байта, представляющие версию шеллкода.
    • 30 2Э 32 34 (0,24)
  • Розовым цветом выделены 17 байтов, составляющих домен C2. Побитовое НЕ (байт без знака) для декодирования значений, включая NULL.
    • 88 98 CE D1 96 91 94 9A 8C 93 96 89 9A D1 9C 90 92
  • Темно-зеленым выделены 103 байта, которые используются для исключения шаблона. XOR со значениями от 0xFF до NULL.
    • FF FF FF FF FF FF FF FF FF FF FF…
  • Пурпурным цветом выделены два байта, составляющие целевой порт C2.
    • BB 01
  • Светло-желтым цветом выделены разрешенные указатели на функции, используемые шеллкодом.
    • 92 13 73 33 37 02
  • Темно-голубым цветом выделены 112 байтов, которые составляют размеры указателя функции, используемые для шифрования или дешифрования функциональных блоков.
    • EE 01
  • Темно-красным выделены 289 байтов, которые составляют разрешенные функции Windows API, используемые шеллкодом.
    • A0 2E 52 CC FC 7F 00 00…
Сетевые коммуникации
word-image-17.png


Перед взаимодействием с сервером C2 шеллкод очищает кеш DNS хоста, выполнив следующие действия:
  • Загружает модуль dnsapi.dll
  • Вызывает API DnsFlushResolverCache

При вызове этого API все разрешенные домены удаляются из кеша DNS хоста, а не только целевой сервер C2. Это вынуждает хост разрешить текущий IP-адрес, связанный с доменом C2, гарантируя, что связь продолжается, когда сетевая инфраструктура становится скомпрометированной или недоступной. Это также подразумевает, что разработчики владеют доменом и могут обновлять IP.

Стаджер начинает с вычисления 10 байтов данных для отправки на сервер C2. Эти 10 байтов составляют пакет запроса вызова. Стаджер отправляет запрос на вызов на C2 и ожидает ответа на запрос. При получении и правильной расшифровке stager проверяет магические значения или байты подписи при определенных смещениях. Если эта проверка не удалась, сетевое соединение прерывается. Эта проверка обеспечивает надежную связь с предполагаемым сервером C2 и инициирует загрузку полезной нагрузки.

I. Stager генерирует пакет запроса на вызов

Стаджер вычисляет 10-байтовый запрос вызова, содержащий информацию для C2, чтобы включить размер данных (являющихся сеансовыми ключами), которые будут получены следующими. Запрос вызова и сеансовые ключи отправляются на C2 одновременно. Пример запроса: 26BCFCCE738A211F3763

II. Сервер C2 расшифровывает пакет запроса на вызов
C2 расшифровывает пакет запроса вызова, используя следующие шаги:

1. Первый байт будет обработан методом XOR со вторым байтом, второй байт - с третьим байтом… до байта 10, за которым следует:
A. Байт 7 обновляется по результату (байт 7 подвергается операции XOR с байтом 3).
Б. Байт 2 обновляется по результату (байт 2 подвергается операции XOR с байтом 0).
C. Байт 8 обновляется по результату (байт 8 подвергается операции XOR с байтом 0).
D. Байт 9 обновляется по результату (байт 9 подвергается операции XOR с байтом 5).
2. Окончательное значение подвергается операции XOR с ключом 0x3FDA5F9AD85D50C77E6A.

Запрос на вызов расшифровывается до следующего (представленного в виде шестнадцатеричных байтов):

word-image-18.png


Последние четыре байта расшифрованного пакета запроса информируют сервер C2 о размере ожидаемого сетевого трафика. Как показано выше, значение равно 0x20 или 32 байта.
Эти 32 байта составляют ключи сеанса, используемые сервером C2 для шифрования ответа сервера на запрос и шифрования полезной нагрузки.

Пример сессионных ключей, полученных сервером C2:
Сеансовый ключ 1–> 8C931D4F764B0661C26D77239EB454CA
Сеансовый ключ 2–> 7A4DD0AA6C3F37CDBDAFA4CBD6B27697

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

III. C2 аутентифицируется с помощью Stager
C2 использует ключи сеанса для создания поля состояния RC4 и в качестве ключа XOR для шифрования и дешифрования.

* Следует отметить, что использование сеансового ключа 2 еще не полностью изучено, и, похоже, он не использовался для связи со стейджером.

1. Предсессионный ключ вычисляется с использованием сеансового ключа 1 (первые 16 байтов) следующим образом:
Предсессионный ключ = сеансовый ключ 1 XOR
0X6162636465666768696A6B6C6D6E6F00

2. Используя вычисленный предсессионный ключ из шага 1, сервер C2 строит алгоритм планирования ключей RC4 (KSA). Он рассчитывается следующим образом:
а. Создайте RC4 KSA, используя следующие входные данные для функции ниже:
data = 16-байтовый ключ 0x0C2F65194FF37B2D63D34635C7B205E4
key = 16-байтовый вычисленный предсессионный ключ из шага 1

Пример RC4 (модифицированной) подпрограммы KSA:


Код:
def rc4_KSA (данные, ключ):
    x = 0
    box = range(258)
    box[256] = 0
    box[257] = 0
    for i in range(256):
    x = (x + box[i] + ord(key[i % len(key)])) % 256
    box[i], box[x] = box[x], box[i]
    return box

* Примечание относительно входного параметра «данные» для процедуры KSA: это результат XOR двух 16-байтовых ключей, показанных неоново-зеленым цветом на рисунке 2. Структура конфигурации шелл-кода.

3. Создайте 10-байтовый заголовок ответа сервера на запрос, используя шестнадцатеричные значения, показанные на рисунке 5.

word-image-19.png


4. Зашифруйте заголовок ответа на запрос сервера из шага 3:
a. Вызов 10-байтового сервера XOR с ключом 0x33836E6B3FAA6AC464DA и выполнение следующего:
i. Байт 7 обновляется по результату (байт 7 подвергается операции XOR с байтом 3).
ii. Байт 2 обновляется по результату (байт 2 XOR соединен с байтом 0).
iii. Байт 8 обновляется по результату (байт 8 подвергается операции XOR с байтом 0).
iv. Байт 9 обновляется по результату (байт 9 подвергается операции XOR с байтом 5).
b. Заголовок ответа на зашифрованный запрос сервера = результат 4 (а)
5. Вычислить окончательный ключ аутентификации:
a. Выполните XOR для следующих значений:
i. 0x0C2F65194FF37B2D63D34635C7B205E4
ii. Значение, рассчитанное на шаге 1, т.е. ключ перед сеансом.

* 16-байтовое значение в 5.a.i - это тот же входной параметр, который используется в алгоритме KSA на шаге 2. Стаджер ожидает этот ключ от C2, в противном случае сеанс прерывается.

Значения, сгенерированные на шагах 4 и 5, составляют полный ответ на запрос сервера. На этом этапе C2 отправляет ответ на запрос сервера в stager, завершая процесс аутентификации.

IV. C2 шифрует и передает полезную нагрузку
Затем C2 готовится отправить команду на stager. BendyBear поддерживает только один тип команды: загрузка полезной нагрузки.

1. Создайте 10-байтовый заголовок команды, используя шестнадцатеричные значения, показанные на рисунке 6.

word-image-20.png


Единственное изменение в заголовке - это фиксированное значение подписи с 0x40 до 0x43.

2. Зашифруйте заголовок команды из шага 1:
Ниже приведен пример модифицированной подпрограммы RC4, которую можно использовать. Первый аргумент, box, будет S-Box, вычисленным на шаге III.2, а второй аргумент, data, будет заголовком команды из шага 1.

Код:
def rc4_Mod_Crypt(box, data):
    x = box[256]
    y = box[257]
    c = 0
    out = []
    for char in data:
        x = (x + 1) % 256
        y = (y + box[x]) % 256
        box[x], box[y] = box[y], box[x]
        z = ( (box[x] + box[y] )&0xff ) % 256
        al = rol( box[z],4,8 )
        out.append( chr( ord( data[c] ) ^ al ) )
        box[z] = al
        c+=1
box[256] = x
box[257] = y
return ”.join(out)

3. Получите размер полезной нагрузки и зашифруйте это значение, используя тот же алгоритм RC4, что и на шаге 2. Размер полезной нагрузки должен быть общим расшифрованным размером полезной нагрузки.

4. Зашифруйте и отправьте полезную нагрузку на стейджер по частям:
a. Прочтите 4086 байт из полезной нагрузки. Это максимальный размер блока, который может принять stager.
b. Создайте заголовок команды (шаг 1 выше) и обновите следующие поля:
i. Размер заголовка = размер блока полезной нагрузки.
ii. Команда = 1.
c. Отправьте обновленный 10-байтовый заголовок команды в stager.
d. Отправьте зашифрованный фрагмент полезной нагрузки.
е. Повторяйте шаги a - d, пока полезные данные не будут отправлены.

На рисунке 7 показан пример одного блока полезной нагрузки, который отправляется в stager.

word-image-21.png


После получения каждого фрагмента stager удаляет заголовок команды и расшифровывает фрагмент полезной нагрузки в памяти.

Загрузка полезной нагрузки в память

После того, как полезная нагрузка полностью расшифрована, stager выполняет некоторые базовые проверки, чтобы убедиться, что полезная нагрузка соответствует исполняемому файлу Windows. Он проверяет заголовок DOS и PE, а также то, что полезная нагрузка является DLL. Затем он загружает полезную нагрузку в прямую память и вызывает ее точку входа (AddressOfEntryPoint). Прямая загрузка памяти полезными данными имитирует загрузку Windows PE - LoadLibrary. В результате структуры метаданных PEB LDR_DATA_TABLE_ENTRY не создаются, а PEB для процесса, выполняющего шеллкод, не имеет записи о загрузке DLL, которая может использоваться для обнаружения несанкционированных модулей, работающих на вашем хосте. Это видно в WinDbg, запустившем команду! Адрес в процессе, загрузившем шеллкод. Пример показан на рисунке 8.

Screen-Shot-2021-02-05-at-6.41.06-PM.png


Артефакты в памяти:
  • Тип - MEM_PRIVATE, что означает, что он является частным для процесса, который его загрузил. На платформах Windows библиотеки DLL обычно загружаются как MEM_IMAGE, чтобы их можно было использовать совместно с разными процессами для экономии места в памяти.
  • Защита - PAGE_EXECUTE_READWRITE (RWX), что означает, что область доступна для записи и выполнения с областью памяти, содержащей заголовок MZ. Заголовок MZ - это загруженный в память модуль.
Результат выполнения команды !address WinDbg, Показанный на рисунке 8, обнаруживает аномальную запись. Адрес памяти модуля 0x7ff4c2450000 был результатом выделения частной памяти, установки защиты на RWX и использования, содержащего заголовок MZ.

x64 Shellcode Behaviors​

В следующей таблице описаны основные функции BendyBear.

Screenshot (32).png


BendyBear vs. WaterBear

Screenshot (33).png


Заключение
Шелл-код BendyBear содержит расширенные функции, которые обычно не встречаются в шелл-коде. Использование методов антианализа и проверки блока подписи указывает на то, что разработчики заботятся о скрытности и уклонении от обнаружения. Кроме того, использование настраиваемых криптографических процедур и манипуляции с байтами предполагает высокий уровень технической сложности.

Дополнительные ресурсы
Taiwan News – Taiwan urges blocking 11 China-linked phishing domains.
iThome News – The Bureau of Investigation’s recent investigation of several cases of Taiwan Government agencies hacked.
TeamT5 – Evil Hidden in Shellcode: The Evolution of malware DbgPrint.
TrendMicro – WaterBear Returns, Uses API Hooking to Evade Security.
TrendMicro – The Trail of BlackTech’s Cyber Espionage Campaigns.
CryCraft Technology Corp – Taiwan Government Targeted by Multiple Cyberattacks in April 2020 Part 1: Waterbear Malware
JPCERT/CC Eyes – ELF_PLEAD – Linux Malware Used by BlackTech

Приложение

Shellcode PoC
Имитация сервера C2, обслуживающего запрос к stager и отправляющего полезную нагрузку (DLL), которая отображает окно сообщения:
Код:
python.exe U42ETHOS_C2.py -l 8080 -p c:\temp\DLLSample.dll
[+] Started U42ETHOS_C2.py ver 1.0.0 waiting for connection on TCP port 8080
[!] Using payload file c:\temp\DLLSample.dll
[!] Received new connection from: (‘192.168.163.138’, 49918)
[-] Received Encrypted challenge Request Packet–> 40da9a64bf3992d39db6
[-] Decrypted challenge Request packet–> 46401f8c032320000000
[+] Session key 1–> 9816f78b57fff54efb5419202d81a729
[+] Session key 2–> 6ec83a6e4d8bc4e28496cac865878574
[+] Computed PreSessionKey–> f97494ef32999226923e724c40efc829
[+] Challenge command–> a3601149a495d02598b7
[-] Challenge key is–> f55bf1f67d6ae90bf1ed3479875dcdcd
[+] Payload Size is 00920100
[!] Payload sent to stager. Check if executed

word-image-46.png


На рисунке 9 показан макет C2-сервера Python, созданный модулем 42 для взаимодействия со стейджером. Он настроен на прослушивание TCP-порта 8080, а полезная нагрузка - это тестовая DLL, которая запускает calc.exe и отображает окно сообщения (Hello, Implant). На рисунке 10 показан хост Windows 10, на котором шеллкод запускается в памяти через специальный загрузчик. Шелл-код был настроен для связи с фиктивным сервером C2.

Network Traffic for the Above Payload (truncated):

word-image-47.png


От ТС
Это перевод материала, взятого отсюда
Если есть предложения, что перевести, вам сюда
Все хэши есть в оригинальной статье

Перевод:
Azrv3l cпециально для xss.pro
 
Пожалуйста, обратите внимание, что пользователь заблокирован
машинный код более 10 000 байт
Бедные они несчастные, 10кб шелкода никогда в жизни не видели.
 


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