Binwalk Path Traversal Vulnerability: Turning Firmware Analysis into Code Execution

The Bug That Turns Security Tools Against Researchers

I found a bug in binwalk that lets an attacker write files anywhere on your computer. If you are a security researcher, you have probably used binwalk to pull apart firmware files. It comes pre-installed on Kali Linux. Hundreds of thousands of people use it every day.

The bug is simple. When binwalk extracts files from a Windows CE firmware image, it reads the filename straight from the binary and uses it to create a file on disk. It never checks whether that filename contains something like “../../” to escape the folder. So a specially crafted firmware image can write files to any location the user has access to.

What makes this worse is that binwalk has a plugin system. It automatically runs any Python file placed in ~/.config/binwalk/plugins/. So an attacker can use this path traversal to drop a malicious Python script into that folder. The next time the victim runs binwalk on anything, the script runs with their privileges. That is how a simple file-write bug becomes Remote Code Execution (RCE).

Vulnerability Summary and Impact

The vulnerability is tracked as CVE-2026-7179. It is a path traversal bug (CWE-22) in binwalk’s WinCE ROM extraction plugin. Here are the key details:

  • Product: binwalk (Python version)
  • Affected versions: 2.4.3 and all earlier versions that include the WinCE plugin
  • Vulnerable files: winceextract.py (lines 61, 64) and winceextractor.py (line 580)
  • Bug type: CWE-22: Path Traversal
  • Impact: Arbitrary file write, escalating to Remote Code Execution
  • NVD CVSS v3.1 : 5.3 MEDIUM (AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L)

This matters because binwalk v2.4.3 is still the default binwalk on every Kali Linux installation. Security researchers, CTF players, and firmware analysis pipelines rely on it. The irony is that the tool meant to analyze firmware can itself be weaponized through a malicious firmware image.

The binwalk repository has been archived since November 2024 and the maintainers have confirmed no further patches will be released for the Python version. Despite this, it remains the default firmware analysis tool on one of the most widely used penetration testing distributions in the world. Users who have not manually installed binwalk v3 (the Rust rewrite) are exposed.

What Led Me to This Target

I was not looking for this bug on a client engagement or as part of any formal project. I had some free time over a weekend and was going through old CVE advisories out of curiosity. I had never actually used binwalk myself, but I kept hearing about it from friends in the security community. It seemed to come up every time someone talked about firmware analysis or CTF challenges. A tool that popular, used by that many researchers, felt like it was worth understanding better, even if just by reading its source code.

While reading through old advisories, I came across CVE-2022-4510, the path traversal that the ONEKEY team found in binwalk’s PFS extraction plugin (unpfs.py). Their writeup was well done. The pattern was simple: filenames read from a firmware binary were passed directly to file operations without any sanitization. The fix they applied was straightforward: an os.path.basename() call and a startswith() boundary check.

What caught my attention was the scope of that fix. It patched one plugin. binwalk has several extraction plugins, and each one reads filenames from binary data in its own way. My question was straightforward: did anyone check the other plugins for the same bug? If the developers missed path sanitization in one parser, they probably missed it in others.

I cloned the binwalk repository and started looking. It felt like the kind of thing that would either take five minutes to confirm as already fixed, or five minutes to confirm as still broken.

Finding the Vulnerability Through Source Code Review

I did not use fuzzing for this. The bug class was already known from CVE-2022-4510, so I just needed to trace how filenames flow from binary parsers to file system operations across the other plugins.

I searched the plugins directory for os.path.join calls where the second argument came from parsed binary data. winceextract.py stood out immediately. Here is the entire extractor function (lines 44 to 65):

Lines 61 and 64 are the problem. Both take a filename (module.file_name or file_e.file_name) and join it with the extraction directory (indir) to build an output path. There is no check on what that filename contains.

Where does that filename come from? I traced it to winceextractor.py, line 580, where it gets set from a function called read_null_terminated_string():

And here is what read_null_terminated_string() does (line 454):

It just reads raw bytes from the ROM binary until it hits a null byte and decodes them as ASCII. No filtering, no validation, nothing. If an attacker puts “../../../some/path” as a filename in the ROM, that string goes through unchanged.

The full data flow is:

Three steps from attacker-controlled input to writing a file anywhere on disk. No os.path.basename(), no startswith() boundary check, no sanitization of any kind. The exact same pattern that CVE-2022-4510 fixed in unpfs.py, just in a different plugin that nobody checked.

Challenges in Building the Proof of Concept

Finding the bug took an afternoon. Building a working proof of concept took longer.

The WinCE ROM format is not well documented. I had to reverse-engineer the struct offsets by reading the WinCEExtractor parser code and matching each struct.unpack call to its position in the binary. The ROM format has a signature (0x43454345) at offset 64, then a ROMHDR structure that tells the parser how many modules and files exist, followed by file entries that each point to a filename string and file data.

My first three ROM builds failed silently. The parser would run without errors but find zero files. The problem was that the load offset, the ROMHDR pointer, and the file entry pointer are all interdependent. The parser uses the load offset to recalculate all other addresses. Getting even one value wrong meant the parser would read garbage for the file count or miss the filename entirely.

Disclosure was also tricky. The binwalk repository 2.4.3 was archived in November 2024. No issues, no pull requests, no security advisories can be filed. No SECURITY.md file exists. I found the maintainer’s public email on their GitHub profile and sent a detailed report. They acknowledged the bug but confirmed no patch would come since the Python version is end-of-life.

How the Exploit Works

Once I got the ROM structure right, the exploit was straightforward. You build a minimal valid WinCE ROM where the embedded filename contains directory traversal sequences. When someone runs binwalk -e on it, the file gets written wherever the filename points.

The key was making the load_offset equal to zero. The parser calculates this value by subtracting two numbers stored in the ROM header. By setting both to the same value, the subtraction gives zero, and all pointers in the ROM become direct byte positions. This made crafting the binary much simpler than working with a non-zero offset where every pointer needs manual adjustment.

For example, setting the filename to:

  • ../../../../../../etc/cron.d/backdoor writes a cron job
  • ../../../home/user/.ssh/authorized_keys injects SSH keys
  • ../../../home/user/.bashrc modifies shell startup

The RCE part works because binwalk auto-loads every .py file in ~/.config/binwalk/plugins/. By setting the filename to ../../../home/user/.config/binwalk/plugins/malicious.py, you can drop a plugin like this:

The realistic attack scenario: someone downloads a firmware image for analysis, runs binwalk -e, and the WinCE plugin silently drops a Python file into the plugins folder. The next time they run binwalk on any file, the malicious plugin executes. The victim never sees anything unusual.

Here is my proof of concept running in a sandbox:

Steps 1-3: Creating a sandbox, building the malicious ROM, and running the extractor

Step 4: Path traversal confirmed. The file was written outside the extraction directory.

Step 5: RCE confirmed. A malicious .py file was planted in the binwalk plugins directory.

Step 6: Sandbox cleaned up. Both path traversal and RCE confirmed.

Disclosure Timeline

  • 2020-11-13: winceextract.py plugin added to binwalk
  • 2026-04-09: Vulnerability discovered
  • 2026-04-10: Reported to maintainer via email
  • 2026-04-27: CVE-2026-7179 assigned

The maintainer acknowledged the bug but said no patch would be released because the Python version has reached end-of-life. The repository is archived and there is no way to file issues or pull requests. I went ahead with public disclosure because binwalk v2.x is still shipped with Kali and people need to know it has this risk.

The suggested fix is the same approach used for CVE-2022-4510. You strip the filename down to just the file part using os.path.basename() and then check it stays inside the extraction directory:

What You Should Do About This

If you use binwalk v2.x, switch to binwalk v3.x (the Rust rewrite). The Rust version handles path sanitization in one central place using a Chroot architecture, so individual plugins cannot have this kind of bug. It is not just a fix for this one CVE; it removes the entire bug class by design.

If you cannot migrate immediately, consider applying the suggested fix above as a local patch. It is only a few lines in winceextract.py. That said, the WinCE plugin is not the only one worth auditing. I only looked at winceextract.py because it was the most obvious candidate, but other extraction plugins in the same codebase may have similar issues. Anyone still maintaining a fork should review every plugin that reads filenames from binary data.

If you run binwalk in automated pipelines or CI/CD, treat firmware extraction like running untrusted code. Use containers, limit filesystem access, and watch for files being written outside the expected extraction directory.

For detection, monitor ~/.config/binwalk/plugins/ for new .py files. Any Python file appearing there after a binwalk extraction that the user did not put there is a strong signal of this attack. You could set up inotifywait or a similar file monitoring tool on that directory to trigger an alert.

More broadly, when a path traversal is found and fixed in one component of a tool, check every other component that does similar work. CVE-2022-4510 was fixed in unpfs.py in 2022. The exact same bug in winceextract.py sat there for four more years. A fix in one parser should always trigger a review of the others.

Final Thoughts

This was not a complicated bug. A missing os.path.basename() call in a plugin that reads filenames from firmware binaries, combined with an auto-loading plugin system, turns a simple file-write into code execution. The people most likely to hit this are security researchers analyzing firmware, which makes it an especially ugly attack vector.

If your organization works with firmware, IoT devices, or embedded systems, Payatu’s IoT Security Assessment and Product Security Assessment services can help find bugs like this before they become a problem.

References

Subscribe to our Newsletter
Subscription Form

DOWNLOAD THE DATASHEET

Fill in your details and get your copy of the datasheet in few seconds

DOWNLOAD THE EBOOK

Fill in your details and get your copy of the ebook in your inbox

Ebook Download

DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download ICS Sample Report

DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Cloud Sample Report

DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download IoT Sample Report

DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Code Review Sample Report

DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Red Team Assessment Sample Report

DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download AI/ML Sample Report

DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download DevSecOps Sample Report

DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Product Security Assessment Sample Report

DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Mobile Sample Report

DOWNLOAD A SAMPLE REPORT

Fill in your details and get your copy of sample report in few seconds

Download Web App Sample Report

Let’s make cyberspace secure together!

Requirements

Connect Now Form

What our clients are saying!

Trusted by