Skillfade Logo

All things SSH - Administering, Scanning, Hopping and Brute Forcing

⏳ 11 min read

Table of Contents

    Cybersecurity Illustration

    Neon light slices through the rain-slick streets outside, illuminating skyscrapers etched with rows of blinking servers. Inside the flicker of monitors and the hiss of cooling fans feels like circuitry over flesh, every cable a vein, every switch a nerve. I’m deep inside the machine now, the data pulses like adrenaline through the network, and SSH is the spine of the operation, it’s the confidant, the gatekeeper, the battle‐scarred conduit I both revere and fear.

    There is the smell of solder, cold steel racks humming, and the static charge whenever I breach a firewall or routable subnet. I can taste packets, the clatter of authentication protocols, the gleam of public‐private keys. I move like an echo, shifting from host to host, through tunnels, hopping like lightning. And when brute force storms the door, patience and precise brutality are the only tools. Welcome to the edge of control, the shadows where SSH binds the nodes and I bend them to my will.


    Administering SSH

    Step-by-Step: Hardening and Configuration

    1. Install & Update OpenSSH
      On *nix systems:
    bash
       sudo apt update && sudo apt install openssh-server
       sudo systemctl enable ssh && sudo systemctl start ssh
    
    1. Change default port (not security by obscurity but reduces noise)
      In /etc/ssh/sshd_config, modify:
       Port 2222
    

    Then restart SSH:

    bash
       sudo systemctl restart ssh
    
    1. Disable root login
       PermitRootLogin no
    
    1. Use key-based authentication only
    text
       PasswordAuthentication no
       PubkeyAuthentication yes
    

    Deploy authorised keys via ~/.ssh/authorized_keys, set permissions: chmod 700 ~/.ssh, chmod 600 authorized_keys.

    1. Restrict user logins and configure forced commands
      Use AllowUsers alice bob or AllowGroups sshusers. Use ForceCommand in authorized_keys for constrained shell or use jail.

    2. Configure idle time-outs, rate limits, and logging
      - ClientAliveInterval 300
      - ClientAliveCountMax 0
      - Use MaxAuthTries 3
      - Log to auth.log or journalctl, perhaps forward logs to central syslog.

    3. Use strong cryptographic algorithms only
      In sshd_config:

       Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
       KexAlgorithms curve25519-sha256
       MACs hmac-sha2-512-etm@openssh.com
    
    1. Enable two-factor authentication (2FA)
      Install libpam-google-authenticator or similar, configure PAM.

    Admin Checklist

    • Change port away from 22
    • Disable root login
    • Enforce key-based auth only
    • Permit only required users or groups
    • Set idle session timeout
    • Limit failed attempts (MaxAuthTries)
    • Strong ciphers/kex/MACs
    • Enable 2‐factor if needed
    • Regularly rotate keys
    • Audit logs

    Mini-lab

    • Set up two virtual machines: one as SSH server, another as client.
    • Configure the server with a custom port, disable password auth, and restrict to one user.
    • Configure key pairs (RSA or better yet ed25519), try login.
    • Attempt password login (should fail).
    • Test inactivity time-out kicks you out after stipulated period.

    Scanning SSH

    I’m crawling through the dark, probing doors. Scanning reveals patterns, a drumbeat of open ports, banners whispering software versions. Know where the weak points are before the attackers do.

    How-to: Scanning for SSH Hosts & Versions

    1. Discover live hosts
    bash
       nmap -sP 192.168.1.0/24
    
    1. Scan for SSH port (usually 22 or custom)
    bash
       nmap -p 22,2222 -sV -O 192.168.1.0/24
    

    -sV grabs version info; -O tries OS detection.

    1. Banner grabbing
    bash
       nc -vv target_hostname_or_ip 22
    

    or use ssh -v user@host to see the server version string.

    1. Mass scanning
      Use Masscan:
    bash
       sudo masscan 10.0.0.0/8 -p22 -oX ssh_hosts.xml
    

    Then feed results into nmap for deeper inspection.

    1. Check for weak or deprecated protocols
      Run ssh-audit tool or use nmap --script ssh2-enum-algos to enumerate weak ciphers, key exchange, MACs.

    Edge Case Notes

    • Some servers may disable version banners or send truncated banners.
    • Hosts behind load-balancers may reveal differing versions.
    • Custom ports, port knocking or firewall rules may hide services.
    • Honeypots will try to mimic SSH responses; look for oddities (banner discrepancies, clock skew, unusual cipher sets).

    Scanning Workflow

    Phase Tool Goal
    Discovery nmap/Masscan find IPs with SSH open
    Versioning nmap, ssh-audit get software version & algorithms
    Enumeration custom banner grabs test for unusual or deprecated crypto
    False positives / noise reduction retries, cross-checking ensure hosts are live and SSH is genuine

    Mini-lab

    • Use three VMs: one running OpenSSH 8.9, another running older 7.x with weak ciphers, a third behind a basic firewall.
    • Use nmap and ssh-audit to enumerate versions and cipher suites.
    • Try scanning across subnets including non-standard ports, identify hosts with SSH.
    • Record banners and spot anomalies.

    SSH Hopping & Tunnelling (Lateral Movement)

    I slip through the corridors of trust, from one compromised node to the next. SSH is worming through the network, a stegosaurus in the system, using tunnels and agent forwarding.

    How-to: SSH Hopping, Agent Forwarding, and Tunnels

    1. Agent forwarding
      On client:
    bash
       ssh -A user@jumpbox
    

    From jumpbox:

    bash
       ssh target_internal_host
    

    The private key stays on local machine. Note: dangerous if jumpbox is compromised.

    1. Jump hosts (ProxyJump)
      In ~/.ssh/config on client:
       Host internal-*
         ProxyJump jumpuser@jump.host.com
    

    Use ssh internal-host and traffic is proxied through jump.host.com.

    1. SSH Tunnelling / Port Forwarding
      - Local port forward:
    bash
         ssh -L 8080:internal.server:80 user@jumpbox
    
    • Remote port forward:
    bash
         ssh -R 9090:localhost:3000 user@public.server
    
    1. Dynamic port forwarding (SOCKS proxy)
    bash
       ssh -D 1080 user@jumpbox
    

    Configure browser or tool to use localhost:1080 as SOCKS proxy to reach internal hosts.

    1. Chaining hops manually
      SSH from A → B → C. Use control sockets or ProxyCommand to avoid multiple password prompts and avoid leaving credentials on hosts.

    2. Port knocking / Single-Packet Authorization (SPA)
      Protect SSH port behind knocking sequences. Use tools like fwknop for SPA.

    Security Concerns & Edge Cases

    • Agent forwarding risk if intermediate host is malicious or compromised.
    • ProxyJump misconfigurations may expose private key usage or allow privilege escalation.
    • Port forwarding may bypass firewall policy unwittingly.
    • Knocked ports might leave logs or be susceptible to replay or brute force of knock sequence.

    Mini-lab Workflow

    • Setup three machines: public jumpbox, internal host accessible only from jumpbox, local machine.
    • Configure ProxyJump in .ssh/config. Use agent forwarding to hop without copying private keys.
    • Set up local port forwarding to access a web service on the internal host via the jumpbox.
    • Try remote port forwarding. Observe firewall or RBAC restrictions.

    Takeaways

    • ProxyJump and agent forwarding are powerful but risky.
    • Tunnels can bypass network segmentation; always monitor.
    • Understand how credentials flow.
    • Audit usage of jump hosts, restrict to trusted users.

    Brute Forcing SSH

    The clash in the neon zones: endless password guesses, rate limits, lockouts. The attacker storms the wall. You must know both sides, the brute force and the defence.

    How-to: Simulated Brute Force and Defence

    Warning: The following snippet is offensive behaviour if used without permission. Must only be executed within authorised, isolated test networks or capture-the-flag labs.

    bash
    #!/bin/bash
    # ssh brute force prototype (authorised use only)
    TARGET=192.168.1.50
    USER=admin
    WORDLIST=/path/to/wordlist.txt
    
    for PASS in $(cat $WORDLIST); do
      sshpass -p "$PASS" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no $USER@$TARGET 'echo success' && {
        echo "Password found: $PASS"
        break
      }
    done
    
    1. Prepare wordlists , rockyou, custom rules (e.g pop culture, regexps).
    2. Use specialised tools , hydra, medusa, patator. These leverage parallelism.
    bash
       hydra -l admin -P /path/to/wordlist.txt 192.168.1.50 ssh
    
    1. Respect rate limits and lockouts , many SSH servers configured with MaxAuthTries, LoginGraceTime, PermitRootLogin no.
    2. Monitor logs , /var/log/auth.log, journalctl for Debian-based; identify repeated failed attempts. Use logwatch or fail2ban.

    3. Defensive scripts , configure fail2ban or sshguard to watch patterns; temporarily block via firewall.

    4. Use captchas or multi-factor to add extra barrier.

    Defending Workflow

    Defence Configuration / Tool
    Rate limiting MaxAuthTries, LoginGraceTime, PermitRootLogin no
    Ban repeated offenders fail2ban with SSH filter
    MFA/2FA usage PAM integration or SSH key + TOTP
    Key rotation remove old unused keys from authorized_keys
    Monitoring set up alerts for authentication failures, unusual source IPs

    Mini-lab

    • Stand up an SSH server with weak password authentication enabled.
    • Use hydra to brute-force a user with a small wordlist.
    • Configure fail2ban to ban offending IPs after three failures.
    • Switch server to key-only auth and try brute force again. Observe failures (no password vector).
    • Set up two-factor auth and test.

    Mastering SSH: Administering, Scanning, Hopping and Brute-Forcing

    Aim

    To guide you through advanced SSH operations with hands-on examples: covering secure administration, scanning targets, hop-based connections, and controlled brute-forcing in a legal context.

    Learning outcomes

    By the end you will be able to:

    • configure SSH securely for administration, including disabling root login and enforcing key-based access
    • scan networks and discover SSH services, identifying versions and exposed hosts
    • establish SSH jumps or bastions for multi-hop access using ProxyJump / ProxyCommand
    • perform legitimate brute-force or dictionary testing on SSH (in lab or approved scope) and defend against such attacks

    Prerequisites

    • A Linux environment (local machine and one or more remote servers) with OpenSSH installed
    • Familiarity with shell commands and editing files (nano, vi etc.)
    • Basic networking knowledge (IP addresses, ports)
    • Tools such as nmap, hydra (or medusa), fail2ban installed

    Step-by-step guide

    1. Secure SSH administration

    1. Open /etc/ssh/sshd_config. Set:
    bash
       PermitRootLogin no
       PasswordAuthentication no
       AllowUsers adminuser1 adminuser2
    

    These restrict root login, force key-based auth and limit allowed users. (sshhandbook.com)

    1. Limit authentication attempts:
    text
       MaxAuthTries 3
       LoginGraceTime 30
    
    1. Enforce idle timeout, disable environment modifications: in sshd_config:
    text
       ClientAliveInterval 300
       ClientAliveCountMax 0
       PermitUserEnvironment no
    
    1. Change default SSH port (optional, obscurity): modify Port 22 to e.g. Port 2222, then restart SSH so firewall can accept. (docs.edisglobal.com)

    2. Install fail2ban, configure SSH jail:

    bash
       sudo apt install fail2ban
    

    In /etc/fail2ban/jail.local:

    text
       [sshd]
       enabled = true
       port = 2222
       filter = sshd
       logpath = /var/log/auth.log
       maxretry = 5
       bantime = 600
    

    Blocks IPs after repeated failures. (sshhandbook.com)


    2. Scanning to discover SSH services

    1. Use nmap to scan hosts / networks for open SSH ports:
    bash
       nmap -sV -p 22,2222 192.168.1.0/24
    

    -sV detects version; specify custom ports. (en.wikipedia.org)

    1. Use faster scanners like ZMap for large IPv4 ranges: single-port scans identify SSH services quickly. (en.wikipedia.org)

    2. Capture SSH banner:

    bash
       nc -v target-host 22
    

    Looks like: SSH-2.0-OpenSSH_8.4p1 Debian-5 etc. Helps identify version and possible vulnerabilities.

    1. Document and archive version info; compare against known advisories to plan patches.

    3. SSH Hopping / Jump Hosts

    1. Using ProxyJump on CLI for a two-hop connection:
    bash
       ssh -J user@jumphost.internal user@target.internal
    
    1. In ~/.ssh/config, define entries:
    text
       Host jumphost
         HostName jumphost.example.com
         User jumpuser
    
       Host target
         HostName target.internal
         User adminuser
         ProxyJump jumphost
         IdentityFile ~/.ssh/id_ed25519
    
    1. For multi-hop: chain ProxyJump:
    text
       Host bastion1
         HostName bastion1.example.net
         User user1
    
       Host bastion2
         HostName bastion2.internal
         User user2
         ProxyJump bastion1
    
       Host target
         HostName target.internal.net
         User admin
         ProxyJump bastion2
    

    Then use ssh target to hop through. (docs.oracle.com)

    1. Alternative via ProxyCommand if older SSH or custom setup:
    bash
       ssh -o "ProxyCommand ssh jumpuser@jumphost.internal nc %h %p"
           adminuser@target.internal
    

    Use when you require fine-grained control. (golinuxcloud.com)


    4. Controlled brute-forcing for testing / awareness

    Use only in lab or explicitly authorised environments.

    1. Use hydra to test SSH credential strength:
    bash
       hydra -l adminuser -P passwords.txt -t 4 target.internal ssh -V
    

    -l single user, -P wordlist, -t parallel tasks, -V verbose output. (en.wikipedia.org)

    1. Use strong wordlists (e.g. SecLists) for passwords; enumerate usernames if possible to avoid wasted guesses.

    2. Monitor impact: logs in /var/log/auth.log will show failed attempts. Use legal and ethical constraints.

    3. Defending against brute force: combine SSH admin settings (key-based login, low MaxAuthTries), fail2ban with proper thresholds, firewall restrictions by IP, optionally geofencing. (usavps.com)


    Actionable insights

    • Always rotate SSH keys periodically and retire keys you no longer use.
    • Enforce least privilege: only give sudo where needed, avoid daily login as root.
    • Use centralised auditing of SSH access and jump host activity.
    • Regularly scan your network for exposed SSH services running out-of-date versions.
    • Simulate brute-force attacks in a safe environment to test your defence settings, adjusting fail2ban thresholds and firewall rules.

    Putting these steps into practice will significantly improve your command of SSH from administrative, scanning, hopping and brute-force perspectives.

    Remember you’re not just coding scripts, scanning hosts or brute forcing credentials. You are mapping trust, observing weakness, sensing the architecture of control. Through administering SSH you sculpt your border, through scanning SSH you read the topography, through hopping you betray trust lines, through brute forcing you probe bones. The machine hums, flickering LEDs reflect in my eyes. I taste the acrid sting of risk and control, I hear cipher suites renegotiate in the dark, I smell smoke when keys are misused and defences collapse. In this neon storm SSH is both weapon and lock, and I am both prisoner and destroyer.