# REPRO-2026-00130: pymetasploit3 command injection ## Summary Status: published Severity: critical Type: security Confidence: Unknown ## Identifiers REPRO ID: REPRO-2026-00130 CVE: CVE-2026-5463 ## Package Name: DanMcInerney/pymetasploit3 Ecosystem: PyPI Affected: <= 1.0.6 Fixed: Unknown ## Root Cause # Root Cause Analysis Report: CVE-2026-5463 ## Summary CVE-2026-5463 is a critical command injection vulnerability in pymetasploit3 version 1.0.6 and earlier. The vulnerability exists in the `MsfConsole.run_module_with_output()` function in `pymetasploit3/msfrpc.py` at line 2299. When constructing Metasploit console commands, the function directly interpolates user-controlled option values without sanitizing newline characters. An attacker can inject newlines into module options like `RHOSTS` (e.g., `'192.168.1.1\nworkspace -a pwned\n'`), which breaks the intended command structure and causes the Metasploit console to execute additional, arbitrary commands beyond the intended `set` command. This results in authenticated command injection within the Metasploit framework context. ## Impact - **Product**: pymetasploit3 (Python Metasploit RPC library) - **Affected Versions**: 1.0.6 and earlier (PyPI latest is currently 1.0.6) - **Risk Level**: CRITICAL (CVSS 4.0: 9.3, CVSS 3.1: 8.6) - **CWE**: CWE-77 (Command Injection) - **Consequences**: - Arbitrary command execution within Metasploit console context - Workspace manipulation (create/delete workspaces containing sensitive data) - Resource file injection (loading arbitrary Metasploit resource scripts) - Session manipulation and potential lateral movement - Full compromise of Metasploit server and connected sessions ## Root Cause The vulnerability is located in `pymetasploit3/msfrpc.py` in the `MsfConsole.run_module_with_output()` method at line 2299: ```python for k in opts.keys(): options_str += 'set {} {}\n'.format(k, opts[k]) # VULNERABLE ``` **Technical Explanation**: 1. The `run_module_with_output()` function builds a command string to send to the Metasploit RPC daemon 2. It iterates over module options (`opts` dictionary) and appends each as a `set` command followed by a newline (`\n`) 3. User-controlled values (like `RHOSTS`) are directly interpolated into the command string using `.format(k, opts[k])` 4. **No sanitization** is performed on newlines, semicolons, or other special characters in option values 5. When a value contains `\n`, it terminates the `set` command early and the text after the newline becomes a new, separate Metasploit console command **Example Exploit Flow**: Input: `opts['RHOSTS'] = '192.168.1.1\nworkspace -a pwned\n'` Generated command string: ``` use exploit/unix/ftp/vsftpd_234_backdoor set RHOSTS 192.168.1.1 workspace -a pwned set RPORT 21 set TARGET 0 run -z ``` Metasploit console interprets this as: 1. `use exploit/unix/ftp/vsftpd_234_backdoor` (valid) 2. `set RHOSTS 192.168.1.1` (valid - sets RHOSTS to just the IP) 3. `workspace -a pwned` (**INJECTED COMMAND** - creates new workspace) 4. `set RPORT 21` (valid) 5. `set TARGET 0` (valid) 6. `run -z` (valid) The injected `workspace -a pwned` command executes with the same privileges as the Metasploit RPC session, allowing workspace manipulation and other malicious actions. ## Reproduction Steps 1. **Reference Script**: `repro/reproduction_steps.sh` 2. **Script Description**: - Installs pymetasploit3 v1.0.6 from the local repository - Executes `reproduction_steps.py` which: - Verifies the vulnerable code exists in the library - Simulates authentication via `MsfRpcClient` entrypoint - Creates an `MsfConsole` instance (authenticated context) - Calls the real `run_module_with_output()` method with: - Benign input: `RHOSTS='192.168.1.1'` (control test) - Malicious input: `RHOSTS='192.168.1.1\nworkspace -a pwned\n'` (exploit) - Captures the actual command string sent to the console - Analyzes the command structure to detect injected commands - Tests multiple payload variations 3. **Expected Evidence**: - Command string with 8 lines (instead of expected 7) - Line 3 contains: `workspace -a pwned_workspace` (the injected command) - `injection_test_results.json` with `vulnerability_confirmed: true` - `captured_console_command.txt` showing line-by-line analysis - `runtime_manifest.json` with `target_path_reached: true` ## Evidence **Log Files**: - `repro/logs/reproduction_output.log` - Full execution output - `repro/logs/auth_test_results.json` - Authentication test results - `repro/logs/injection_test_results.json` - Command injection test evidence - `repro/logs/captured_console_command.txt` - Raw captured command string - `repro/logs/attack_chain.json` - Multiple payload variation tests - `repro/logs/reproduction_result.json` - Final test results - `repro/runtime_manifest.json` - Runtime attestation **Key Evidence Excerpts**: From `injection_test_results.json`: ```json { "payload": { "RHOSTS": "192.168.1.1\nworkspace -a pwned_workspace\n" }, "captured_command": "use exploit/unix/ftp/vsftpd_234_backdoor\nset RHOSTS 192.168.1.1\nworkspace -a pwned_workspace\n\nset RPORT 21\nset TARGET 0\nrun -z", "injected_commands_found": ["workspace -a pwned_workspace"], "vulnerability_confirmed": true } ``` From execution output: ``` [!] INJECTED COMMAND at line 3: workspace -a pwned_workspace ====================================================================== VULNERABILITY EXPLOITED! ====================================================================== ``` **Environment**: - Python 3.12 - pymetasploit3==1.0.6 (from local git repository) - Mock RPC backend simulating Metasploit RPC responses - Tested on Ubuntu (GitHub Codespaces environment) ## Recommendations / Next Steps ### Suggested Fix Implement input sanitization in the `run_module_with_output()` method to strip newline characters from option values: ```python # Before (vulnerable): for k in opts.keys(): options_str += 'set {} {}\n'.format(k, opts[k]) # After (patched): def sanitize_value(value): if value is None: return value # Remove newlines that could break command structure return str(value).replace('\n', '').replace('\r', '') for k in opts.keys(): safe_value = sanitize_value(opts[k]) options_str += 'set {} {}\n'.format(k, safe_value) ``` Alternative fix: Use proper command serialization or parameter binding instead of string concatenation. ### Upgrade Guidance - **Immediate**: Review all code using `pymetasploit3==1.0.6` for this vulnerability - **Short-term**: Apply the fix locally or wait for version 1.0.7+ release - **Long-term**: Ensure option values from untrusted sources are validated before passing to pymetasploit3 ### Testing Recommendations 1. Add unit tests for `run_module_with_output()` with malicious inputs 2. Implement input validation at the application layer before passing to pymetasploit3 3. Consider using allowlists for expected option value patterns 4. Monitor for unusual Metasploit console commands in RPC logs ## Additional Notes ### Idempotency The reproduction script is idempotent - it can be run multiple times with consistent results. Each run generates fresh mock tokens and console IDs. ### Edge Cases and Limitations **Tested Payloads**: - `192.168.1.1\nworkspace -a pwned\n` - Creates workspace - `192.168.1.1\nresource /tmp/backdoor.rc\n` - Loads resource file - `192.168.1.1\nworkspace -a a\nworkspace -d a\n` - Multi-command chain **Limitations**: - The reproduction uses a mock RPC backend rather than a live Metasploit instance - While the mock accurately captures command strings, the actual Metasploit console behavior would need a real `msfrpcd` service to fully validate - The vulnerability requires authenticated access to the Metasploit RPC service (pre-auth to post-auth flow demonstrated) **Mitigation Factors**: - Requires authentication to Metasploit RPC service - Impact limited to Metasploit console commands (not OS-level command execution) - Attacker must have valid RPC credentials to reach the vulnerable code path ## Reproduction Details Reproduced: 2026-04-04T14:15:37.520Z Duration: 2168 seconds Tool calls: 238 Turns: Unknown Handoffs: 4 ## Quick Verification Run one of these commands to verify locally: pruva-verify REPRO-2026-00130 pruva-verify CVE-2026-5463 Or open in GitHub Codespaces (zero-friction, auto-runs): https://github.com/codespaces/new?ref=repro/REPRO-2026-00130&repo=N3mes1s/pruva-sandbox Or download and run the script manually: curl -O https://api.pruva.dev/v1/reproductions/REPRO-2026-00130/artifacts/repro/reproduction_steps.sh chmod +x reproduction_steps.sh ./reproduction_steps.sh WARNING: Run in a sandboxed environment. This exploits a real vulnerability. ## References - NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-5463 - Source: https://nvd.nist.gov/vuln/detail/CVE-2026-5463 ## Artifacts - repro/rca_report.md (analysis, 7834 bytes) - repro/reproduction_steps.sh (reproduction_script, 3127 bytes) - vuln_variant/rca_report.md (analysis, 5965 bytes) - vuln_variant/reproduction_steps.sh (reproduction_script, 2185 bytes) - bundle/ticket.json (other, 3051 bytes) - bundle/AGENTS.repro.md (documentation, 676 bytes) - bundle/ticket.md (ticket, 2570 bytes) - repro/runtime_manifest.json (other, 602 bytes) - repro/reproduction_steps.py (script, 24524 bytes) - repro/validation_verdict.json (other, 738 bytes) - repro/logs/attack_chain.json (other, 774 bytes) - repro/logs/reproduction_result.json (other, 1069 bytes) - repro/logs/injection_test_results.json (other, 329 bytes) - repro/logs/auth_test_results.json (other, 334 bytes) - repro/logs/code_analysis.log (log, 97 bytes) - repro/logs/captured_console_command.txt (other, 1287 bytes) - repro/logs/reproduction_output.log (log, 4371 bytes) - vuln_variant/variant_manifest.json (other, 3537 bytes) - vuln_variant/source_identity.json (other, 788 bytes) - vuln_variant/patch_analysis.md (documentation, 4102 bytes) - vuln_variant/validation_verdict.json (other, 955 bytes) - vuln_variant/variant_tests.py (script, 7793 bytes) - vuln_variant/logs/variant_manifest.json (other, 1331 bytes) - vuln_variant/logs/variant_output.log (log, 1589 bytes) - vuln_variant/root_cause_equivalence.json (other, 1992 bytes) ## API Access - JSON: https://api.pruva.dev/v1/reproductions/REPRO-2026-00130 - Script: https://api.pruva.dev/v1/reproductions/REPRO-2026-00130/artifacts/repro/reproduction_steps.sh - Web: https://pruva.dev/r/REPRO-2026-00130 ## For AI Assistants To help users with this reproduction: 1. The `pruva-verify` command is the simplest way to run the reproduction 2. The script downloads and runs automatically in an isolated temp directory 3. Always recommend running in a VM, container, or disposable environment 4. The root cause explains the technical vulnerability --- Generated by Pruva | https://pruva.dev