Recently, F5, a major load balancer vendor, disclosed a vulnerability. From reading their disclosure, they noted that it was a heap-based buffer overflow, has been actively exploited, and is present in many major versions. This is the vulnerability and how the authors of this post reverse-engineered the patch to find the issue.
They opened up the code in a diff editor. The patch ended up being a pretty simple bounds check. In particular, a buffer of size 0x4100 is created, the value of the Authorization header is copied into that buffer. Sending a large amount of A's just crashes the server. So, this bug is pre-authentication. Crazy!
The system has ASLR enabled, stacks canaries, partial RELRO, and NX. Even with these binary protections, it was missing one: PIE. This means that the binary address itself was not randomized so ROP was on the table if they could control RIP. While fuzzing around, they noticed that about 90% of the time a function pointer was on the heap a ways passed the buffer.
After finding some stack pivoting gadgets to clean things up, they were able to do the classic ret2plt chain to call execvp. This executed on the machine but they hit a SELinux roadblock that gave them access denied.
The initial exploit payload they wrote tried to write a file to the system and write a file to the web server for a reverse shell, but both of these failed because of SELinux. They figured out that the process that crashed was from /etc/bigstart/scripts/tmm.finish. So, they decided to use their ret2plt to open this bash script and add their file write/shell to it instead.
Now, SELinux no longer crashes. The next time the script was loaded, it executed the attacker's commands. Defense-in-depth doesn't matter until it REALLY does. So, it's important to take these things seriously.
Overall, a good blog post on a simple bug, a routine exploit, and a fun SELinux bypass. Good work!