T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/build_rc.py:55
- Finding
- Metasploit Resource Script Command Injection via Unvalidated Module and Payload Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/build_rc.py`, lines 55–62 **Vulnerability Type**: Metasploit resource-script command injection **Risk Level**: High ### Vulnerable Code ```python lines.append(f"use {args.module}") if args.rhosts: lines.append(f"set RHOSTS {quote_value(args.rhosts)}") if args.rport is not None: lines.append(f"set RPORT {args.rport}") if args.payload: lines.append(f"set PAYLOAD {args.payload}") ``` ### Technical Analysis The values supplied through `--module` and `--payload` are interpolated directly into Metasploit resource-script commands. Neither value is validated against the expected Metasploit module-path syntax, escaped, nor passed through `quote_value()`. An attacker who can influence the script arguments can include newline characters in either value. The newline terminates the intended `use` or `set PAYLOAD` command and introduces one or more additional commands into the generated `.rc` file. Metasploit resource scripts are subsequently intended to be executed using the documented command: ```bash msfconsole -q -r run.rc ``` Because `msfconsole` supports commands capable of invoking local operating-system commands, injected resource-script content can lead to arbitrary command execution under the identity of the operator running Metasploit. This is a generation-time injection vulnerability: creating the file does not itself execute the payload, but execution occurs when an operator follows the documented workflow and loads the generated resource script. ### Attack Path 1. An attacker gains control over, or convinces an operator to use, a crafted `--module` or `--payload` argument. 2. The malicious argument contains a valid-looking value followed by a newline and an additional Metasploit console command, such as a command that invokes a local shell. 3. `build_rc.py` writes the attacker-controlled text directly into the resource script. 4. The operator review ...[truncated 1481 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Strictly validate module and payload paths** Apply an allowlist that accepts only the syntax required for Metasploit identifiers. For example: ```python MODULE_RE = re.compile(r"^[A-Za-z0-9_./-]+$") ``` Reject values that do not match the allowlist before generating any output. If stricter syntax is practical, require known prefixes such as `exploit/`, `auxiliary/`, or recognized payload families. 2. **Reject command delimiters and control characters globally** Reject carriage returns, line feeds, NUL bytes, and other ASCII control characters in every user-controlled value written to the resource script. This protection should apply to `--module`, `--payload`, `--rhosts`, `--lhost`, `--targeturi`, `--workspace`, `--spool`, `--set`, and `--setg` values. ```python def reject_control_characters(value: str, field: str) -> None: if any(ord(ch) < 32 or ord(ch) == 127 for ch in value): raise ValueError(f"{field} contains prohibited control characters") ``` 3. **Use field-specific validation** Do not rely solely on generic quoting. Validate each argument according to its semantics: - Module and payload: constrained resource paths. - Ports: enforce the range `1–65535`. - Hosts: validate expected hostname, IP address, or CIDR syntax. - Option keys: retain the existing strict key allowlist. - File paths: reject line breaks and apply an explicit path policy where appropriate. 4. **Fail safely before writing output** Validate all arguments before creating parent directories or writing the resource file. On validation failure, return a nonzero status and avoid leaving a partial script. 5. **Add regression tests** Include tests proving rejection of: - `\n` and `\r\n` injection in module and payload arguments. - Control characters in all other string arguments. - Embedded resource-script commands. - Invalid module-path characters. - Out-of-ran ...[truncated 246 chars]
