Full Report
Openwrt is open source router firmware. While the researcher was updating their router, they noticed that there was a service called attended sysupgrade that builds and hosts the firmware remotely. So, they decided to take a look into it. Why look at this though? Building a firmware image from user-provided packages is very dangerous because of the amount of control a user has over this process. Proper isolation must be done as well. The first goal was getting code execution within the context of the container. There is a Makefile that is used to build the router firmware. The make command will expand shell variables before executing a command. Since the package name is controlled by the user and set as an environment variable, this can be used to execute arbitrary bash commands on the server. To me, this is somewhat by design though. When building user controlled code, there is going to be a way to execute arbitrary code. Of course, this is why the code runs in a container. Regardless, the make command expanding the variables before executing as bash was interesting to me! When determining if a build is unique or not, the method is generating a hash of the request. While reviewing this code, they noticed that the package hash being used was truncated to only 12 characters of hex - 2^48 of entropy! 48 bits is vulnerable to brute force attacks. The idea is to create a cache key collision by brute forcing the algorithm until we can create something where the 12 characters match the other builds. Once successful, the build will override the other build, resulting in users pulling the wrong firmware. They wanted to prove that this could be brute forced. They attempted to write their own OpenCL program to brute force using the GPU but it was very slow. To get partial hash match support they make a quick patch to hashcat. They played around with the settings until it was running fast and using the proper characters. Eventually, it was running at 18 billion hashes with a collision being found within an hour. Once they found the issue, the openwrt team fixed and released a version in 3 hours. Overall, a super interesting vulnerability and exploitation of a crypto-usage issue. Good finds!
Analysis Summary
# Vulnerability: OpenWrt Attended Sysupgrade Supply Chain Compromise
## CVE Details
- **CVE ID**: CVE-2024-54133 (Command Injection), CVE-2024-54134 (Truncated Hash Collision)
- **CVSS Score**: 9.1 (Critical) - *Estimated based on supply chain impact*
- **CWE**: CWE-78 (OS Command Injection), CWE-326 (Inadequate Encryption Strength)
## Affected Systems
- **Products**: OpenWrt Attended Sysupgrade Server (`asu`)
- **Versions**: Versions prior to the fix released on December 6, 2024.
- **Configurations**: Any instance of the `asu` build server allowing user-defined packages for firmware generation.
## Vulnerability Description
Two distinct flaws were identified in the `sysupgrade.openwrt.org` infrastructure that, when combined, allow for a complete supply chain compromise:
1. **Command Injection via Makefile**: The server uses a containerized environment to run `make` commands for firmware builds. The `PACKAGES` variable, which contains user-provided package names, is passed directly into a sub-shell call within the Makefile. Because `make` expands variables before shell execution, an attacker can inject arbitrary bash commands (e.g., `' ; whoami #`).
2. **Truncated SHA-256 Collision**: The build server caches firmware images based on a hash of the build request. This hash was truncated to only 12 hex characters (48 bits). This provides only $2^{48}$ entropy, which is susceptible to brute-force attacks.
## Exploitation
- **Status**: PoC demonstrated by researcher; remediated by vendor.
- **Complexity**: Medium (Requires GPU resources for hash brute-forcing).
- **Attack Vector**: Network.
An attacker can generate a collision where a "malicious" build request (containing the command injection payload) produces the same 12-character truncated hash as a "legitimate" build request. By submitting the malicious request first, the poisoned firmware is cached. When a legitimate user requests that specific configuration, the server serves the attacker's poisoned image from the cache.
## Impact
- **Confidentiality**: High (Ability to execute code within the build container).
- **Integrity**: Critical (Attackers can overwrite legitimate firmware images with malicious versions).
- **Availability**: High (Service was temporarily taken offline for remediation).
## Remediation
### Patches
- **OpenWrt/asu**: Fixed in the latest commit on Dec 6, 2024. The fix involved increasing the hash length and sanitizing package inputs to prevent shell injection.
### Workarounds
- Users are advised to verify the checksums of any firmware downloaded during the vulnerable window and monitor for unusual router behavior.
## Detection
- **Indicators of Compromise**: Monitor for unexpected outbound connections from the `asu` build containers or unusual package names in build logs containing characters like `;`, `$()`, or `` ` ``.
- **Detection Methods**: The OpenWrt team released an announcement for users to check device integrity. Security teams can audit `asu` server logs for hash collisions or failed build attempts with suspicious package strings.
## References
- **Vendor Advisory**: [http://lists.openwrt.org/pipermail/openwrt-announce/2024-December/000061.html]
- **Research Blog**: [https://flatt.tech/research/posts/compromising-openwrt-supply-chain-sha256-collision/]
- **Source Code**: [https://github.com/openwrt/asu]