Reverse TCP shell in PowerShell for fun. Made in spring 2020 with inspiration from (and a few fixes to) samratashok/nishang Invoke-PowerShellTcp.ps1 and PoweShell: Encrypt TCP Client-Server Traffic with a self-signed X509 Certificate
Some of these defenses come from MITRE ATT&CK T1059.001 - have a look at the Mitigations and Detection sections. If you cannot deploy company wide, deploying defenses on just 20% of your clients reduces the risk probability of ~20%.
- PowerShell
- Enforce PowerShell Constrained Language Mode.
- Configure this with a Computer Policy, not a User Policy which can be overriden by an attacker.
- Can be configured with AppLocker or Windows Defender Application Control.
- Set PowerShell execution policy to execute only signed scripts.
- Remove PowerShell version 1 & 2 from systems where not needed (rarely needed) - these versions bypass AMSI malware detection and bypass Constrained Language Mode.
- Prevent PowerShell.exe execution completely with e.g. AppLocker or Windows Defender Application Control.
- Be aware bypasses of above exist, but not all threat actors use bypasses, the probability is therefore still reduced.
- Enforce PowerShell Constrained Language Mode.
- Logging
- Preventing malware execution cannot be the ultimate goal, logging is in place is key when you're attacked.
- Enable PowerShell logging
- Three logs exist, all should be collected: Transcript, Script Block, and Module logging.
- Windows PowerShell Logging Cheat Sheet
- Log process creation events with e.g. Sysmon
- Centrally collect, and if possible alert, on the logs, e.g. with ELK Stack.
- If this seems like a big task, at least ensure logging is enabled and client log retention is reasonable (90+ days).
- Log DNS requests from DNS server logs, and from Windows logs with e.g. Sysmon
- Network
- Only allow outgoing/egress network traffic on specicically allowed ports, an example is only allowing egress port 80 and 443 from clients, and egress port 53 from DNS servers. Block anything else.
If I were to implement the least amount of safeguards with mimimum required effort, I would focus on:
- PowerShell Constrained Language Mode
- Removing PowerShell version 1 & 2
- Enabling PowerShell logging
Basic TCP reverse shell with no encryption.
An extension of the basic shell to:
- Fetch C2 IP and port via DNS over HTTPS (e.g. 'powershell-reverse-shell.demo.example.com' would need an A-record: 127.0.0.1 and TXT-record: 13337)
- Encrypt C2 communication (see Netcat bullet in Listener tips section below)
- Ensure the send buffer of your listener has enough bytes for your commands.
- On Windows some listeners are:
- PowerCat is LOTL and has a send buffer of 65536 bytes (same as my tool)
- Nmap's Ncat has an unmodifiable send buffer of 512 bytes
- .\ncat.exe -lvnp 13337
- Use -ssl flag to listen for TLS with self-signed random certificate: .\ncat.exe --ssl -lvnp 13337
- Netcat has an unmodifiable buffer of 4096 bytes.
- .\netcat64.exe -lvnp 13337