CVE-2026-87690
Executive Summary
CVE-2026-87690 is a relative path traversal vulnerability (CWE-22) in the Metasploit Framework post-exploitation module post/apple_ios/gather/ios_image_gather. The module interpolates filenames from a Meterpreter directory listing on a hostile or tampered iOS device directly into the local destination path passed to client.fs.file.download_file(), permitting an attacker-controlled device to escape the intended loot directory and overwrite files in the operator's ~/.msf4/ configuration tree. Because the overwritten msfconsole.rc resource file is automatically executed on every msfconsole startup, this arbitrary file write escalates to persistent code execution and an interactive shell as the operator (frequently root) on the penetration tester's workstation.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The flaw resides in a Metasploit post module rather than in the target-facing payload. The module post/apple_ios/gather/ios_image_gather enumerates files on a connected iOS device through a Meterpreter session and retrieves them to the operator's local loot directory. The critical property of this data flow is trust asymmetry: the directory listing is fully controlled by the iOS device, which may be hostile, jailbroken, or otherwise tampered with, yet the module treats each returned filename as a safe local filename.
The module builds a local destination path and passes it to client.fs.file.download_file(). No sanitization is performed on the listing entry before it is interpolated into that destination path. The underlying stdapi sink at lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb writes to whatever path it is supplied, performing no traversal validation of its own. A listing entry containing relative traversal sequences — for example ../../msfconsole.rc — therefore resolves outside the intended ~/.msf4/loot/<random> directory and lands in ~/.msf4/msfconsole.rc. This is a classic relative path traversal (CWE-22) where the attacker-controlled component is a filename from a remote enumeration response, not a user-supplied HTTP parameter.
The impact of the overwrite is disproportionate to the apparent severity of "an overwritten config file." ~/.msf4/msfconsole.rc is a Metasploit resource script that lib/msf/ui/console/driver.rb:196 automatically executes at startup for every msfconsole invocation. Anything written into that file therefore executes as the operator. The NVD description further notes that the written msfconsole.rc can load a second written file — a Ruby plugin whose top-level code runs on require — which removes the practical limitation of resource-script syntax and yields a genuine interactive shell as the operator. Because Metasploit operators commonly run the console as root, the resulting privilege level is frequently root.
The NVD description explicitly notes that an equivalent traversal had already been remediated upstream in the recursive downloader, where stdapi/fs/dir.rb scrubs path separators. The ios_image_gather module simply omitted the equivalent scrub, making this a re-introduction of a known-safe pattern rather than a novel class of bug. The stated fix is to apply the same separator scrub — or File.basename — to listing entries before constructing the local path. No patch evidence is available from any tracked source, so the vulnerability should be treated as unpatched.
Exploitation Scenarios
No public PoC is available; the attack chain below is described strictly from the NVD description and the vulnerability class. No function names, endpoints, or paths beyond those stated in the description are asserted.
Reconnaissance / target identification. The attacker requires an operator to run the
post/apple_ios/gather/ios_image_gathermodule against an attacker-controlled or tampered iOS device. This is a social-engineering precondition: the device must be in scope for the engagement, lent to the tester, or otherwise accepted as a legitimate target. The attacker does not need network access to the operator's workstation and needs no credentials there.Triggering the flaw class. When the module enumerates the device's filesystem, the hostile device returns a directory listing. The attacker embeds a filename containing relative traversal sequences — the description's example is
../../msfconsole.rc. Because the module interpolates that entry into the local destination path without sanitization, the traversal escapes the intended~/.msf4/loot/<random>directory.Payload / execution method. The file content downloaded overwrites
~/.msf4/msfconsole.rc. When the operator next launchesmsfconsole,lib/msf/ui/console/driver.rb:196automatically executes that resource file. The description states that the writtenmsfconsole.rccan in turn load a second written Ruby plugin file; the plugin's top-level code runs onrequire, giving the attacker a fully interactive shell as the operator instead of being limited to resource-script syntax.Post-exploitation impact. Execution occurs as the operator account, which is frequently root for Metasploit workstations, and it is persistent — the overwritten resource file is re-executed at every console launch until cleaned. The operator's workstation typically holds client loot, captured credentials, SSH keys, cloud tokens, and network access into client environments, so the blast radius extends well beyond a single engagement.
An important nuance of this attack is that the malicious content is not delivered by the target device as "malware" but as routine loot from a trusted penetration-testing tool. Operators rarely inspect the contents of looted files, and the malicious behavior only manifests at the next console startup, so detection relies on file-integrity monitoring and process telemetry rather than on user vigilance.
Impact Assessment
CVSS 3.1 base score 8.8 (High), vector CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H.
- AV:N (Network) — the hostile input arrives over the Meterpreter session from a remote device; no local access to the operator's host is needed.
- AC:L (Low) — no special conditions or race are required; a single crafted listing entry succeeds.
- PR:N (None) — the attacker needs no privileges on the operator's system.
- UI:R (Required) — the operator must run the affected gather module against the attacker's device, which is the sole barrier to exploitation.
- S:U (Unchanged) — impact is confined to the vulnerable component (the operator workstation running Metasploit).
- C:H / I:H / A:H — full compromise of confidentiality, integrity, and availability on the operator's host: code execution as the operator, writes to arbitrary accessible paths, and persistent tampering with the toolchain.
The blast radius is concentrated on the security team itself. A compromise of an operator's workstation grants access to engagement data, client credentials, internal network reachable from that host, and any stored secrets. Because the initial foothold is delivered through the security tooling pipeline, EDR and integrity controls that normally protect production systems are frequently absent or poorly tuned on tester workstations. The vulnerability also undermines client trust in engagements performed with an affected Metasploit version. No EPSS score has been published by FIRST.org and no CISA KEV entry exists at time of writing.
Detection Guidance
Sigma Rule
title: Metasploit ios_image_gather Path Traversal Overwrite of msfconsole.rc
id: 9f1c2a44-8b7e-4c1d-9a02-8a2f5c7b1e23
status: experimental
description: Detects writes of the Metasploit resource file ~/.msf4/msfconsole.rc or loot directory escapes consistent with CVE-2026-87690.
author: valtersit.com
logsource:
category: file_event
product: linux
detection:
selection_target:
TargetFilename|endswith:
- '/.msf4/msfconsole.rc'
- '\\.msf4\\msfconsole.rc'
selection_writer:
Image|endswith:
- '/ruby'
- '/msfconsole'
- '/ruby.exe'
condition: selection_target and selection_writer
falsepositives:
- Legitimate operator configuration of msfconsole.rc
level: high
tags:
- attack.t1195
- cve.2026.87690
YARA Rule
rule CVE_2026_87690_IOS_IMAGE_GATHER_TRAVERSAL
{
meta:
author = "valtersit.com"
description = "Detects traversal-bearing filenames and msfconsole.rc overwrite artifacts associated with CVE-2026-87690"
reference = "CVE-2026-87690"
date = "2026-01-01"
strings:
$traversal1 = "../../msfconsole.rc"
$traversal2 = "..\\..\\msfconsole.rc"
$module1 = "ios_image_gather"
$loot1 = ".msf4/loot/"
$sink1 = "fs.file.download_file"
condition:
(any of ($traversal1, $traversal2)) or
($module1 and any of ($loot1, $sink1))
}
Suricata IDS Rule
alert tcp any any -> any any (msg:"CVE-2026-87690 Metasploit ios_image_gather Path Traversal Filename"; flow:established,to_client; content:"../../msfconsole.rc"; nocase; sid:2026876900; rev:1; reference:cve,2026-87690; classtype:attempted-user; metadata:affected_product Metasploit, attack_target Workstation, deployment Perimeter, signature_severity Major, created_at 2026_01_01;)
Elastic Detection
file where event.action in ("creation", "modification", "rename") and
file.path like~ "*/.msf4/msfconsole.rc" and
process.name in ("ruby", "msfconsole", "ruby.exe")
Splunk SPL Query
index=endpoint OR index=edr (EventCode=11 OR event.action="file_write" OR event.action="file_modified")
(TargetFilename="*/.msf4/msfconsole.rc" OR TargetFilename="*\\.msf4\\msfconsole.rc")
(Image="*ruby*" OR Image="*msfconsole*")
| stats count min(_time) as first_seen max(_time) as last_seen by host, user, Image, TargetFilename, ProcessId
| convert ctime(first_seen) ctime(last_seen)
Wazuh OSSEC Rule
<group name="msf_exploit,">
<rule id="100901" level="12">
<if_sid>550</if_sid>
<field name="file">\.msf4/msfconsole\.rc$</field>
<description>CVE-2026-87690: Metasploit msfconsole.rc modified - possible path traversal via ios_image_gather</description>
<mitre>
<id>T1195</id>
</mitre>
</rule>
<rule id="100902" level="10">
<if_sid>550</if_sid>
<field name="file">\.msf4/loot/.*\.\./</field>
<description>CVE-2026-87690: traversal sequence detected in Metasploit loot path</description>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source).
Immediate mitigations
- Avoid running
post/apple_ios/gather/ios_image_gatheragainst devices that are not fully trusted and physically controlled, especially in engagements where a device is supplied by a third party. - Make
~/.msf4/msfconsole.rcand the containing directory immutable where operationally feasible (e.g.,chattr +ion Linux) so an overwrite attempt fails rather than silently succeeding. - Monitor the loot directory and
~/.msf4/for unexpected writes and for traversal sequences in local filenames. - Run Metasploit as a dedicated unprivileged account rather than root, to reduce the privilege level obtained by any successful exploitation.
- Avoid running
Patch/upgrade steps
- Apply the fix described in the NVD entry, which scrubs path separators or applies
File.basenameto listing entries before building the local destination path, mirroring the existing mitigation already present in the recursive downloader (stdapi/fs/dir.rb). - Track the Metasploit Framework repository for the commit implementing this scrub; no vendor advisory or release reference is available from tracked sources at this time. Until such a reference exists, treat all versions as affected.
- After upgrading, verify by testing that a crafted listing entry containing
../no longer escapes the intended~/.msf4/loot/<random>directory.
- Apply the fix described in the NVD entry, which scrubs path separators or applies
Long-term hardening
- Treat all data returned from a compromised or untrusted target as adversarial at every layer of the toolchain, including enumeration responses, not merely payload output.
- Adopt a general policy of basename-plus-allowlist validation for any filename used to construct a local path from remote data.
- Apply file-integrity monitoring to security-tool configuration directories on operator workstations, and restrict write permissions to those paths.
- Encourage independent review of post modules for similar unsanitized filename interpolation, since this instance reflects an omitted scrub that already exists elsewhere in the same codebase.
References
- NVD — CVE-2026-87690: https://nvd.nist.gov/vuln/detail/CVE-2026-87690
- CWE-22: Improper Limitation of a Pathname to a Restricted Directory ("Path Traversal"): https://cwe.mitre.org/data/definitions/22.html
- FIRST EPSS: not yet scored — https://www.first.org/epss/
- CISA Known Exploited Vulnerabilities Catalog: no entry exists for this CVE — https://www.cisa.gov/known-exploited-vulnerabilities-catalog
- MITRE ATT&CK T1195 Supply Chain Compromise: https://attack.mitre.org/techniques/T1195/
No public proof-of-concept, exploit code, Nuclei template, or evidence of in-the-wild exploitation or named threat actor campaigns is available for CVE-2026-87690 at the time of writing.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.