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!