Carrot disclosure
Fri 08 March 2024 — download

Once you have found a vulnerability, you can either sit on it, or disclose it. There are usually two ways to disclose, with minor variations:

  1. Coordinated Disclosure, where one gives time to the vendor to issue a fix before disclosing
  2. Full Disclosure, where one discloses immediately without notifying anyone before.

I would like to coin a 3rd one: Carrot Disclosure, dangling a metaphorical carrot in front of the vendor to incentivise change. The main idea is to only publish the (redacted) output of the exploit for a critical vulnerability, to showcase that the software is exploitable. Now the vendor has two choices: either perform a holistic audit of its software, fixing as many issues as possible in the hope of fixing the showcased vulnerability; or losing users who might not be happy running a known-vulnerable software. Users of this disclosure model are of course called Bugs Bunnies.

We all looked at catastrophic web applications, finding a ton of bugs, and deciding not to bother with reporting them, because they were too many of them, because we knew that there will be more of them lurking, because the vendor is a complete tool and it would take more time trying to properly disclose things than it took finding the vulnerabilities, … This is an excellent use case for Carrot Disclosure! Of course, for unauditably-large codebases, it doesn't work: you've got a Linux LPE, who cares.

Interestingly, it shifts the work balance a bit: it's usually harder to write an exploit than it's to fix here. But here, the vendor has to audit and fix its entire codebase, for the ~low cost of one (1) exploit, that you don't even have to publish if you don't want to. It also has the nice effect of informing users about some known capabilities of an attacker, allowing to take informed decisions.

If you want to be extra-nice, you can:

  • Publish the SHA256 of the exploit, to prove that you weren't making things up, once it's fixed or if you get sued for whatever frivolous reasons like libel.
  • Maintain the exploits against new versions, proving that the exploit is still working.
  • Publish the exploit once it has been fixed, otherwise you risk to have vendors call your bluff next time, or at least notify that the issue has been fixed. Since you don't have hardcoded offsets because we're in 2024, you can even put this in a continuous integration.

Let's have an example, as a treat. A couple of shitty vulnerabilities for RaspAP that took me 5 minutes to find and at least 5 more to write an exploit for each of them:

$ ./read-raspap.py 10.3.141.1 /etc/passwd | head -n 5
[+] Target is running RaspAP
[+] Dumping /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
$ ./authed-mitm-raspap.py 10.3.141.1
[+] default login/password in use
[+] backdooring system…
[+] system backdoored, enjoy your permanent MITM!
$ ./leak-wifi-password-raspap.py 10.3.141.1
[+] Got the wifi password: "secretwifipassword"
$ ./leak-wireguard-key-raspap.py 10.3.141.1
[+] Got the key! Saved as ./wg-10.3.141.1.key
$ ./brick-raspap.py 10.3.141.1
[+] Target is running RaspAP
[+] Bricking the system…
[+] System bricked!
$

It looks like there is a low-hanging unauthenticated arbitrary code execution chainable with a privilege escalation to root as well, but since writing an exploit would take more than 5 minutes, I can't be bothered, and odds are that it'll be fixed along with the persistent denial-of-service anyway. Let me know when you think those are fixed.

edit: couple of days later, it seems to be a success:

  • A pull-request from defendtheworld adding more escaping, and making all the ajax requests authenticated.
  • Another pull-request from one of the authors of RaspAP, adding a bit more hardening on top of it.

But there are still more things to fix.

This article has been published in Paged Out #4, page 37.