Introduction
A new Go-based botnet dubbed NadMesh has emerged in early July 2026, specifically targeting exposed AI services to harvest cloud credentials and Kubernetes tokens. According to threat intelligence, the botnet operator's dashboard claims the compromise of 3,811 unique AWS keys—a staggering figure that underscores the severity of this campaign.
NadMesh represents a paradigm shift in botnet operations: rather than exploiting unpatched vulnerabilities, it capitalizes on a fundamental operational failure—development teams standing up AI tools (ComfyUI, Ollama, n8n, Open WebUI, Langflow, Gradio) rapidly without securing them behind proper network controls. This "shadow AI" infrastructure has become a prime attack surface for credential theft.
Defenders need to act immediately. The botnet actively scans for these services using Shodan harvesting, and once credentials are extracted, the dwell time before cloud resource compromise is minimal. This is not a theoretical risk—active credential theft is occurring in production environments right now.
Technical Analysis
Affected Products and Platforms
NadMesh specifically targets the following AI/ML services commonly deployed in development and production environments:
| Service | Type | Default Port(s) |
|---|---|---|
| ComfyUI | Image Generation/UI | 8188 |
| Ollama | Local LLM Runner | 11434 |
| n8n | Workflow Automation | 5678 |
| Open WebUI | LLM Web Interface | 8080, 3000 |
| Langflow | Flow-based AI Apps | 7860 |
| Gradio | ML Model Interface | 7860, 7861 |
Attack Vector and Methodology
The NadMesh botnet operates through a sophisticated but operationally simple attack chain:
-
Discovery Phase: A Shodan harvester continuously populates the botnet's scan queue with IP addresses hosting the targeted AI services. The botnet specifically looks for services exposed to the public internet without authentication.
-
Credential Harvesting: Once an exposed service is identified, NadMesh attempts to:
- Extract environment variables containing AWS access keys, secret keys, and session tokens
- Locate and exfiltrate Kubernetes service account tokens (typically mounted at
/var/run/secrets/kubernetes.io/serviceaccount/token) - Scrape configuration files and API keys from exposed dashboards
-
Privilege Escalation: Valid credentials are immediately validated against AWS APIs and Kubernetes clusters. Active credentials are auctioned or used for cryptomining, data exfiltration, or lateral movement.
Exploitation Status
- Active Exploitation: Confirmed in-the-wild as of July 2026
- Attack Surface: Misconfigured AI services exposed to public internet
- No CVE Required: This campaign exploits configuration failures, not software vulnerabilities
- Scope: Global, with thousands of compromised AWS keys already claimed
Why This Matters
The danger of NadMesh lies not in exploiting zero-day vulnerabilities, but in capitalizing on the rapid, often unchecked adoption of AI tooling. Development teams deploy these services for proof-of-concept work, testing, and production workflows—frequently bypassing formal security review. When these services expose their web interfaces or APIs directly to the internet without authentication, they become trivial targets for automated credential harvesters.
Detection & Response
SIGMA Rules
---
title: NadMesh Botnet - Public AI Service Exposure Scan
id: 4a7b3c9d-1e2f-4a5b-8c9d-0e1f2a3b4c5d
status: experimental
description: Detects incoming network connections to common AI service ports from external sources, indicative of NadMesh scanning activity or successful exposure.
references:
- https://thehackernews.com/2026/07/new-nadmesh-botnet-hunts-exposed-ai.html
author: Security Arsenal
date: 2026/07/15
tags:
- attack.discovery
- attack.t1595
logsource:
category: network_connection
product: windows
detection:
selection_ports:
DestinationPort:
- 8188 # ComfyUI
- 11434 # Ollama
- 5678 # n8n
- 8080 # Open WebUI common
- 3000 # Open WebUI alternative
- 7860 # Langflow/Gradio
- 7861 # Gradio alternative
filter_internal:
SourceIp|cidr:
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/16'
- '127.0.0.0/8'
- '::1/128'
- 'fc00::/7'
condition: selection_ports and not filter_internal
falsepositives:
- Legitimate external access to AI services (should be rare and intentional)
level: high
---
title: NadMesh Botnet - AWS Credential Exfiltration via Unusual Process
id: 7d8e9f0a-2b3c-4d5e-9f0a-1b2c3d4e5f6a
status: experimental
description: Detects processes potentially associated with NadMesh botnet or similar malware making outbound connections to AWS endpoints, indicative of credential validation or exfiltration activity.
references:
- https://thehackernews.com/2026/07/new-nadmesh-botnet-hunts-exposed-ai.html
author: Security Arsenal
date: 2026/07/15
tags:
- attack.exfiltration
- attack.t1041
logsource:
category: network_connection
product: linux
detection:
selection_aws_endpoint:
DestinationHostname|contains:
- '.amazonaws.com'
selection_suspicious_process:
Image|contains:
- '/tmp/'
- '/dev/shm/'
- '/var/tmp/'
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
selection_go_binary:
Image|endswith:
- '/bot'
- '/scan'
- '/harvest'
condition: selection_aws_endpoint and (selection_suspicious_process or selection_go_binary)
falsepositives:
- Legitimate AWS CLI tools from standard locations
- Authorized monitoring agents
level: critical
---
title: NadMesh Botnet - Kubernetes Token Access from Unusual Process
id: 1a2b3c4d-3e4f-5a6b-7c8d-9e0f1a2b3c4d
status: experimental
description: Detects processes attempting to read Kubernetes service account tokens from non-standard paths or unusual parent processes, a key TTP of the NadMesh botnet.
references:
- https://thehackernews.com/2026/07/new-nadmesh-botnet-hunts-exposed-ai.html
author: Security Arsenal
date: 2026/07/15
tags:
- attack.credential_access
- attack.t1552
logsource:
category: file_access
product: linux
detection:
selection_token_path:
TargetFilename|contains: '/var/run/secrets/kubernetes.io/serviceaccount/token'
filter_legitimate:
Image|contains:
- '/usr/local/bin/kubectl'
- '/usr/bin/kubectl'
- '/usr/local/bin/helm'
- '/usr/bin/helm'
- '/opt/cni/bin/'
- '/home/kubernetes/'
filter_suspicious_location:
Image|contains:
- '/tmp/'
- '/var/tmp/'
- '/dev/shm/'
condition: selection_token_path and not filter_legitimate and filter_suspicious_location
falsepositives:
- Custom agents with non-standard paths (verify and tune)
level: high
KQL (Microsoft Sentinel / Defender)
// Hunt for NadMesh botnet indicators - AI service exposure and credential theft
// Combine network traffic, process execution, and sign-in logs
let AIPorts = dynamic([8188, 11434, 5678, 8080, 3000, 7860, 7861]);
let AIProcessNames = dynamic(["comfyui", "ollama", "n8n", "open-webui", "langflow", "gradio"]);
// Detect public exposure of AI services
let ExposedAIServices =
DeviceNetworkEvents
| where RemotePort in (AIPorts)
| where InitiatingProcessSHA256 != "" // Ensure valid process data
| where not(IPv4Prefix(RemoteIP, 10) or IPv4Prefix(RemoteIP, 172.16) or IPv4Prefix(RemoteIP, 192.168) or RemoteIP == "127.0.0.1")
| summarize ExposureCount = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp),
RemoteIPs = makeset(RemoteIP), InitiatingProcesses = makeset(InitiatingProcessFileName)
by DeviceId, DeviceName, LocalPort, RemotePort
| where ExposureCount > 0;
// Detect suspicious AWS access from unexpected processes
let SuspiciousAWSAccess =
DeviceNetworkEvents
| where RemoteUrl contains "amazonaws.com"
| where InitiatingProcessFolderPath in ("/tmp/", "/var/tmp/", "/dev/shm/", "C:\\Users\\Public\\", "C:\\Windows\\Temp\\")
or InitiatingProcessFileName in ("bot", "scan", "harvest", "loader", "updater")
| project Timestamp, DeviceId, DeviceName, InitiatingProcessFileName,
InitiatingProcessSHA256, RemoteUrl, RemoteIP
| summarize AWSCalls = count(), AWSRegions = makeset(RemoteUrl)
by DeviceId, DeviceName, InitiatingProcessFileName, InitiatingProcessSHA256;
// Detect unexpected processes accessing k8s token path
let K8sTokenAccess =
DeviceFileEvents
| where FileName == "token"
| where FolderPath contains "/var/run/secrets/kubernetes.io/serviceaccount/" or
FolderPath contains "serviceaccount"
| where not(InitiatingProcessFolderPath contains "/usr/local/bin/" or
InitiatingProcessFolderPath contains "/usr/bin/" or
InitiatingProcessFolderPath contains "/opt/")
| project Timestamp, DeviceId, DeviceName, InitiatingProcessFileName,
InitiatingProcessSHA256,FolderPath
| summarize TokenAccessCount = count() by DeviceId, DeviceName, InitiatingProcessFileName;
// Correlate findings
union
(ExposedAIServices | project-rename FindingType="Exposed AI Service", Evidence=pack("RemoteIPs", RemoteIPs, "Processes", InitiatingProcesses)),
(SuspiciousAWSAccess | project-rename FindingType="Suspicious AWS Access", Evidence=pack("AWSRegions", AWSRegions, "CallCount", AWSCalls)),
(K8sTokenAccess | project-rename FindingType="K8s Token Access", Evidence=pack("AccessCount", TokenAccessCount))
| order by Timestamp desc
Velociraptor VQL
-- Hunt for NadMesh botnet indicators on Linux endpoints
-- Check for exposed AI service ports, suspicious binaries, and credential access
LET AI_PORTS = '8188,11434,5678,8080,3000,7860,7861'
-- Check for listening AI service ports exposed to 0.0.0.0 (all interfaces)
SELECT Pid, Name, CommandLine,
listen.Address AS ListenAddress,
listen.Port AS ListenPort,
listen.State AS ConnectionState
FROM listen()
WHERE Port IN split(string=AI_PORTS, sep=',')
AND Address = '0.0.0.0'
-- Hunt for suspicious Go binaries in temp directories
SELECT Pid, Name, Exe, CommandLine, Username, Cwd,
exe.Size AS BinarySize,
exe.ModTime AS BinaryModified
FROM pslist()
WHERE Exe =~ '/tmp/' OR Exe =~ '/var/tmp/' OR Exe =~ '/dev/shm/'
AND Name =~ '^(bot|scan|harvest|loader|agent|update)'
OR (Exe =~ 'go_build' AND Exe =~ '/tmp/')
-- Check for processes reading Kubernetes service account tokens
SELECT Pid, Name, CommandLine, Exe, Username,
fd.Path AS AccessedPath,
fd.Mode AS AccessMode
FROM pslist()
JOIN foreach(
row=
SELECT Pid, FdNumber, Path, Mode
FROM fd(pid=Pid)
WHERE Path =~ '/var/run/secrets/kubernetes.io/serviceaccount/token'
)
WHERE NOT (Exe =~ '/usr/(bin|local/bin)/' OR Exe =~ '/opt/' OR Exe =~ '/home/kubernetes/')
-- Check for AWS credential files being accessed by suspicious processes
SELECT Pid, Name, CommandLine, Exe, Username,
fd.Path AS CredentialPath,
fd.Mode AS AccessMode
FROM pslist()
JOIN foreach(
row=
SELECT Pid, FdNumber, Path, Mode
FROM fd(pid=Pid)
WHERE Path =~ '/.aws/credentials' OR Path =~ '/.aws/config'
)
WHERE Exe =~ '/tmp/' OR Exe =~ '/var/tmp/' OR Exe =~ '/dev/shm/'
Remediation Script (Bash)
#!/bin/bash
# NadMesh Botnet - AI Service Hardening Script
# Usage: sudo ./nadmesh_hardening.sh
# This script checks for exposed AI services and applies security controls
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}[*] NadMesh Botnet Hardening - Starting Assessment${NC}"
# Array of AI service ports to check
AI_PORTS=(8188 11434 5678 8080 3000 7860 7861)
AI_SERVICE_NAMES=("ComfyUI" "Ollama" "n8n" "OpenWebUI" "OpenWebUI-Alt" "Langflow" "Gradio")
EXPOSED_COUNT=0
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}[!] Please run as root${NC}"
exit 1
fi
# Function to check if port is exposed to 0.0.0.0
check_exposed_port() {
local port=$1
local service_name=$2
if netstat -tuln 2>/dev/null | grep -q ":${port} .*0.0.0.0"; then
echo -e "${RED}[!] ${service_name} (port ${port}) is EXPOSED to 0.0.0.0 - CRITICAL RISK${NC}"
# Find process listening on this port
local pid=$(netstat -tulnp 2>/dev/null | grep ":${port} " | awk '{print $7}' | cut -d'/' -f1)
local process_name=$(netstat -tulnp 2>/dev/null | grep ":${port} " | awk '{print $7}' | cut -d'/' -f2)
echo -e " Process: ${process_name} (PID: ${pid})"
# Check for AWS credentials in process environment
if [ -n "$pid" ]; then
if cat /proc/${pid}/environ 2>/dev/null | tr '\0' '\n' | grep -q "AWS_ACCESS_KEY_ID"; then
echo -e " ${RED}[WARNING] Process has AWS credentials in environment!${NC}"
fi
if cat /proc/${pid}/environ 2>/dev/null | tr '\0' '\n' | grep -q "KUBERNETES_SERVICE_HOST"; then
echo -e " ${YELLOW}[WARNING] Process has access to Kubernetes service account!${NC}"
fi
fi
((EXPOSED_COUNT++))
return 1
else
echo -e "${GREEN}[+] ${service_name} (port ${port}) - Not exposed to public internet${NC}"
return 0
fi
}
# Check all AI service ports
for i in "${!AI_PORTS[@]}"; do
check_exposed_port "${AI_PORTS[$i]}" "${AI_SERVICE_NAMES[$i]}"
done
# Scan for suspicious binaries in temp directories
echo -e "\n${YELLOW}[*] Scanning for suspicious binaries in temp directories...${NC}"
SUSPICIOUS_COUNT=0
for temp_dir in /tmp /var/tmp /dev/shm; do
if [ -d "$temp_dir" ]; then
# Look for Go binaries and botnet-related filenames
find "$temp_dir" -type f -executable -o -name "*bot*" -o -name "*scan*" -o -name "*harvest*" 2>/dev/null | while read file; do
if [ -x "$file" ]; then
echo -e "${RED}[!] Suspicious executable found: ${file}${NC}"
file "$file"
((SUSPICIOUS_COUNT++))
fi
done
fi
done
# Check for exposed Kubernetes tokens
echo -e "\n${YELLOW}[*] Checking for Kubernetes token exposure...${NC}"
if [ -f "/var/run/secrets/kubernetes.io/serviceaccount/token" ]; then
echo -e "${YELLOW}[!] This host has a Kubernetes service account token${NC}"
# Check if AI services have access to it
if [ "$EXPOSED_COUNT" -gt 0 ]; then
echo -e "${RED}[CRITICAL] Exposed AI services may have access to Kubernetes tokens!${NC}"
fi
fi
# Summary
echo -e "\n${GREEN}[*] Assessment Complete${NC}"
echo -e " Exposed AI Services: ${EXPOSED_COUNT}"
echo -e " Suspicious Binaries: ${SUSPICIOUS_COUNT}"
# Recommendations
echo -e "\n${YELLOW}[*] REMEDIATION RECOMMENDATIONS:${NC}"
if [ "$EXPOSED_COUNT" -gt 0 ]; then
echo -e "${RED} 1. IMMEDIATELY bind all AI services to 127.0.0.1 or internal network interfaces${NC}"
echo -e " 2. Configure firewalls to block external access to AI service ports"
echo -e " 3. Implement authentication (OAuth, API keys, or JWT) on all AI services"
echo -e " 4. Rotate all AWS credentials and Kubernetes tokens that may have been exposed"
echo -e " 5. Review AWS CloudTrail and Kubernetes audit logs for unauthorized access"
fi
echo -e " 6. Deploy Web Application Firewall (WAF) rules for AI service endpoints"
echo -e " 7. Implement network segmentation for AI/ML development environments"
echo -e " 8. Enable audit logging for all AI service access"
echo -e " 9. Regularly scan for exposed AI services using vulnerability management tools"
echo -e " 10. Establish security review process before deploying AI tools to production"
if [ "$EXPOSED_COUNT" -eq 0 ] && [ "$SUSPICIOUS_COUNT" -eq 0 ]; then
echo -e "\n${GREEN}[+] No immediate indicators of NadMesh exposure detected${NC}"
exit 0
else
echo -e "\n${RED}[!] CRITICAL FINDINGS DETECTED - IMMEDIATE ACTION REQUIRED${NC}"
exit 1
fi
Remediation
Immediate Actions (Within 24 Hours)
-
Identify and Inventory All AI Services
- Scan your entire network infrastructure for the affected services (ComfyUI, Ollama, n8n, Open WebUI, Langflow, Gradio)
- Use the provided hardening script or run:
nmap -p 8188,11434,5678,8080,3000,7860,7861 <your-network-cidr> - Document all instances, including ownership, purpose, and exposure status
-
Isolate Exposed Services
- Immediately block public internet access to all AI service ports at the network edge
- Reconfigure services to bind only to
127.0.0.1(localhost) or internal VPN-protected subnets - If external access is required, implement authentication and restrict via IP whitelisting
-
Credential Rotation (CRITICAL)
- Assume any AWS credentials, API keys, or Kubernetes tokens accessible by exposed AI services are compromised
- Rotate all potentially exposed AWS access keys, secret keys, and session tokens
- Rotate all Kubernetes service account tokens that may have been accessible
- Review AWS CloudTrail logs for any suspicious API calls in the past 30 days
- Review Kubernetes audit logs for unauthorized access
Short-Term Hardening (Within 1 Week)
-
Implement Authentication and Access Controls
- Enable authentication on all AI services. Recommended methods:
- Ollama: Set
OLLAMA_ORIGINS="*"and use reverse proxy with OAuth - n8n: Configure LDAP/OAuth2 authentication
- ComfyUI: Implement HTTP Basic Auth or OAuth via reverse proxy
- Open WebUI: Enable built-in authentication in configuration
- Ollama: Set
- Deploy a reverse proxy (nginx, Apache, or Caddy) with OAuth2/OIDC integration
- Enable authentication on all AI services. Recommended methods:
-
Network Segmentation
- Place all AI/ML infrastructure in isolated network segments (VPCs/VLANs)
- Implement strict egress filtering—AI services should only connect to necessary endpoints
- Deploy internal firewalls to control lateral movement between AI services and production systems
-
Deploy Web Application Firewall Rules
- Create WAF rules to detect and block scanning activity targeting AI service ports
- Implement rate limiting and anomaly detection for AI service endpoints
Long-Term Controls (Within 30 Days)
-
Establish AI Security Governance
- Create a formal policy for AI/ML tool deployment and security
- Require security review before any AI service is deployed to production
- Maintain an approved list of AI tools with security configurations
-
Implement Continuous Monitoring
- Deploy the provided Sigma rules and KQL queries to your SIEM
- Set up automated alerts for:
- New AI services exposed to the internet
- Unusual AWS API calls from non-standard processes
- Kubernetes token access from unexpected processes
- Schedule weekly vulnerability scans focused on AI service exposure
-
Secure Development Practices
- Provide developers with pre-configured, secure AI service templates
- Integrate security checks into CI/CD pipelines for AI/ML applications
- Use secrets management solutions (HashiCorp Vault, AWS Secrets Manager) instead of environment variables
Vendor-Specific Hardening Guidance
| Service | Binding Configuration | Authentication Guidance |
|---|---|---|
| ComfyUI | Edit start.sh: --listen 127.0.0.1 | Use nginx with auth_basic or OAuth2 proxy |
| Ollama | Set OLLAMA_HOST=127.0.0.1:11434 | Use reverse proxy with authentication |
| n8n | Edit config: N8N_HOST=127.0.0.1 | Enable N8N_BASIC_AUTH_ACTIVE=true or LDAP |
| Open WebUI | Set HOST=127.0.0.1 in .env | Enable WEBUI_AUTH=True in configuration |
| Langflow | Set --host 127.0.0.1 on startup | Use Caddy with OAuth2 |
| Gradio | Set server_name="127.0.0.1" in code | Implement auth=() parameter or proxy auth |
Verification Steps
After implementing remediation:
- Verify all AI services are accessible only from authorized internal IPs
- Test authentication is required for all AI service access
- Confirm no AI services are visible on Shodan or internet scanners
- Validate that no processes from temp directories are accessing AWS or Kubernetes APIs
- Review SIEM alerts for 7 days to confirm no scanning activity persists
References and Official Resources
- AWS Security Best Practices for AI/ML
- Kubernetes Hardening Guide
- NIST AI Risk Management Framework
- CISA KEV Catalog
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.