Adversaries may use Base64-encoded PowerShell commands to establish a reverse TCP shell, leveraging the Nishang toolkit to exfiltrate data undetected. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential command-and-control activity and mitigate lateral movement risks.
KQL Query
imProcessCreate
| where Process has_any ("powershell.exe","powershell_ise.exe") and CommandLine contains "-e"
| mvexpand SS = split(CommandLine, " ")
| where SS matches regex "[A-Za-z0-9+/]{50,}[=]{0,2}"
| extend DecodeString = base64_decode_tostring(tostring(SS))
| extend FinalString = replace("\\0", "", DecodeString)
| where FinalString has "tcpclient" and FinalString contains "$" and (FinalString contains "invoke" or FinalString contains "iex")
| extend timestamp = TimeGenerated, AccountCustomEntity = User, HostCustomEntity = Dvc
id: 3a8e307b-5037-4182-a4e2-e76d99cecab8
name: Nishang Reverse TCP Shell in Base64 (Normalized Process Events)
description: |
'Looks for Base64-encoded commands associated with the Nishang reverse TCP shell.
Ref: https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcp.ps1'
requiredDataConnectors: []
tactics:
- Exfiltration
relevantTechniques:
- T1011
query: |
imProcessCreate
| where Process has_any ("powershell.exe","powershell_ise.exe") and CommandLine contains "-e"
| mvexpand SS = split(CommandLine, " ")
| where SS matches regex "[A-Za-z0-9+/]{50,}[=]{0,2}"
| extend DecodeString = base64_decode_tostring(tostring(SS))
| extend FinalString = replace("\\0", "", DecodeString)
| where FinalString has "tcpclient" and FinalString contains "$" and (FinalString contains "invoke" or FinalString contains "iex")
| extend timestamp = TimeGenerated, AccountCustomEntity = User, HostCustomEntity = Dvc
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AccountCustomEntity
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: HostCustomEntity
| Sentinel Table | Notes |
|---|---|
imProcessCreate | Ensure this data connector is enabled |
Scenario: A system administrator is using Invoke-PowerShellTcp to remotely manage a server via a legitimate PowerShell script.
Filter/Exclusion: Check for the presence of a known admin tool or script path, e.g., C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe with a known admin script location.
Scenario: A scheduled job runs a PowerShell script that includes Base64 encoding for data compression or encoding purposes, not for malicious intent.
Filter/Exclusion: Filter events where the process is associated with a known scheduled job or task scheduler, e.g., Task Scheduler or schtasks.exe.
Scenario: A security tool or script (e.g., PowerShell Universal or Pester) uses Base64 encoding to pass commands securely or for testing.
Filter/Exclusion: Exclude processes that are associated with known security or testing tools, e.g., PowerShell Universal or Pester scripts.
Scenario: A developer is using Invoke-PowerShellTcp to debug or test a remote PowerShell connection in a development environment.
Filter/Exclusion: Filter by user context (e.g., Development user group) or by process name associated with development tools, e.g., Visual Studio or PowerShell ISE.
Scenario: A system update or patching tool uses Base64 encoding to pass configuration data or scripts during deployment.
Filter/Exclusion: Exclude processes that are associated with known patching or configuration management tools, e.g., Chocolatey, Ansible, or SCCM.