12 KiB
Загальні API, що використовуються в шкідливому ПЗ
{{#include ../banners/hacktricks-training.md}}
Загальні
Мережа
Сирі сокети | WinAPI сокети |
---|---|
socket() | WSAStratup() |
bind() | bind() |
listen() | listen() |
accept() | accept() |
connect() | connect() |
read()/recv() | recv() |
write() | send() |
shutdown() | WSACleanup() |
Постійність
Реєстр | Файл | Служба |
---|---|---|
RegCreateKeyEx() | GetTempPath() | OpenSCManager |
RegOpenKeyEx() | CopyFile() | CreateService() |
RegSetValueEx() | CreateFile() | StartServiceCtrlDispatcher() |
RegDeleteKeyEx() | WriteFile() | |
RegGetValue() | ReadFile() |
Шифрування
Назва |
---|
WinCrypt |
CryptAcquireContext() |
CryptGenKey() |
CryptDeriveKey() |
CryptDecrypt() |
CryptReleaseContext() |
Анти-аналіз/VM
Назва функції | Інструкції асемблера |
---|---|
IsDebuggerPresent() | CPUID() |
GetSystemInfo() | IN() |
GlobalMemoryStatusEx() | |
GetVersion() | |
CreateToolhelp32Snapshot [Перевірка, чи запущено процес] | |
CreateFileW/A [Перевірка, чи існує файл] |
Схованість
Назва | |
---|---|
VirtualAlloc | Виділення пам'яті (пакувальники) |
VirtualProtect | Зміна дозволів пам'яті (пакувальник надає дозвіл на виконання секції) |
ReadProcessMemory | Ін'єкція в зовнішні процеси |
WriteProcessMemoryA/W | Ін'єкція в зовнішні процеси |
NtWriteVirtualMemory | |
CreateRemoteThread | Ін'єкція DLL/процесу... |
NtUnmapViewOfSection | |
QueueUserAPC | |
CreateProcessInternalA/W |
Виконання
Назва функції |
---|
CreateProcessA/W |
ShellExecute |
WinExec |
ResumeThread |
NtResumeThread |
Різне
- GetAsyncKeyState() -- Логування клавіш
- SetWindowsHookEx -- Логування клавіш
- GetForeGroundWindow -- Отримати назву активного вікна (або вебсайту з браузера)
- LoadLibrary() -- Імпорт бібліотеки
- GetProcAddress() -- Імпорт бібліотеки
- CreateToolhelp32Snapshot() -- Список запущених процесів
- GetDC() -- Скриншот
- BitBlt() -- Скриншот
- InternetOpen(), InternetOpenUrl(), InternetReadFile(), InternetWriteFile() -- Доступ до Інтернету
- FindResource(), LoadResource(), LockResource() -- Доступ до ресурсів виконуваного файлу
Техніки шкідливого ПЗ
Ін'єкція DLL
Виконати довільну DLL всередині іншого процесу
- Знайти процес для ін'єкції шкідливої DLL: CreateToolhelp32Snapshot, Process32First, Process32Next
- Відкрити процес: GetModuleHandle, GetProcAddress, OpenProcess
- Записати шлях до DLL всередині процесу: VirtualAllocEx, WriteProcessMemory
- Створити потік у процесі, який завантажить шкідливу DLL: CreateRemoteThread, LoadLibrary
Інші функції для використання: NTCreateThreadEx, RtlCreateUserThread
Відображувана ін'єкція DLL
Завантажити шкідливу DLL без виклику звичайних API Windows.
DLL відображається всередині процесу, вона вирішить адреси імпорту, виправить переміщення та викличе функцію DllMain.
Захоплення потоку
Знайти потік з процесу та змусити його завантажити шкідливу DLL
- Знайти цільовий потік: CreateToolhelp32Snapshot, Thread32First, Thread32Next
- Відкрити потік: OpenThread
- Призупинити потік: SuspendThread
- Записати шлях до шкідливої DLL всередині процесу жертви: VirtualAllocEx, WriteProcessMemory
- Відновити потік, що завантажує бібліотеку: ResumeThread
Ін'єкція PE
Ін'єкція Portable Execution: Виконуваний файл буде записаний у пам'яті процесу жертви і буде виконуватися звідти.
Порожнє процесу (також відоме як RunPE)
Process Hollowing
є одним з улюблених трюків обходу захисту / виконання, що використовуються шкідливим ПЗ для Windows. Ідея полягає в тому, щоб запустити легітимний процес у призупиненому стані, видалити (порожнє) його оригінальне зображення з пам'яті та скопіювати довільний PE на його місце. Коли первинний потік нарешті відновлюється, шкідливий вхідний пункт виконується під виглядом довіреного бінарного файлу (часто підписаного Microsoft).
Типовий робочий процес:
- Запустити доброзичливий хост (наприклад,
RegAsm.exe
,rundll32.exe
,msbuild.exe
) призупиненим, щоб жодні інструкції ще не виконувалися.
STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcessA("C:\\Windows\\Microsoft.NET\\Framework32\\v4.0.30319\\RegAsm.exe",
NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
- Прочитати шкідливий вантаж у пам'ять і розібрати його PE заголовки, щоб отримати
SizeOfImage
, секції та новийEntryPoint
. - NtUnmapViewOfSection / ZwUnmapViewOfSection – зняти відображення оригінальної бази зображення призупиненого процесу.
- VirtualAllocEx – зарезервувати RWX пам'ять
SizeOfImage
всередині віддаленого процесу. - WriteProcessMemory – спочатку скопіювати
Headers
, а потім пройтися по секціях, копіюючи їх сирі дані. - SetThreadContext – виправити значення
EAX/RAX
(RCX
на x64) абоRip
у структурі контексту, щобEIP
вказував наEntryPoint
вантажу. - ResumeThread – потік продовжує виконання, виконуючи код, наданий атакуючим.
Мінімальний доказ концепції (x86) скелет:
void RunPE(LPCSTR host, LPVOID payload, DWORD payloadSize){
// 1. create suspended process
STARTUPINFOA si = {sizeof(si)}; PROCESS_INFORMATION pi;
CreateProcessA(host, NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,&pi);
// 2. read remote PEB to get ImageBaseAddress
CONTEXT ctx; ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(pi.hThread,&ctx);
PVOID baseAddr;
ReadProcessMemory(pi.hProcess,(PVOID)(ctx.Ebx+8),&baseAddr,4,NULL);
// 3. unmap original image & allocate new region at same base
NtUnmapViewOfSection(pi.hProcess,baseAddr);
PVOID newBase = VirtualAllocEx(pi.hProcess,baseAddr,pHdr->OptionalHeader.SizeOfImage,
MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
// 4-5. copy headers & sections …
// 6. write new image base into PEB and set Eip
WriteProcessMemory(pi.hProcess,(PVOID)(ctx.Ebx+8),&baseAddr,4,NULL);
ctx.Eax = (DWORD)(newBase) + pHdr->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(pi.hThread,&ctx);
// 7. run!
ResumeThread(pi.hThread);
}
Практичні нотатки, спостережені в кампанії DarkCloud Stealer:
- Завантажувач вибрав
RegAsm.exe
(частина .NET Framework) як хост – підписаний бінарний файл, який навряд чи приверне увагу. - Розшифрований VB6 крадій (
holographies.exe
) не скидається на диск; він існує лише всередині порожнього процесу, що ускладнює статичне виявлення. - Чутливі рядки (regex, шляхи, облікові дані Telegram) RC4-зашифровані для кожного рядка і розшифровуються лише під час виконання, що ще більше ускладнює сканування пам'яті.
Ідеї для виявлення:
- Сповіщати про процеси
CREATE_SUSPENDED
, які ніколи не створюють GUI/консольні вікна перед тим, як область пам'яті буде виділена як RWX (рідко для доброчинного коду). - Шукати послідовність викликів
NtUnmapViewOfSection ➜ VirtualAllocEx ➜ WriteProcessMemory
в різних процесах.
Хукінг
- SSDT (System Service Descriptor Table) вказує на функції ядра (ntoskrnl.exe) або драйвера GUI (win32k.sys), щоб користувацькі процеси могли викликати ці функції.
- Руткіт може змінювати ці вказівники на адреси, які він контролює.
- IRP (I/O Request Packets) передають частини даних з одного компонента в інший. Практично все в ядрі використовує IRP, і кожен об'єкт пристрою має свою власну таблицю функцій, яку можна підключити: DKOM (Direct Kernel Object Manipulation).
- IAT (Import Address Table) корисний для вирішення залежностей. Можливо підключити цю таблицю, щоб перехопити код, який буде викликаний.
- EAT (Export Address Table) Хуки. Ці хуки можна робити з userland. Мета полягає в тому, щоб підключити експортовані функції DLL.
- Inline Hooks: Цей тип важко досягти. Це передбачає модифікацію коду самих функцій. Можливо, шляхом вставлення стрибка на початку цього.
Посилання
{{#include ../banners/hacktricks-training.md}}