This hunt targets the presence of VShell, a lightweight web shell often deployed by adversaries to maintain persistent access and execute commands within compromised Azure environments. Proactively hunting for these IOCs is critical because VShell can operate stealthily to facilitate lateral movement and data exfiltration, making early detection essential to disrupt the adversary’s foothold before it escalates.
Malware Family: VShell Total IOCs: 19 IOC Types: sha256_hash, ip:port
| Type | Value | Threat Type | First Seen | Confidence |
|---|---|---|---|---|
| ip:port | 45[.]192[.]213[.]11:80 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 8[.]137[.]35[.]137:18084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]61[.]104:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]61[.]110:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]61[.]113:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]61[.]122:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]60[.]117:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]60[.]122:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]60[.]111:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]60[.]115:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]60[.]109:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]60[.]105:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]59[.]109:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]60[.]101:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]59[.]100:8084 | botnet_cc | 2026-09-18 | 100% |
| ip:port | 154[.]91[.]58[.]122:8084 | botnet_cc | 2026-09-18 | 100% |
| sha256_hash | 9b45f364fea59f35833dbc1ed6e6bbcded8f2970a506d86e9e7303a56a09593c | payload | 2026-09-18 | 95% |
| sha256_hash | 63b0475bd58c48b4fe32f23515816550b6bb20455725b703e12d3428b3e7bedf | payload | 2026-09-18 | 95% |
| sha256_hash | 6f102146c656ffdc9a31fbbbeb8e319b00898e485f93b76c5ad04a964bfd4fdc | payload | 2026-09-18 | 95% |
// Hunt for network connections to known malicious IPs
// Source: ThreatFox - VShell
let malicious_ips = dynamic(["45.192.213.11", "154.91.60.117", "154.91.60.115", "154.91.60.109", "154.91.59.100", "8.137.35.137", "154.91.61.122", "154.91.60.105", "154.91.60.101", "154.91.61.104", "154.91.60.122", "154.91.61.113", "154.91.59.109", "154.91.58.122", "154.91.60.111", "154.91.61.110"]);
CommonSecurityLog
| where DestinationIP in (malicious_ips) or SourceIP in (malicious_ips)
| project TimeGenerated, SourceIP, DestinationIP, DestinationPort, DeviceAction, Activity
| order by TimeGenerated desc
// Hunt in Defender for Endpoint network events
let malicious_ips = dynamic(["45.192.213.11", "154.91.60.117", "154.91.60.115", "154.91.60.109", "154.91.59.100", "8.137.35.137", "154.91.61.122", "154.91.60.105", "154.91.60.101", "154.91.61.104", "154.91.60.122", "154.91.61.113", "154.91.59.109", "154.91.58.122", "154.91.60.111", "154.91.61.110"]);
DeviceNetworkEvents
| where RemoteIP in (malicious_ips)
| project Timestamp, DeviceName, RemoteIP, RemotePort, InitiatingProcessFileName, ActionType
| order by Timestamp desc
// Hunt for files matching known malicious hashes
// Source: ThreatFox - VShell
let malicious_hashes = dynamic(["9b45f364fea59f35833dbc1ed6e6bbcded8f2970a506d86e9e7303a56a09593c", "63b0475bd58c48b4fe32f23515816550b6bb20455725b703e12d3428b3e7bedf", "6f102146c656ffdc9a31fbbbeb8e319b00898e485f93b76c5ad04a964bfd4fdc"]);
DeviceFileEvents
| where SHA256 in (malicious_hashes) or SHA1 in (malicious_hashes) or MD5 in (malicious_hashes)
| project Timestamp, DeviceName, FileName, FolderPath, SHA256, InitiatingProcessFileName
| order by Timestamp desc
| Sentinel Table | Notes |
|---|---|
CommonSecurityLog | Ensure this data connector is enabled |
DeviceFileEvents | Ensure this data connector is enabled |
DeviceNetworkEvents | Ensure this data connector is enabled |
rsync or a CI/CD pipeline.
/var/www/html/, /opt/app/) and the process creating the file is a known deployment tool (e.g., ansible, jenkins-agent, git).npm, pip, composer, apt-get) and the file is located in a standard plugin/module directory (e.g., /wp-content/plugins/, /var/lib/jenkins/plugins/).cron job or Task Scheduler task runs a script that copies a backup archive or a shared library folder containing a VShell file (perhaps from a test environment or a shared NAS) to a staging or development server.
crond, taskeng.exe) and the destination path is a designated backup or staging directory (e.g., /backups/, /staging/).