{
	"id": "6f4e60e1-0728-4cff-959b-dd2d8405c3cf",
	"created_at": "2026-04-29T02:21:07.522028Z",
	"updated_at": "2026-04-29T08:22:53.628844Z",
	"deleted_at": null,
	"sha1_hash": "a9a9c8dda8962cb6769cb1d9df833e2c541423a0",
	"title": "Detecting Parent PID Spoofing - F-Secure Blog",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 757153,
	"plain_text": "Detecting Parent PID Spoofing - F-Secure Blog\r\nBy 21.12.18 8 min. read\r\nPublished: 2018-12-21 · Archived: 2026-04-29 02:04:03 UTC\r\nOne of the most useful techniques hunt teams can use for detecting anomalous activity is the analysis of parent-child process relationships. However, more capable adversaries can bypass this using Parent PID (PPID) Spoofing\r\nallowing the execution of a malicious process from an arbitrary parent process. While this technique itself is not\r\nnew, having been covered by Cobalt Strike [1] and Didier Stevens [2] [3], very little research has been done in\r\ndetecting such attacks.\r\nIn this blog, we will explore how this technique works and how defenders can utilize Event Tracing for Windows\r\n(ETW) to detect this technique. We’ll also release a proof of concept PowerShell script to perform PPID spoofing\r\nand DLL injection, as well as a Python script that makes use of the pywintrace [8] library to detect this activity.\r\nWhy spoof in the first place?\r\nIn the past attackers were often able to move through networks undetected, but with the rise of EDR and threat\r\nhunting the tables have started to turn. The use of parent-child process analysis in particular has been a useful\r\ntechnique in detecting anomalous activity generated during nearly every phase of a kill chain.\r\nSome examples we use at Countercept:\r\n– Macro payload delivery – WinWord spawning processes\r\n– JS/VBS C# payload delivery – cscript spawning csc\r\n– Lateral movement – services/wmiprvse spawning new processes\r\nThis has pushed attackers to re-evaluate their approach and look at techniques like PPID spoofing in order to\r\nbypass modern defensive teams.\r\nSpoofing via CreateProcessA\r\nThere are a number of different ways to spoof process parents. In this post we’re going to focus on one of the\r\nsimplest and most commonly used techniques involving the API call CreateProcessA.\r\nCreateProcessA, unsurprisingly, lets users create new processes and by default, processes will be created with\r\ntheir inherited parent. However, this function also supports a parameter called “lpStartupInfo” where you can\r\nessentially define the parent process you want to use. This feature was first introduced in Windows Vista with the\r\naddition of UAC in order to correctly set parents.\r\nhttps://web.archive.org/web/20200726110643/https://blog.f-secure.com/detecting-parent-pid-spoofing/\r\nPage 1 of 9\n\nFigure 1\r\nAt a deeper technical level, the lpStartupInfo parameter points to a STARTUPINFOEX structure [5].This structure\r\ncontains an lpAttributeList and using UpdateProcThreadAttribute you can set the process parent via the\r\n“PROC_THREAD_ATTRIBUTE_PARENT_PROCESS” attribute.\r\nFigure 2\r\nAs an aside, this approach can also be used for privilege escalation. The documentation alludes to this stating that\r\n“Attributes inherited from the specified process include handles, the device map, processor affinity, priority,\r\nquotas, the process token and job object.” Adam Chester has a blog that demonstrates how this can be abused to\r\nget SYSTEM in Windows [6].\r\nHave I lied to my parents?\r\nOne of the most common ways to gain a foothold on a network is using a malicious macro document. Many\r\npayloads will often launch new processes, such as cmd, PowerShell, regsvr32 or certutil; Figure 3 shows an\r\nexample of this with rundll32 spawning from winword. However, this behavior is relatively anomalous and can\r\neasily be detected by most modern blue-teams.\r\nhttps://web.archive.org/web/20200726110643/https://blog.f-secure.com/detecting-parent-pid-spoofing/\r\nPage 2 of 9\n\nFigure 3\r\nTo overcome this issue, an attacker could instead use a VBS macro implementation of the CreateProcessA\r\ntechnique to launch a payload from an expected parent process (e.g. Explorer launching cmd) to blend in with the\r\nenvironment. Figure 4 gives a glimpse into how this could be implemented.\r\nFigure 4\r\nWe won’t be releasing this VBS code; however, more information can be found here [7].\r\nBut, can we take this even further to avoid common Windows utilities completely? One option would be to use\r\nsome form of DLL or memory injection to load a payload within an already running process.\r\nTo illustrate this we created a PowerShell script based on code from Didier Stevens [3]  that can be used to create\r\na process with a spoofed parent and then inject a DLL within it.\r\n# ppid spoofing and process spoofing happening now. $result1 =\r\n[Kernel32]::InitializeProcThreadAttributeList([IntPtr]::Zero, 1, 0, [ref]$lpSize) $sInfoEx.lpAttributeList =\r\n[System.Runtime.InteropServices.Marshal]::AllocHGlobal($lpSize) $result1 =\r\n[Kernel32]::InitializeProcThreadAttributeList($sInfoEx.lpAttributeList, 1, 0, [ref]$lpSize) $result1 =\r\n[Kernel32]::UpdateProcThreadAttribute($sInfoEx.lpAttributeList, 0, 0x00020000, #\r\nPROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000 $lpValue, [IntPtr]::Size, [IntPtr]::Zero,\r\n[IntPtr]::Zero) $result1 = [Kernel32]::CreateProcess($spawnTo, [IntPtr]::Zero, [ref]$SecAttr, [ref]$SecAttr, 0,\r\n0x08080004, #EXTENDED_STARTUPINFO_PRESENT | CREATE_NO_WINDOW | CREATE_SUSPENDED\r\nhttps://web.archive.org/web/20200726110643/https://blog.f-secure.com/detecting-parent-pid-spoofing/\r\nPage 3 of 9\n\n# 0x00080010, # EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE (This will show the\r\nwindow of the process) [IntPtr]::Zero, $GetCurrentPath, [ref] $sInfoEx, [ref] $pInfo)\r\nFigure 5\r\n# Load and execute dll into spoofed process. $loadLibAddress =\r\n[Kernel32]::GetProcAddress([Kernel32]::GetModuleHandle(“kernel32.dll”), “LoadLibraryA”) $lpBaseAddress =\r\n[Kernel32]::VirtualAllocEx($pInfo.hProcess, 0, $dllPath.Length, 0x00003000, 0x4) $result1 =\r\n[Kernel32]::WriteProcessMemory($pInfo.hProcess, $lpBaseAddress, (New-Object\r\n“System.Text.ASCIIEncoding”).GetBytes($dllPath), $dllPath.Length, [ref]0) # $result1 =\r\n[Kernel32]::VirtualProtectEx($pInfo.hProcess, $lpBaseAddress, $dllPath.Length, 0x20, [ref]0) $result1 =\r\n[Kernel32]::CreateRemoteThread($pInfo.hProcess, 0, 0, $loadLibAddress, $lpBaseAddress, 0, 0)\r\nFigure 6\r\nTo demonstrate how such a script could be used to hide activity we looked at commonly running processes on\r\nWindows 10. One quite common legitimate relationship we saw was “svchost.exe” launching\r\n“RuntimeBroker.exe” (Figure 7).\r\nFigure 7\r\nhttps://web.archive.org/web/20200726110643/https://blog.f-secure.com/detecting-parent-pid-spoofing/\r\nPage 4 of 9\n\nUsing the PowerShell script we were able to mimic this activity and forcibly spawn a legitimate\r\n“RuntimeBroker.exe” from “svchost.exe”, then inject and execute our DLL payload.\r\nFigure 8\r\nThis vector shows how such techniques can potentially bypass detection rules focused on parent-child\r\nrelationships.\r\nHow can we find the liar?\r\nIn the previous section we showed that the CreateProcessA technique can spoof parent IDs and from a blue team\r\nperspective if you queried running processes with something like Task Manager or Process Explorer you would\r\nsee the spoofed IDs. But is there some way to find out the real IDs?\r\nOne of the best forensic data sources in Windows is Event Tracing for Windows (ETW). ETW provides a real-time stream of data about events occurring on a system and is something we use within our endpoint agent at\r\nCountercept.\r\nThe Microsoft-Windows-Kernel-Process provider in particular can give some useful insights into process creation\r\nand can help us detect the process ID spoofing. In the example below you’ll see how “rundll32.exe” (PID 5180) is\r\nbeing spawned from “winword.exe” (PID 9224) (Figure 9).\r\nhttps://web.archive.org/web/20200726110643/https://blog.f-secure.com/detecting-parent-pid-spoofing/\r\nPage 5 of 9\n\nFigure 9\r\nLooking into the ETW data collected (Figure 10) you’ll see there are multiple ProcessId fields, including the\r\nEventHeader ProcessId, as well as the actual event ProcessID and ParentProcessID. Although this is somewhat\r\nconfusing, reading through the MSDN documentation, we find that the EventHeader ProcessId actually identifies\r\nthe process that generated the event – i.e. the parent.\r\nFigure 10 \r\nAnd in this legitimate example you’ll notice that the EventHeader ProcessId and ParentProcessId correctly match.\r\nIn this second example we executed our malicious PowerShell script and spawned a “RuntimeBroker.exe” (PID\r\n4976) from “svchost.exe” (PID 4652).\r\nhttps://web.archive.org/web/20200726110643/https://blog.f-secure.com/detecting-parent-pid-spoofing/\r\nPage 6 of 9\n\nFigure 11\r\nAs before, we can see ETW generated a process event (Figure 12); however, this time the EventHeader ProcessId\r\nand ParentProcessID are different. And in fact the EventHeader ProcessId shows the real parent, which is\r\n“winword.exe” (PID 9224). We’ve just caught someone performing ParentPID spoofing!\r\nFigure 12\r\nHowever, as always in threat detection, things aren’t that simple and if you attempt to do this at scale you’re going\r\nto see false positives from legitimate spoofing. One common example is User Account Control (UAC), which is\r\nused to elevate process privileges. In Windows 10 when UAC executes, the Application Information service\r\n(through svchost) is used to launch the elevated process, but will then spoof the parent to show the original caller.\r\nhttps://web.archive.org/web/20200726110643/https://blog.f-secure.com/detecting-parent-pid-spoofing/\r\nPage 7 of 9\n\nThe example below shows how an elevated cmd.exe will show explorer.exe as the parent, when in fact it was\r\nsvchost.exe.\r\nFigure 13\r\nAnother false positive we saw involved crash handling with WerFault. In the example below, when MicrosoftEdge\r\ncrashed svchost was used to launch WerFault.exe and the parent was spoofed as MicrosoftEdge.exe.\r\nFigure 14\r\nFor testing purposes we created a simple proof-of-concept Python script that used pywintrace to log events from\r\nETW, compare PIDs, and then filter results to remove false positives (Figure 15).\r\nFigure 15\r\nThe code for the PowerShell spoofing script, as well as the detection script, can be found on our Github.\r\nConclusion\r\nIn this post we’ve shown how attackers can abuse legitimate Windows functions to fool blue teamers and\r\npotentially bypass detection techniques based on parent-child relationships.\r\nFrom a defensive perspective though, we’ve shown how analysis of ETW process events can easily highlight\r\nanomalous parent spoofing and help discover the true origin of a process. As always this research shows how\r\nessential it is for defenders to push the boundaries of current technology and stay one step ahead of attackers at all\r\ntimes.\r\nReferences\r\n[1] https://blog.cobaltstrike.com/2017/05/23/cobalt-strike-3-8-whos-your-daddy/\r\nhttps://web.archive.org/web/20200726110643/https://blog.f-secure.com/detecting-parent-pid-spoofing/\r\nPage 8 of 9\n\n[2] https://blog.didierstevens.com/2017/03/20/\r\n[3] https://blog.didierstevens.com/2009/11/22/quickpost-selectmyparent-or-playing-with-the-windows-process-tree/\r\n[4] https://msdn.microsoft.com/en-us/library/windows/desktop/aa363759(v=vs.85).aspx\r\n[5] https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_startupinfoexa\r\n[6] https://blog.xpnsec.com/becoming-system/\r\n[7] http://www.pwncode.club/2018/08/macro-used-to-spoof-parent-process.html\r\n[8] https://github.com/fireeye/pywintrace\r\nSource: https://web.archive.org/web/20200726110643/https://blog.f-secure.com/detecting-parent-pid-spoofing/\r\nhttps://web.archive.org/web/20200726110643/https://blog.f-secure.com/detecting-parent-pid-spoofing/\r\nPage 9 of 9",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://web.archive.org/web/20200726110643/https://blog.f-secure.com/detecting-parent-pid-spoofing/"
	],
	"report_names": [
		"detecting-parent-pid-spoofing"
	],
	"threat_actors": [],
	"ts_created_at": 1777429267,
	"ts_updated_at": 1777450973,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/a9a9c8dda8962cb6769cb1d9df833e2c541423a0.pdf",
		"text": "https://archive.orkl.eu/a9a9c8dda8962cb6769cb1d9df833e2c541423a0.txt",
		"img": "https://archive.orkl.eu/a9a9c8dda8962cb6769cb1d9df833e2c541423a0.jpg"
	}
}