Back to Articles

Spidernet: What SSH-Based Botnets Teach Us About Remote Administration Gone Wrong

[ View on GitHub ]

Spidernet: What SSH-Based Botnets Teach Us About Remote Administration Gone Wrong

Hook

The same Python library you use to automate server deployments can manage a botnet with just 300 lines of code. Spidernet proves that the difference between DevOps tooling and malicious infrastructure is mostly just intent.

Context

Remote administration has always walked a fine line. Ansible, Salt, and Fabric are celebrated as essential DevOps tools, yet their core capability—executing arbitrary commands on multiple remote hosts—is functionally identical to botnet command-and-control systems. The SSH protocol, designed as a secure replacement for telnet and rsh, has become the backbone of modern infrastructure management. But this ubiquity creates an interesting security paradox: SSH traffic is so common that malicious C&C communications can hide in plain sight among legitimate administrative activity.

Spidernet exists in the murky territory between educational security research and offensive tooling. It's a proof-of-concept that demonstrates how trivially simple it is to build a botnet when you have compromised credentials. Unlike sophisticated malware that exploits zero-days or employs complex evasion techniques, Spidernet operates on a brutally honest premise: if an attacker has valid SSH credentials to multiple hosts, managing them as a botnet requires nothing more than Paramiko and basic Python knowledge. This simplicity is the point—it exposes how credential compromise, not technical sophistication, is often the real security failure.

Technical Insight

Paramiko Layer

Menu Commands

Add Host

Execute Command

Store

SSH Channel

SSH Channel

SSH Channel

Maintains

Maintains

Maintains

Command Output

Command Output

Command Output

Display Results

Reference

Operator Console

Central Controller

Host Registry

In-Memory Dict

Command Dispatcher

Host Entry

IP, Creds, SSHClient

Compromised Host 1

SSH Session

Compromised Host 2

SSH Session

Compromised Host N

SSH Session

SSH Connection Pool

Persistent Clients

Response Aggregator

System architecture — auto-generated

At its core, Spidernet is a connection pooling system wrapped in a command dispatcher. The architecture relies on Paramiko's SSHClient to establish and maintain persistent connections to compromised hosts. Rather than creating a custom protocol or payload, it simply leverages standard SSH channels—the same mechanism you'd use in a legitimate remote shell session.

The controller maintains an in-memory registry of hosts, each represented as a dictionary containing IP address, port, credentials, and system metadata. When you add a host, Spidernet attempts an SSH connection, retrieves system information via uname, and stores the active SSHClient object for reuse:

def add_host(ip, port, username, password):
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        client.connect(ip, port=port, username=username, password=password, timeout=10)
        stdin, stdout, stderr = client.exec_command('uname -a')
        system_info = stdout.read().decode().strip()
        
        host_data = {
            'ip': ip,
            'port': port,
            'username': username,
            'client': client,
            'system': system_info
        }
        hosts[ip] = host_data
        return True
    except Exception as e:
        print(f"Connection failed: {e}")
        return False

The AutoAddPolicy() call is particularly telling—it blindly accepts any SSH host key, eliminating the normal trust-on-first-use security model. This is exactly the kind of security theater bypass that makes the tool unsuitable for legitimate use but demonstrates real-world attacker behavior.

Command execution follows a simple fan-out pattern. The controller iterates through connected hosts, dispatches the same command via exec_command(), and aggregates results. There's no sophisticated queuing, no retry logic, no async execution—just synchronous SSH command execution in a loop:

def execute_on_all(command):
    results = {}
    for ip, host_data in hosts.items():
        try:
            client = host_data['client']
            stdin, stdout, stderr = client.exec_command(command)
            output = stdout.read().decode()
            errors = stderr.read().decode()
            results[ip] = {'stdout': output, 'stderr': errors}
        except Exception as e:
            results[ip] = {'error': str(e)}
    return results

The interactive shell mode is where things get interesting architecturally. Rather than exec_command(), it invokes a full PTY session using invoke_shell(), giving the operator a persistent interactive terminal. This is the same mechanism behind tools like ssh -t that allocate pseudo-terminals for interactive programs. The implementation pumps data between the operator's local terminal and the remote shell, effectively proxying stdin/stdout through the SSH channel.

What makes this architecture notable isn't sophistication—it's the absence of it. There's no custom encryption, no protocol obfuscation, no domain generation algorithms for controller discovery. It's pure SSH traffic that looks identical to a systems administrator running Ansible playbooks or manually SSH'ing into servers. Network security tools that whitelist or deprioritize SSH traffic would completely miss this C&C activity. The only detection vectors are behavioral: unusual connection patterns, commands executed, or the fact that all hosts connect to the same controller IP.

The tool's simplicity also reveals a critical insight about modern botnets: technical complexity isn't always necessary. If you've already compromised credentials (via phishing, credential stuffing, or data breaches), weaponizing that access requires minimal code. The real defensive challenge isn't detecting sophisticated malware—it's identifying compromised credentials being used for unauthorized access patterns.

Gotcha

Spidernet's limitations are numerous and intentional—this is a proof-of-concept, not operational malware. The most glaring issue is credential storage: passwords are held in plaintext in memory with no encryption at rest. If the controller host is compromised, the entire botnet's credentials are immediately exposed. There's also zero resilience—if a host's SSH daemon restarts or the network hiccups, the connection is lost with no automatic reconnection logic. A production botnet would implement heartbeat checks and automatic re-establishment of dead connections.

The synchronous command execution model is a significant bottleneck. With dozens of hosts, executing a command means waiting for each host to respond serially. Network latency compounds linearly—10 hosts with 200ms latency each means a 2-second wait for full results. Legitimate tools like Ansible solve this with parallel execution and configurable fork counts. The menu-driven interface is also a dead giveaway if someone gets shell access to the controller—there's no attempt to masquerade as a legitimate process or hide its purpose.

From a detection standpoint, Spidernet leaves massive forensic footprints. Every command execution is logged in the target's SSH daemon logs (typically /var/log/auth.log or /var/log/secure), clearly showing the source IP and username. Many organizations already monitor for SSH sessions from unexpected geographic locations or unusual command patterns. The controller's IP becomes a single point of failure and detection—identify one compromised host connecting to it, and you've found the entire botnet's control infrastructure.

Verdict

Use if: You're a security researcher studying C&C architectures in an isolated lab environment, a penetration tester with explicit written authorization to demonstrate credential compromise impact, or an educator teaching the fundamentals of botnet mechanics and why credential security matters. This is valuable for understanding attacker TTPs (Tactics, Techniques, and Procedures) and developing detection strategies. Skip if: You need actual remote administration tooling (use Ansible, Salt, or Fabric instead), lack explicit authorization on target systems (using this without consent is illegal in virtually every jurisdiction), or want production-ready infrastructure automation (this has none of the reliability, audit logging, or safety features required for real deployments). This tool is exclusively for understanding threats, not implementing solutions.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/ai-dev-tools/wandering-nomad-spidernet.svg)](https://starlog.is/api/badge-click/ai-dev-tools/wandering-nomad-spidernet)