Rogue/linpeas_light.py
2026-05-31 04:12:58 +00:00

327 lines
13 KiB
Python

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