{
	"id": "31100329-57d1-4cb4-9289-a91baf303f42",
	"created_at": "2026-04-06T00:17:24.229038Z",
	"updated_at": "2026-04-10T03:20:45.961412Z",
	"deleted_at": null,
	"sha1_hash": "b287bfe3bc1b3f6ee47136d38ff0e0a9aeb9357d",
	"title": "How DopplePaymer Hunts \u0026 Kills Windows Processes | CrowdStrike",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 833315,
	"plain_text": "How DopplePaymer Hunts \u0026 Kills Windows Processes |\r\nCrowdStrike\r\nBy Shaun Hurley\r\nArchived: 2026-04-05 14:21:39 UTC\r\nIn a July 2019 blog post about DoppelPaymer, Crowdstrike Intelligence reported that ProcessHacker was being\r\nhijacked to kill a list of targeted processes and gain access, delivering a “critical hit.” Although the blog is now a\r\ncouple of years old, the hijacking technique is interesting enough to dig into its implementation. The hijack occurs\r\nwhen ProcessHacker loads a malicious stager DLL designed to exploit legitimate behavior. Once the process has\r\nbeen hijacked, the stager DLL is able to terminate processes, including those protected by Protected Process Light\r\n(PPL). To accomplish this task, it leverages ProcessHacker’s kernel driver, KProcessHacker, that has been\r\nregistered under the service name KProcessHacker3. This blog delves into the details about how DoppelPaymer\r\nhijacks ProcessHacker and exploits KProcessHacker to kill a list of processes, including both antivirus (AV) and\r\nendpoint detection and response (EDR) applications.\r\nFigure 1. Architecture diagram to kill a target process\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 1 of 12\n\nLaunching Process Hacker\r\nTo start ProcessHacker, DoppelPaymer writes the ProcessHacker executable, the KProcessHacker driver, and the\r\nmalicious stager DLL into a subdirectory of %APPDATA% . Both the subdirectory name and the file names for the\r\nexecutable and driver are a unique string of alphanumeric characters. Once those two files have been written, one\r\nof the DLLs loaded by ProcessHacker has to be hijacked using a technique called “DLL search order hijacking.”\r\nDLL Search Order Hijacking\r\nSimilar to Dridex, DoppelPaymer uses DLL search order hijacking to exploit the DLL loading behavior for\r\nWindows processes. As the operating system PE loader loads a binary, it also needs to load the DLL files required\r\nfor the PE to function. By default, MS Windows has a specific path it takes when looking for the DLL files to\r\nload. Windows checks for Windows system DLLs in the same directory as the target binary before it checks the\r\nWindows system directories. A malicious process, in this case DoppelPaymer, can drop a malicious version of a\r\nDLL in that directory and it will be loaded by the target application. To determine which DLL to hijack,\r\nDoppelPaymer walks the module name list in the Import Address Table (IAT) of the ProcessHacker binary. Each\r\nname is hashed with a CRC32 algorithm and compared against a hardcoded list of hashes (Table 1), and if a match\r\noccurs, the name is added to a list data structure. A random number generator is used to pick one of the three\r\nnames out of the list.\r\nCRC32 Filename\r\n0xd8946922 VERSION.dll\r\n0x020da855 WINSTA.dll\r\n0x3c55abe2 UxTheme.dll\r\nTable 1. Mapping DLL name to CRC32 hash for search order hijacking\r\nOnce a DLL has been picked, the legitimate Windows version of the DLL is read into a memory buffer. This DLL\r\nis used as a template to build the malicious stager DLL. The file is written to the same subdirectory as the\r\nProcessHacker executable with the same file name as the hijacked DLL.\r\nCreating the Process\r\nDoppelPaymer passes two arguments to the ProcessHacker process: The first is the name of the\r\nKProcessHacker.sys driver, and the second is an integer that will be used for inter-process communication (IPC)\r\nbetween the DoppelPaymer and ProcessHacker processes. C:\\Users\\ducksoup\\AppData\\Roaming\\M28fPT\\ibOLR\r\n2LEQV0 161604546\r\nFigure 2. ProcessHacker command line\r\nSetting Up the IPC Objects\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 2 of 12\n\nEvent handlers and section objects are used to communicate between the two processes. These objects allow\r\nDoppelPaymer to communicate directly with the stager DLL that is loaded inside the ProcessHacker process. The\r\nexample handle values in Table 2 are used throughout the rest of this post when referencing these objects. These\r\nvalues vary with different executions of DoppelPaymer.\r\nObject Type Handle Value Purpose\r\nEvent Object 0x120 Notify data in queue\r\nEvent Object 0x11C Notify data processed\r\nSection Object 0x124 Queue used to send process information to the stager DLL\r\nSection Object 0x128 Contains the three events\r\nTable 2. IPC handles with concrete values from testing\r\nFor each section object, a view is mapped into process memory, so that DoppelPaymer is able to write data to the\r\nobjects. The 0x124 object is the queue where the process information of the processes to terminate will be\r\nwritten. The other object, 0x128 , will contain the handle values of the other three objects: 0x120 , 0x11C and\r\n0x124 . For the stager DLL to access those three handles, DoppelPaymer needs to provide the 0x128 handle\r\nvalue to ProcessHacker. Sticking with the example command line in Figure 1, the second argument to\r\nProcessHacker is the section object handle 0x128 XORd against the same constant value (unique per binary)\r\nused throughout the lifetime of DoppelPaymer. For this binary, the constant is 0x9a1e2ea . XORing 0x128 with\r\n0x9a1e2ea gives us the decimal value 161604546 . After these IPC objects are created, and the second argument\r\nto ProcessHacker has been generated, CreateProcessW is called to launch ProcessHacker. Now DoppelPaymer\r\nhas to wait for the stager DLL to initialize inside of the ProcessHacker process prior to establishing inter process\r\ncommunication. NtWaitForSingleObject is called for event handle 0x120 , and DoppelPaymer waits for that\r\nevent to be signaled.\r\nLoading the Stager DLL\r\nThe stager DLL is loaded into ProcessHacker. Several initialization steps have to occur before the stager DLL can\r\nleverage KProcessHacker to kill processes:\r\nProcessHacker’s entry point needs to be modified to ensure that none of the startup routines for\r\nProcessHacker execute\r\nThe KProcessHacker service has to be initialized\r\nProcessHacker and the stager DLL have to be verified as a valid client for the KProcessHacker service\r\nThe IPC objects necessary for DoppelPaymer to communicate with the stager DLL need to be duplicated\r\nAfter all four of these steps have been successfully completed, the stager DLL can start killing target processes\r\nprovided by DoppelPaymer.\r\nReaching ProcessHacker’s Code Entrypoint Address\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 3 of 12\n\nOnce the process starts to load the stager DLL, the malicious code will start to execute, but if control isn’t passed\r\nback to the OS to finish loading ProcessHacker, it will not be usable by DoppelPaymer. The loading process\r\ncompletes when the entry-point address of ProcessHacker is reached. To determine when the entry point is\r\nreached, the stager DLL will overwrite the entry point of ProcessHacker with the code in Figure 3.\r\n.rdata:10006120 mov eax, 94A351BBh\r\n.rdata:10006125 push 0\r\n.rdata:10006127 push 8FF4B5ACh ; Event handle\r\n.rdata:1000612C call eax ; NtSetEvent\r\n.rdata:1000612E loc_1000612E:\r\n.rdata:1000612E push 0\r\n.rdata:10006130 push 1\r\n.rdata:10006132 push 0FFFFFFFEh\r\n.rdata:10006134 mov eax, 1DCB264Eh\r\n.rdata:10006139 call eax ; NtWaitForSingleObject\r\n.rdata:1000613B jmp short loc_1000612E\r\nFigure 3. Entrypoint template code\r\nThis code is copied from the .rdata section of the stager DLL and is modified to represent the current process\r\nenvironment. Placeholders exist for the event handle and for the two Windows API functions used for the\r\nnotification routines. The event used to signal that the entry point has been reached is created and copied to the\r\n8FF4B5ACh placeholder. The addresses for NtSetHandle and NtWaitForSingleObject are resolved and written\r\nto 94A351BBh and 1DCB264Eh , respectively. Once the template is complete, VirtualProtect is called to set\r\nProcessHacker’s entry point to write-able, the entry point code is overwritten, and the original protection restored.\r\nThe new entry-point code, in C, is shown in Figure 4.\r\n//\r\n// Signal entrypoint reached\r\n//\r\nNtSetEvent(entryPointReachedHdl, NULL);\r\nwhile (1) {\r\n //\r\n // Entrypoint thread will loop indefinitely\r\n //\r\n NtWaitForSingleObject(-2, 1, NULL);\r\n}\r\nFigure 4. ProcessHacker entry point infinite loop\r\nThe code in Figure 4 signals to the stager DLL thread that the entry point has been reached, and it continues in an\r\ninfinite loop that calls NtWaitForSingleObject . Not only will this infinite loop let the stager DLL know when the\r\nentry point is reached, it also prevents ProcessHacker from interfering with the stager DLL and prevents the\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 4 of 12\n\nProcessHacker window from being displayed. Now that the entry point is overwritten, the stager DLL spawns a\r\nnew thread that initializes the KProcessHacker driver and sets the stage for killing AV processes. First, the thread\r\ncalls NtWaitForSingleObject and waits for the entry point to be reached.\r\nInitializing the KProcessHackerDriver\r\nThe “entry point reached” event is signaled, and this thread can continue and initialize the KProcessHacker driver.\r\nThe stager DLL has to create the KProcessHacker service and register the driver. The code to accomplish this task\r\nis essentially the same code used by the two ProcessHacker functions that can be found in the kph.c source code:\r\nKphConnect2Ex\r\nKphConnect\r\nThe code opens the service control manager in Windows and creates the KProcessHacker service under the name\r\nKProcessHacker3 . The stager DLL passes the following arguments to the CreateService procedure:\r\nCreateService(\r\n scmHandle,\r\n L”kprocesshacker3”,\r\n L”kprocesshacker3”,\r\n SERVICE_ALL_ACCESS,\r\n SERVICE_KERNEL_DRIVER,\r\n SERVICE_DEMAND_START,\r\n SERVICE_ERROR_IGNORE,\r\n //\r\n // Path to kprocesshacker.sys driver file\r\n //\r\n L”C:\\Users\\ducksoup\\AppData\\Roaming\\M28fPT\\2LEQV0”,\r\n NULL,\r\n NULL,\r\n NULL,\r\n NULL,\r\n L\"\"\r\n);\r\nThe KProcessHacker service has been created and started and is ready to receive requests from the client\r\nProcessHacker process. Before a client can make a request to the service, it needs to be verified.\r\nKernel Verification of the KProcessHacker Client\r\nEvery time an IOCTL is sent to the KProcessHacker service, it is checked to ensure that the caller is a verified\r\nKProcessHacker client that is allowed to communicate with the service. All attempts to communicate with\r\nKProcessHacker are validated using an IOCTL request key that is generated by sending a KPH_RETRIEVEKEY\r\nrequest from the user-mode process. The importance of this key is discussed in the “KProcessHacker IOCTL\r\nRequest Keys and APC'' section below. Attached to the KPH_RETRIEVEKEY request is an Asynchronous Procedure\r\nCall (APC) routine, KphpWithKeyApcRoutine , which will be executed upon completion. KProcessHacker\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 5 of 12\n\ninitializes a KPH_CLIENT structure that needs to be populated with the correct values to distinguish the caller as\r\nverified. This initialization occurs when the stager DLL opens a handle to the KProcessHacker driver file. As this\r\noccurs, the Windows kernel sends an IRP_MJ_CREATE request to the KProcessHacker driver, and the handler,\r\nKphDispatchCreate , is called.\r\ntypedef struct _KPH_CLIENT\r\n{\r\n struct\r\n {\r\n ULONG VerificationPerformed : 1;\r\n ULONG VerificationSucceeded : 1;\r\n ULONG KeysGenerated : 1;\r\n ULONG SpareBits : 29;\r\n };\r\n FAST_MUTEX StateMutex;\r\n NTSTATUS VerificationStatus;\r\n PVOID VerifiedProcess; // EPROCESS (for equality checking only - do not access contents)\r\n HANDLE VerifiedProcessId;\r\n PVOID VerifiedRangeBase;\r\n SIZE_T VerifiedRangeSize;\r\n // Level 1 and 2 secret keys\r\n FAST_MUTEX KeyBackoffMutex;\r\n KPH_KEY L1Key;\r\n KPH_KEY L2Key;\r\n} KPH_CLIENT, *PKPH_CLIENT;\r\nFigure 5. KPH_CLIENT data structure from the Kph.h source code\r\nThis KphDispatchCreate function allocates kernel memory to store this data structure. Due to it being kernel\r\nmemory, the stager DLL is unable to manipulate the data structure from user mode, even from inside the\r\nProcessHacker process. Instead, the stager DLL can send a KPH_VERIFYCLIENT IOCTL request to the driver. The\r\nhandler function, KphVerifyClient , for this IOCTL will set the necessary fields once the client is verified.\r\nIOCTL Request Name Description\r\n0x99992007 KPH_VERIFYCLIENT Verify the client process\r\n0x999200B KPH_RETRIEVEKEY Retrieve the verification key\r\n0x999920CB KPH_OPENPROCESS Opens a process\r\n0x999920DF KPH_TERMINATEPROCESS Terminate a process\r\nTable 3. KProcessHacker IOCTLs used by the stager DLL\r\nThe KphVerifyClient function first checks to see if verification has already occurred by checking the boolean\r\nvalue, Client-\u003eVerificationPerformed . If this field is false, the following checks are made by KProcessHacker:\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 6 of 12\n\n1. Verify that the start address of the APC routine is a user-space address and not a kernel address\r\n2. Compare the process image file name against the mapped PE image name where the APC routine resides\r\n3. Verify that the APC routine address came from an area of memory that is type MEM_IMAGE and in a\r\nMEM_COMMIT state\r\n1. These states ensure that the memory where the APC routine resides is both committed memory and\r\na mapped view of an image section\r\n4. Verify the PE file backing the process making the request by hashing the file’s contents and comparing it\r\nagainst a digital signature:\r\n1. The 256-bit Elliptic Curve Digital Signature is a hash of a known valid ProcessHacker PE file that\r\nwas signed using KProcessHacker’s private key\r\n2. The digital signature is decoded from the stager DLL and sent with the KPH_VERIFYCLIENT request\r\n3. The contents of the file backing the process that made the request is hashed using SHA-256\r\n4. The signed hash is decrypted using KProcessHacker’s public key\r\n5. If the decrypted signed hash and the generated hash match, then the PE file is verified\r\nOnce verification passes, the code in Figure 6 is executed to populate several fields that will be used for\r\nverification when the stager DLL attempts to send the KPH_OPENPROCESS and KPH_TERMINATEPROCESS IOCTL\r\nrequests.\r\nstatus = KphVerifyFile(processFileName, Signature, SignatureSize);\r\nif (NT_SUCCESS(status))\r\n{\r\n Client-\u003eVerifiedProcess = PsGetCurrentProcess();\r\n Client-\u003eVerifiedProcessId = PsGetCurrentProcessId();\r\n Client-\u003eVerifiedRangeBase = memoryBasicInfo.BaseAddress;\r\n Client-\u003eVerifiedRangeSize = memoryBasicInfo.RegionSize;\r\n}\r\nClient-\u003eVerificationStatus = status;\r\nClient-\u003eVerificationSucceeded = NT_SUCCESS(status);\r\nClient-\u003eVerificationPerformed = TRUE;\r\nFigure 6. KphVerifyClient sets verified fields of a KPH_CLIENT structure\r\nThe hijacked ProcessHacker process is now a verified client of the KProcessHacker service. A new thread is\r\nspawned to duplicate the IPC objects from DoppelPaymer into the ProcessHacker process space.\r\nDuplicating the IPC Objects Inside ProcessHacker\r\nFrom Figure 2, the second argument, 161604546 , is decoded, yielding the handle ID of 0x128 . The section\r\nobject that this handle references is duplicated in the ProcessHacker process. The section object is duplicated with\r\nthe same access rights as the original. Duplicating objects generate new handle values, but to keep it simple, this\r\npost reuses the original values.\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 7 of 12\n\n//\r\n// Duplicating DoppelPaymer’s section object handle.\r\n//\r\nNtDuplicateObject(\r\n DoppelPaymerProcHandle, // Process handle for source process\r\n 0x128, // Handle for the source section object\r\n 0xFFFFFFFF, // ProcessHacker process handle\r\n duplicateHdl, // New section object handle\r\n NULL,\r\n NULL,\r\n DUPLICATE_SAME_ACCESS\r\n);\r\nA view of the duplicated section object is mapped to local process memory using NtMapViewOfSection . It\r\ncontains the same handles from Table 2 that were written to the section object in the DoppelPaymer process:\r\n0x120 , 0x11C and 0x124 . Each of these handles is duplicated, and a view of the 0x124 section object is\r\nmapped into ProcessHacker’s process memory. DoppelPaymer is now in a state where it is waiting for an event to\r\nbe signaled that notifies it that the stager DLL has completed initialization and is ready to process requests in the\r\nqueue. This notification is sent by calling NtSetEvent with the 0x120 event handle, and the stager DLL waits\r\nfor requests.\r\nKilling Blocklisted Applications\r\nOnce DoppelPaymer receives the signaled event, it starts enumerating both service and process names, and hashes\r\nthem with the CRC32 algorithm. These hashes are compared against a list of blocklisted hashes in\r\nDoppelPaymer’s process memory. The complete list was covered in the previous DoppelPaymer blog post. This\r\nsection discusses what happens when an application matches one of the blocklisted items. DoppelPaymer writes\r\nthe process ID associated with the service, along with a command to the mapped section object, 0x124 . The\r\ncommand will tell the stager DLL which steps to take.\r\nAntiAV {\r\n +0x00 Command\r\n +0x08 Process ID\r\n +0x10 errorCodeResponse // Response code from ProcessHacker\r\n}\r\nFigure 7. Blocklisted process information written to IPC section\r\nProcess termination occurs in two steps: a process is opened, then it is killed. The first command sent, 1 , will tell\r\nthe stager DLL to open a handle to the process. Table 4 contains a list of valid commands.\r\nCommand Action\r\n0 Terminate ProcessHacker\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 8 of 12\n\n1 Open the process\r\n2 Kill the process\r\nOther value Invalid, wait for the next command\r\nTable 4. IPC handles with concrete values from testing\r\nThe command is written to the queue, along with the process ID, and DoppelPaymer signals the event to notify the\r\nstager DLL that data is in the queue. Once that event is signaled, it waits for a response.\r\nKProcessHacker IOCTL Request Keys and APC\r\nCertain IOCTL requests to the KProcessHacker service require the verification of an IOCTL request key. To\r\nensure that the key cannot be tampered with, the key is generated by the driver and stored in the KPH_CLIENT\r\nstructure. The following IOCTL requests require a key:\r\nKPH_OPENPROCESS\r\nKPH_OPENPROCESSTOKEN\r\nKPH_TERMINATEPROCESS\r\nKPH_READVIRTUALMEMORY\r\nKPH_OPENTHREAD\r\nPrior to making any of these requests, ProcessHacker has to send a KPH_RETRIEVEKEY request using\r\nNtDeviceIoControlFile . Along with this request, the user-mode address of an APC routine,\r\nKphpWithKeyApcRoutine , and the user-mode address of a function called by the APC are sent as parameters. This\r\nroutine to be called by the APC will end up making one of the IOCTL requests mentioned in the above bulleted\r\nlist.\r\nNtDeviceIoControlFile(\r\n PhKphHandle,\r\n NULL,\r\n KphpWithKeyApcRoutine, // Called after NtDeviceIoControlFile\r\n // returns\r\n NULL,\r\n \u0026context.Iosb, // Receives the status code\r\n KPH_RETRIEVEKEY, // IOCTL\r\n \u0026input, // Parameters passed to IOCTL\r\n sizeof(input),\r\n NULL,\r\n 0\r\n);\r\nThe KPH_RETRIEVEKEY request is handled by KphRetrieveKeyViaApc . Prior to generating the request key, several\r\nchecks are performed to ensure that the client (ProcessHacker, in this case) making the request is verified and that\r\nthe APC parameter is valid:\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 9 of 12\n\nEnsure the client has been verified by checking the KPH_CLIENT-\u003eVerificationSucceeded field\r\nEnsure that the process information for the client matches what was set during the verification process\r\nKPH_CLIENT-\u003eVerifiedProcess\r\nKPH_CLIENT-\u003eVerifiedProcessId\r\nEnsure that the instruction address of the APC routine falls within the executable section of the verified\r\nclient\r\nOnce those checks are passed, a request key is generated and stored in the KPH_CLIENT structure. This key will\r\nalso be passed as argument to the APC routine. So now, both the client and the server have independent copies of\r\nthe same request key. The APC routine, KphpWithKeyApcRoutine , executes. As noted earlier, the APC routine\r\nreceives a function pointer that will be used to execute a specific action (kill process, open process, etc.). To\r\nrestrict which requests can be made via this APC routine, it makes sure that only the following functions can be\r\ncalled from the APC:\r\nKphpGetL1KeyContinuation\r\nKphpOpenProcessContinuation\r\nKphpOpenProcessTokenContinuation\r\nKphpTerminateProcessContinuation\r\nKphpReadVirtualMemoryUnsafeContinuation\r\nKphpOpenThreadContinuation\r\nThis check prevents DLLs from being injected into ProcessHacker and leveraging the KphpWithKeyApcRoutine\r\nAPC as a method to execute its own routines under the guise of being a valid KPH_CLIENT . Once this check\r\npasses, the function passed to the APC is called and the client copy of the request key is passed to that function.\r\nBoth this check and the checks made in the KphRetrieveKeyViaApc procedure pose a challenge for the stager\r\nDLL. The author of the stager DLL scraps the original KphpWithKeyApcRoutine routine and passes their own\r\nAPC routine, StagerAPCRoutine . The code for this is written directly after ProcessHacker’s overwritten entry-point code. This bypasses both of the function pointer checks and passes the checks performed by\r\nKphRetrieveKeyViaApc .\r\n000000013f5b2f2c jmp cs:CallFunctionPointerRoutine\r\n000000013f5b2f3a push rax\r\n000000013f5b2f3b retn\r\nFigure 8. StagerAPCRoutine\r\nThe StagerAPCRoutine (Figure 8) shortcuts the entire process and jumps directly to a procedure,\r\nCallFunctionPointerRoutine , that calls the DLL stager versions of KphpOpenProcessContinuation and\r\nKphpTerminateProcessContinuation procedures and passes the client copy of the request key as a parameter.\r\nOpening a Process Handle\r\nAs outlined in the previous section, to open a process handle, a KPH_RETRIEVEKEY request is sent to the\r\nKProcessHacker service. Along with this request, the StagerAPCRoutine address and the address of the function\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 10 of 12\n\ncalled by the APC open a process, StagerOpenProcess . A new request key is generated, saved to KPH_CLIENT\r\nand passed to StagerAPCRoutine . Once everything has been validated, the StagerAPCRoutine calls\r\nStagerOpenProcess where a KPH_OPENPROCESS request is sent to the KProcessHacker service. Both the client\r\ncopy of the request key and the process ID of the target are sent with the request.\r\nFigure 9. Process diagram to open a process\r\nThe service handles this request by calling KpiOpenProcess . Before a handle to the process can be opened, the\r\nclient’s request key is validated by calling KphValidateKey , where the client copy of the key is compared against\r\nthe copy stored in KPH_CLIENT . If these match, a handle to the target process is opened.\r\nPsLookupProcessByProcessId is called to get a pointer to the process object in kernel memory. That pointer is\r\nused to open a handle to the object by calling ObOpenObjectByPointer . This handle can now be referenced by the\r\nstager DLL. The stager DLL signals the 0x120 event handle, notifying DoppelPaymer that a handle has\r\nsuccessfully been opened to the target process. Now the process can be killed.\r\nKilling a Process\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 11 of 12\n\nDoppelPaymer verifies that the process was successfully opened, and then takes the appropriate action. If an error\r\noccurred, it continues checking for blocklisted applications; otherwise, another notification is sent, this time with\r\nthe command 2 to terminate the process. Terminating a process follows the same procedure as opening a process\r\nwith one difference: The StagerKillProcess function pointer is passed to the StagerAPCRoutine . The\r\nStagerKillProcess function sends a KPH_TERMINATEPROCESS request to the KProcessHacker service. This is\r\nhandled by the KpiTerminateProcess kernel-mode function. The request key is validated before process\r\ntermination can occur. The target process is reopened to get a kernel handle, and ZwTerminateProcess is called to\r\nkill the process. Note that using this procedure ignores PPL, so even protected processes will be killed.\r\nConclusion\r\nDoppelPaymer’s usage of ProcessHacker to kill AV services is part of a larger trend of various actors leveraging\r\nlegitimate tools to disable AV/EDR functionality. DoppelPaymer’s method is a testament to how innovative\r\nmalware authors can be when it comes to neutralizing the defenses of their target. Many thanks to Bill Demirkapi\r\nfor helping to sort out how digital signature verification is used to validate the PE.\r\nAdditional Resources\r\nDiscover how CrowdStrike CROWDSTRIKE FALCON® INTELLIGENCE combines automated analysis\r\nwith human intelligence, enabling security teams, regardless of size or skill, to get ahead of the attacker’s\r\nnext move.\r\nFind out how to stop adversaries targeting your industry — schedule a free 1:1 intel briefing with a\r\nCrowdStrike threat intelligence expert today.\r\nLearn about the powerful, cloud-native CrowdStrike Falcon® platform by visiting the product webpage.\r\nGet a full-featured free trial of CrowdStrike Falcon® Prevent™ to see for yourself how true next-gen AV\r\nperforms against today’s most sophisticated threats.\r\nSource: https://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nhttps://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/\r\nPage 12 of 12",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE",
		"Malpedia"
	],
	"references": [
		"https://www.crowdstrike.com/blog/how-doppelpaymer-hunts-and-kills-windows-processes/"
	],
	"report_names": [
		"how-doppelpaymer-hunts-and-kills-windows-processes"
	],
	"threat_actors": [],
	"ts_created_at": 1775434644,
	"ts_updated_at": 1775791245,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/b287bfe3bc1b3f6ee47136d38ff0e0a9aeb9357d.pdf",
		"text": "https://archive.orkl.eu/b287bfe3bc1b3f6ee47136d38ff0e0a9aeb9357d.txt",
		"img": "https://archive.orkl.eu/b287bfe3bc1b3f6ee47136d38ff0e0a9aeb9357d.jpg"
	}
}