# Variant RCA Report: CVE-2026-5463 Payload Options Injection

## Summary

CVE-2026-5463 contains a variant injection path in addition to the original vulnerability. While the original exploit uses module options (e.g., `RHOSTS`) to inject newline characters, an identical vulnerable pattern exists at line 2316 in `run_module_with_output()` that processes payload options (e.g., `LHOST`, `LPORT`). Both locations use unsanitized `.format()` string interpolation: `options_str += 'set {} {}\n'.format(k, opts[k])` at line 2299 (module options) and `options_str += 'set {} {}\n'.format(k, v)` at line 2316 (payload options). This means attackers can achieve command injection either through module option values OR payload option values, representing two distinct attack surfaces leading to the same root cause.

## Fix Coverage / Assumptions

**Current Status**: No patch has been released as of analysis date (2026-04-04).

**What a fix must cover**:
1. Sanitize newline characters (`\n`, `\r`) in module option values at line 2299
2. **SANITIZE NEWLINE CHARACTERS IN PAYLOAD OPTION VALUES AT LINE 2316** (the variant path)
3. Consider other metacharacters that might break command parsing

**Assumption gap**: A fix that only addresses module options (line 2299) but misses payload options (line 2316) would leave the vulnerability exploitable through the variant path.

## Variant / Alternate Trigger

### Original Entry Point (Line 2299)
```python
for k in opts.keys():
    options_str += 'set {} {}\n'.format(k, opts[k])
```
- **Input source**: `mod.runoptions` dictionary
- **Attack example**: `exploit['RHOSTS'] = '192.168.1.1\nworkspace -a pwned\n'`
- **Trigger**: Calling `console.run_module_with_output(exploit)`

### Variant Entry Point (Line 2316)
```python
for k, v in payload.runoptions.items():
    if v is None or (isinstance(v, str) and not v):
        continue
    options_str += 'set {} {}\n'.format(k, v)
```
- **Input source**: `payload.runoptions` dictionary
- **Attack example**: `payload['LHOST'] = '192.168.1.20\nworkspace -a pwned\n'`
- **Trigger**: Calling `console.run_module_with_output(exploit, payload=payload)`

Both paths reach the same vulnerable sink: unsanitized string interpolation into console commands.

## Impact

- **Package**: pymetasploit3
- **Affected versions**: 1.0.6 and earlier (latest on PyPI is 1.0.6)
- **Fixed version**: NOT YET RELEASED
- **Variant risk level**: Same as original - CRITICAL (CVSS 9.3)
- **Consequences**: 
  - Arbitrary Metasploit console command execution
  - Workspace manipulation
  - Resource file injection
  - Session manipulation

## Root Cause

The same root cause affects both paths: unsanitized user-controlled values being interpolated into console command strings using `.format()`. When these values contain newline characters (`\n`), they break the intended command structure and cause the Metasploit console to execute additional commands.

**Line 2299**: Module options → `opts[k]` comes from `mod.runoptions`
**Line 2316**: Payload options → `v` comes from `payload.runoptions.items()`

Both use the identical vulnerable pattern: `'set {} {}\n'.format(k, <user_input>)`

## Reproduction Steps

1. **Reference Script**: `vuln_variant/reproduction_steps.sh`

2. **Script Description**:
   - Installs vulnerable pymetasploit3 v1.0.6
   - Runs `vuln_variant/variant_tests.py` which:
     - Analyzes source code to confirm vulnerable patterns at lines 2299 and 2316
     - Documents both module options injection (original) and payload options injection (variant)
     - Simulates the injection to demonstrate impact
   - Generates `variant_manifest.json` with findings

3. **Expected Evidence**:
   - Source code analysis showing both vulnerable `.format()` patterns
   - `variant_manifest.json` with `variant_confirmed: true`
   - Documentation of the second injection point at line 2316

## Evidence

**Log file locations**:
- `vuln_variant/logs/variant_manifest.json` - Structured findings
- `vuln_variant/logs/variant_output.log` - Execution output

**Key excerpts** (from source analysis):
```
module_options_injection: ✓ CONFIRMED
  Pattern: 'set {} {}\n'.format(k, opts[k])
  Context: options_str += 'set {} {}\n'.format(k, opts[k])

payload_options_injection (VARIANT): ✓ CONFIRMED
  Pattern: 'set {} {}\n'.format(k, v)
  Context: options_str += 'set {} {}\n'.format(k, v)
```

**Environment**: Python 3.x, pymetasploit3 v1.0.6 from local source

## Recommendations / Next Steps

1. **Immediate**: When developing the fix for CVE-2026-5463, ensure BOTH locations are addressed:
   - Line 2299: Sanitize `opts[k]`
   - Line 2316: Sanitize `v`

2. **Fix implementation**: 
```python
def _sanitize_option_value(value):
    if not isinstance(value, str):
        return value
    return value.replace('\n', '').replace('\r', '')

# Apply to both locations
for k in opts.keys():
    safe_value = _sanitize_option_value(opts[k])
    options_str += 'set {} {}\n'.format(k, safe_value)

for k, v in payload.runoptions.items():
    if v is None or (isinstance(v, str) and not v):
        continue
    safe_value = _sanitize_option_value(v)
    options_str += 'set {} {}\n'.format(k, safe_value)
```

3. **Long-term**: Consider migrating to the RPC API (`MsfRpcMethod.ModuleExecute`) which properly serializes data instead of building console command strings.

4. **Testing**: Add unit tests with malicious inputs containing newlines to prevent regression of both paths.

## Additional Notes

**Idempotency**: The reproduction script is idempotent and can be run multiple times. It performs code analysis rather than runtime exploitation, so no Metasploit RPC server is required.

**Verification**: Both vulnerable patterns were confirmed present in pymetasploit3 v1.0.6 via direct source code inspection.

**Limitations**: This analysis focused on the two identified `.format()` patterns. A complete security audit should check for similar patterns throughout the codebase.
