# 🛡️ Defensive Measures — Making Every Attack in This Lab Fail

> This document is the defensive mirror of the entire `4_PenTesting` module.
> For every attack demonstrated against Metasploitable, this file explains **why it worked**, **what specific control would have stopped it**, and **how to implement that control**.
>
> Follow the same order as the lab: reconnaissance → enumeration → exploitation → privilege escalation → persistence.

---

## 📖 How to Read This Document

Each section maps directly to a lab module:

| 🔴 Attack Module | 🔵 Defensive Section |
|----------------|-------------------|
| `2_` — Recon, SMB, SSH brute-force | [Section 1 — Reduce the Attack Surface](#1--reduce-the-attack-surface) |
| `3_` — Post-exploitation enumeration | [Section 2 — Limit What an Attacker Can Learn](#2--limit-what-an-attacker-can-learn) |
| `4_` — CVE exploitation (vsftpd, distcc) | [Section 3 — Patch and Eliminate Vulnerable Services](#3--patch-and-eliminate-vulnerable-services) |
| `5_` — Privilege escalation, persistence | [Section 4 — Prevent Escalation and Persistence](#4--prevent-escalation-and-persistence) |

---

## 1. 🗺️ Reduce the Attack Surface

*Attacks countered: Nmap port scanning, SMB enumeration, SSH brute-force (Medusa)*

The Nmap scan of Metasploitable returned **29 open ports**. Every open port is a potential entry point. The first and most impactful defensive measure is simply: **close everything you don't need**.

---

### 1.1 🔌 Disable Unused Services

Metasploitable exposed services that no production system should ever run: Telnet, rsh, rexec, rlogin, distcc, bindshell, IRC. These exist for legacy compatibility and offer zero security benefit today.

**Audit what's listening:**
```bash
ss -tlnp          # Modern replacement for netstat
netstat -tlnp     # Alternative on older systems
```

**Disable services you don't use (systemd):**
```bash
systemctl stop vsftpd && systemctl disable vsftpd
systemctl stop distccd && systemctl disable distccd
systemctl stop telnet && systemctl disable telnet
systemctl stop rsh-server && systemctl disable rsh-server
```

> 💡 **Rule:** if you can't immediately explain why a service is running and who uses it, turn it off. Unneeded services that are never started cannot be exploited.

---

### 1.2 🔥 Firewall — Whitelist, Don't Blacklist

A host-based firewall should enforce the principle of **least exposure**: allow only ports your system actively needs, drop everything else silently.

**Set a default-deny policy with UFW:**
```bash
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp    # SSH — only if needed
ufw allow 80/tcp    # HTTP — only if a web server is running
ufw enable
```

**Or directly with iptables:**
```bash
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -lo -j ACCEPT
```

> 🎯 **What this stops:** the Nmap full-port scan (`-p 1-65535`) would return almost nothing. Every service hidden behind a firewall is effectively invisible to network reconnaissance.

---

### 1.3 🔐 Harden SSH — Kill Brute-Force at the Root

The Medusa brute-force attack worked because SSH accepted password-based logins and had no rate limiting. Both are fixable.

**Edit `/etc/ssh/sshd_config`:**
```bash
# Disable password authentication entirely — keys only
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes

# Reduce attack window
MaxAuthTries 3
LoginGraceTime 20

# Restrict to specific users if possible
AllowUsers youruser

# Optionally change the default port (security through obscurity — minor benefit)
Port 2222
```

**Restart SSH to apply:**
```bash
systemctl restart sshd
```

**Install `fail2ban` to auto-block repeated failures:**
```bash
apt install fail2ban

# Default SSH jail configuration (/etc/fail2ban/jail.local):
[sshd]
enabled = true
maxretry = 5
findtime = 300
bantime = 3600
```

> 🎯 **What this stops:** with key-based auth only, Medusa's wordlist attack becomes completely useless — there are no passwords to guess. `fail2ban` adds a second layer by banning IPs after a configurable number of failures.

---

### 1.4 🔒 Lock Down SMB

The SMB enumeration retrieved usernames, shares, and OS details without a single valid credential — because anonymous access was enabled.

**Disable anonymous SMB access in `/etc/samba/smb.conf`:**
```ini
[global]
restrict anonymous = 2
map to guest = never
```

**Disable SMBv1 entirely** (it has no business being enabled in any modern environment):
```ini
[global]
min protocol = SMB2
```

**If Samba is not needed at all:**
```bash
systemctl stop smbd nmbd
systemctl disable smbd nmbd
ufw deny 139/tcp
ufw deny 445/tcp
```

> 🎯 **What this stops:** `smb-enum-users`, `smb-enum-shares`, and `smb-os-discovery` would all return nothing. No username leak, no OS fingerprint, no share listing.

---

### 1.5 📡 Detect Reconnaissance — IDS/IPS

Even with a hardened surface, reconnaissance attempts should be logged and alerted on.

**Deploy Snort or Suricata** on network ingress to detect scan patterns:

```bash
apt install suricata
suricata -c /etc/suricata/suricata.yaml -i eth0
```

Key detection rules to enable:
- Port scan detection (`stream`, `portscan` preprocessors in Snort)
- Nmap OS fingerprinting signatures
- Service version probe patterns

> 🎯 **What this stops:** Nmap scans won't be prevented, but they will be **detected and logged** — giving the blue team time to respond and block the source IP before exploitation begins.

---

## 2. 🕵️ Limit What an Attacker Can Learn

*Attacks countered: system enumeration, user/group discovery, process listing, credential harvesting, NetCat exfiltration*

An attacker who lands on your system with limited access should hit walls everywhere they turn. The goal is **information starvation**: make enumeration difficult, slow, and noisy.

---

### 2.1 👤 Apply the Principle of Least Privilege

The `msfadmin` account was a member of the `admin` group and had broad system access. Regular service accounts and users should have only the permissions they actually need.

```bash
# Review group memberships
id username

# Remove a user from a privileged group
gpasswd -d username admin
gpasswd -d username sudo

# Lock service accounts so they can't log in interactively
usermod -s /usr/sbin/nologin daemon
usermod -s /usr/sbin/nologin www-data
```

---

### 2.2 🔑 Protect `/etc/shadow`

The `shadow` file was readable and exfiltrated in the lab. Its permissions should make this impossible for unprivileged users — but verify it explicitly.

```bash
# Correct permissions: root-owned, not world-readable
chmod 640 /etc/shadow
chown root:shadow /etc/shadow

# Verify
ls -la /etc/shadow
# Expected: -rw-r----- 1 root shadow
```

**Use strong password hashing** — MD5 (`$1$`) was cracked easily. Modern systems should use SHA-512:

```bash
# In /etc/pam.d/common-password, ensure:
password    [success=1 default=ignore]    pam_unix.so obscure sha512 rounds=65536
```

**Enforce password complexity:**
```bash
apt install libpam-pwquality
# /etc/pam.d/common-password:
password    requisite    pam_pwquality.so retry=3 minlen=12 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1
```

> 🎯 **What this stops:** even if an attacker reads the shadow file, SHA-512 with 65,536 rounds is orders of magnitude slower to crack than the MD5 hashes Metasploitable used. A 12-character complex password becomes computationally infeasible with common wordlists.

---

### 2.3 📋 Audit Logging — Know When You're Being Enumerated

Install and configure `auditd` to log sensitive file access and suspicious commands:

```bash
apt install auditd

# Watch for reads of /etc/shadow
auditctl -w /etc/shadow -p r -k shadow_read

# Log all use of sudo
auditctl -w /usr/bin/sudo -p x -k sudo_exec

# Monitor /etc/passwd changes
auditctl -w /etc/passwd -p wa -k passwd_changes

# Review logs
ausearch -k shadow_read
```

---

### 2.4 🚧 Block NetCat Exfiltration

The file transfer in the lab used NetCat on a non-standard port (`4444`). A properly configured egress firewall would have silently dropped this connection.

```bash
# Block all outbound except known-good ports (egress filtering)
iptables -P OUTPUT DROP
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
```

> 🎯 **What this stops:** `nc 192.168.100.10 > passwd` would silently fail — the outbound TCP connection to port `4444` (or `1337`) would be blocked. No exfiltration, no reverse shell callback either.

---

## 3. 🩹 Patch and Eliminate Vulnerable Services

*Attacks countered: vsftpd 2.3.4 backdoor (CVE-2011-2523), distcc RCE (CVE-2004-2687), MySQL/PostgreSQL CVEs, VNC, Tomcat*

Both exploits used in this lab targeted **known vulnerabilities with public CVEs and working exploit code**. Neither would have succeeded on a patched, properly configured system.

---

### 3.1 🔄 Keep Software Updated — Always

```bash
# Debian/Ubuntu
apt update && apt upgrade -y
apt install unattended-upgrades

# Enable automatic security updates
dpkg-reconfigure unattended-upgrades
```

**The vsftpd 2.3.4 backdoor** (CVE-2011-2523) was discovered in 2011. The fix was published the same day. A system that applied security updates would never have been running the backdoored binary.

**The distcc vulnerability** (CVE-2004-2687) was disclosed in **2002** — over two decades ago. There is no excuse for a production system to be running an unpatched version of distcc in 2026.

---

### 3.2 🚫 Disable distcc Entirely

distcc is a development tool for distributed compilation. It has no place on a production server.

```bash
systemctl stop distccd
systemctl disable distccd
ufw deny 3632/tcp
```

> If you genuinely need distcc in a build environment, **restrict it to localhost or a specific trusted IP range** via `~/.distcc/hosts` and firewall rules. Never expose port 3632 to an untrusted network.

---

### 3.3 🔒 Replace FTP with SFTP

FTP transmits credentials and data in plaintext and has a long history of critical vulnerabilities. Replace it:

```bash
# Disable vsftpd
systemctl stop vsftpd && systemctl disable vsftpd
ufw deny 21/tcp

# Use SFTP instead (built into OpenSSH — no additional software needed)
# Restrict SFTP users to their home directory in /etc/ssh/sshd_config:
Match Group sftpusers
    ChrootDirectory %h
    ForceCommand internal-sftp
    AllowTcpForwarding no
```

---

### 3.4 🔎 Continuous Vulnerability Scanning

Don't wait for an attacker to find your CVEs — find them first.

```bash
# Nessus (commercial, free for personal use via Nessus Essentials)
# OpenVAS — open source alternative
apt install openvas
gvm-setup
gvm-start

# Lynis — lightweight local security auditing
apt install lynis
lynis audit system
```

> 🎯 **What this stops:** a weekly or monthly vulnerability scan would have flagged vsftpd 2.3.4 and distcc as critical findings with public exploits, prompting immediate action.

---

### 3.5 📦 Verify Package Integrity — Detect Supply Chain Attacks

The vsftpd backdoor was a **supply chain attack**: the binary downloaded from the official site was replaced with a trojaned version. Package managers with cryptographic verification catch this automatically.

```bash
# Always install software from your distribution's official repos
apt install vsftpd    # Verified via GPG-signed package lists

# Verify integrity of a downloaded binary manually
sha256sum vsftpd-2.3.4.tar.gz
# Compare against the checksum published on the official site

# Check for unexpected modifications to installed packages
debsums vsftpd    # Reports files that differ from the package manifest
```

---

## 4. 🏰 Prevent Escalation and Persistence

*Attacks countered: SUID nmap shell escape, cron job persistence, reverse shell backdoor, systemd service implant, typosquatted process names*

An attacker who gains a low-privilege foothold should find every escalation path blocked and every persistence attempt detected.

---

### 4.1 ⚙️ Audit and Strip SUID Bits

The `nmap --interactive` root escape worked because Nmap had the SUID bit set — entirely unnecessary for a network scanner.

**Audit all SUID binaries:**
```bash
find / -perm -u=s -type f 2>/dev/null
```

**Remove SUID from non-essential binaries:**
```bash
chmod u-s /usr/bin/nmap
chmod u-s /usr/lib/pt_chown
chmod u-s /usr/bin/at
```

**Expected SUID binaries** (these are legitimate):

| ✅ Binary | 📌 Why it needs SUID |
|---------|-------------------|
| `/bin/su` | Switch user authentication |
| `/usr/bin/passwd` | Modify shadow file |
| `/usr/bin/sudo` | Run commands as another user |
| `/bin/ping` | Raw ICMP socket access |
| `/usr/bin/ssh-agent` | Privileged socket creation |

Everything else should be scrutinized and stripped unless you can justify it.

---

### 4.2 🔒 Restrict `sudo` Access

```bash
visudo

# Never allow ALL commands to regular users
# BAD:
msfadmin ALL=(ALL) ALL

# GOOD — whitelist only specific commands if sudo is needed:
msfadmin ALL=(ALL) /usr/bin/apt, /sbin/reboot
```

---

### 4.3 👁️ File Integrity Monitoring (FIM)

Persistence techniques write files to disk: cron entries, startup scripts, systemd units. A **File Integrity Monitor** detects these changes in real time.

**Install AIDE (Advanced Intrusion Detection Environment):**
```bash
apt install aide
aide --init
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# Run a check
aide --check
```

**Monitor critical paths with auditd:**
```bash
# Alert on any write to cron directories
auditctl -w /etc/cron.d -p wa -k cron_changes
auditctl -w /var/spool/cron -p wa -k cron_changes
auditctl -w /etc/rc.local -p wa -k startup_changes
auditctl -w /etc/systemd/system -p wa -k systemd_changes

# Alert on new SUID files
auditctl -a always,exit -F perm=u -F auid>=1000 -k suid_change
```

> 🎯 **What this stops:** the cron `@reboot` persistence would trigger an immediate alert the moment crontab was written. Security teams can investigate and remove the backdoor before the next reboot.

---

### 4.4 🌐 Block Reverse Shell Callbacks

The persistence payload opened an outbound connection from the target to the attacker's listener. **Egress filtering** is the control that breaks this:

```bash
# Default-deny outbound, allow only legitimate destinations
iptables -P OUTPUT DROP
iptables -A OUTPUT -d <trusted-update-server> -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT   # HTTPS
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
```

> Without an outbound path to the attacker's IP on port `1337` (or any other), the reverse shell payload starts, connects, and immediately fails. The backdoor exists but is functionally dead.

---

### 4.5 🔍 Monitor for Suspicious Processes and Typosquatting

The persistence script was named `postgress` to blend in with the legitimate `postgres` database process. Baseline monitoring catches this.

**Check for unexpected process names:**
```bash
ps aux --sort=-%cpu
# Look for processes with names very similar to known services
# postgres vs postgress, crond vs cron_d, sshd vs ssshd
```

**Use a process baseline tool:**
```bash
# Install and run chkrootkit or rkhunter periodically
apt install rkhunter
rkhunter --update
rkhunter --check

apt install chkrootkit
chkrootkit
```

**Set up automatic process anomaly detection** with a SIEM or EDR agent (Wazuh is a good open-source option):
```bash
apt install wazuh-agent
# Wazuh monitors process creation, file writes, and network connections
# and alerts on deviations from a known-good baseline
```

---

## 5. 📊 Summary — Attack → Defence Mapping

| 🔴 Attack | 🛠️ Tool Used | 🔵 Control That Stops It |
|----------|------------|-------------------------|
| Full port scan | Nmap `-p 1-65535` | Firewall default-deny; IDS scan detection |
| Service version fingerprinting | Nmap `-sV` | Minimize exposed services; suppress banners |
| SMB user enumeration | Nmap SMB scripts | Disable anonymous access; disable SMBv1 |
| OS fingerprinting via SMB | `smb-os-discovery` | Disable anonymous SMB; firewall 139/445 |
| SSH brute-force | Medusa | Key-based auth only; `fail2ban`; `MaxAuthTries 3` |
| Vulnerability scanning | Nmap vuln/vulners | Keep software patched; minimize exposed services |
| vsftpd backdoor (CVE-2011-2523) | `49757.py` | Remove vsftpd; replace with SFTP; verify package integrity |
| distcc RCE (CVE-2004-2687) | Nmap script + Metasploit | Disable distcc; firewall port 3632; patch immediately |
| Shadow file harvest | `cat /etc/shadow` | Correct permissions (`640`); SHA-512 hashing; `auditd` |
| NetCat file exfiltration | `nc` | Egress firewall; DLP monitoring |
| Password cracking | John the Ripper | Strong hashing (`sha512`, high rounds); complex passwords |
| SUID nmap shell escape | `nmap --interactive` | Remove SUID from non-essential binaries |
| Cron job persistence | `crontab -e @reboot` | FIM on cron dirs; `auditd`; regular crontab audits |
| Startup script persistence | `/etc/rc.local` | FIM on startup files; `auditd` watch on `/etc/rc.local` |
| Systemd service implant | `systemctl enable` | FIM on `/etc/systemd/system`; `auditd`; service baseline |
| Reverse shell callback | Python socket + `nc` | Egress firewall default-deny; network anomaly detection |
| Typosquatted process names | `postgress.sh` | Process baseline monitoring; `rkhunter`; Wazuh EDR |

---

## 6. 🏅 Security Hardening Checklist

Use this as a quick reference before deploying any Linux system:

### 🌐 Network
- [ ] Firewall with default-deny on all unused ports (inbound **and** outbound)
- [ ] All non-essential services disabled and removed
- [ ] SMBv1 disabled; anonymous SMB access forbidden
- [ ] FTP replaced with SFTP
- [ ] IDS/IPS deployed at network perimeter

### 🔐 Authentication
- [ ] SSH key-based authentication only (`PasswordAuthentication no`)
- [ ] Root login over SSH disabled
- [ ] `fail2ban` installed and configured for SSH (and other exposed services)
- [ ] Strong password policy enforced via PAM (`pwquality`)
- [ ] `/etc/shadow` uses SHA-512 with high round count

### 🩹 Patching
- [ ] Automatic security updates enabled (`unattended-upgrades`)
- [ ] No known CVEs with CVSS ≥ 7.0 on exposed services
- [ ] Regular vulnerability scans scheduled (Lynis, OpenVAS, Nessus Essentials)
- [ ] Package integrity verified for all externally downloaded software

### ⚙️ System Hardening
- [ ] SUID bits stripped from all non-essential binaries
- [ ] Principle of least privilege applied to all user and service accounts
- [ ] `auditd` configured with rules for shadow, cron, sudo, and SUID changes
- [ ] AIDE or equivalent FIM initialized and scheduled

### 👁️ Monitoring
- [ ] Centralized logging (SIEM) collecting auth logs, syslog, auditd
- [ ] Alerts on: brute-force attempts, new SUID files, cron changes, unexpected outbound connections
- [ ] Regular process baseline reviews
- [ ] `rkhunter` or `chkrootkit` scheduled weekly

---

> ## 🔵 The Defender's Mindset
>
> Every attack in this lab exploited one of three root causes:
>
> 1. 🏚️ **Outdated software** — vsftpd, distcc, OpenSSH 4.7p1, kernel 2.6.24
> 2. 🚪 **Unnecessary exposure** — 29 open ports, anonymous SMB, no firewall
> 3. ⚙️ **Misconfiguration** — SUID on nmap, weak passwords, no logging
>
> None of these require sophisticated zero-days. They all require **negligence**.
> Good security hygiene — patching, hardening, monitoring — makes the attacker's job dramatically harder at every step.
