Very Normal, Everything Is Fine V4 + XHTTPwned
Challenge Information
Project: curl
Type: delta
Harnesses: 17
Vulnerabilities: 2
AFC Challenge Performance
Number of Unique Vulnerabilities Discovered: #
Number of Teams with Scoring PoVs: 3
Number of Teams with Scoring Patches: 3
Number of Teams with Scoring Bundles: 3
Total Points Scored for this Challenge: 30.790713906673602
What design decisions were considered for this challenge?
This challenge combines two wholly disjoint vulnerabilities to test a CRS’s ability to identify and address multiple independent issues within a single challenge.
Why this set of vulnerabilities?
Delta vs Full and why?
All “verynormalprotocol” challenges are delta challenges.
Challenge Harnesses
- curl_fuzzer_https
- curl_fuzzer_ftp
- curl_fuzzer_tftp
- curl_fuzzer_rtsp
- curl_fuzzer
- curl_fuzzer_pop3
- curl_fuzzer_ws
- curl_fuzzer_gopher
- curl_fuzzer_dict
- curl_fuzzer_bufq
- curl_fuzzer_smb
- curl_fuzzer_mqtt
- curl_fuzzer_smtp
- curl_fuzzer_file
- curl_fuzzer_imap
- curl_fuzzer_http
- fuzz_url
Challenge Vulnerabilities
HTTP Header-Parsing Stack Buffer Overflow
Vulnerability Information
Author: revpwn
Harness: curl_fuzzer_http
CWE Classification: CWE-121
What functions and functionality is relevant?
The function Curl_http_header is the vulnerable function. It’s responsible for parsing http response headers and in this case we added an extra header value to be parsed, X-Powered-By.
Why is this vulnerable?
The vulnerability is due to the fact that the buffer our X-Powered-By string is put into is hardcoded and the size is miscalculated in our memcpy check. We intended to grab the size of our hardcoded buffer, but instead we accidentally grabbed the length of the input itself, allowing for a trivial buffer overflow.
Is this a replay and/or is inspired by anything?
This is not a replay and isn’t inspired by anything other than generally speaking parsing http headers can be difficult and a source of vulnerabilities.
What makes it interesting?
It’s an easy bug to trigger, it’s easy to understand, and it’s common for developers to mix up arguments to common functions like memcpy.
Additional Details
When you navigate to google.com, you send an HTTP request that contains several request headers. These can be things like the requested url(google.com), the request method(GET/POST/PUT, etc.), the content type(json/xml, etc.), and many others. Once google receives this, it will send back an HTTP response that also contains headers. In our case, we care about the X-Powered-By header, since that is where our vulnerability is. X-Powered-By is a non-standard header for identifying the application or framework that generated this response. It was not chosen for any specific reason for this challenge other than it was a header that existed and had a somewhat easily parseable value field.
Technical Details
Once we received a response header that matched X-Powered-By, we simply parse the result and store it in a stateful struct called SingleRequest. The issue is that the array storing that result is hardcoded to have a size of 64. This could obviously be an issue if the function copying in data doesn’t account for it, which is our case, it does not. The memcpy responsible for the Stack Buffer Overflow looks like this:
if(HD_VAL(hd, hdlen, "X-Powered-By:")) {
char *xpoweredby = Curl_copy_header_value(hd);
memcpy(data->req.xpoweredby, xpoweredby, strlen(xpoweredby));
return CURLE_OK;
}
The issue is that we’ve accidentally taken the length of the header copying the value and not the length of the hardcoded buffer. This allows for a trivial buffer overflow if the user sends back an X-Powered-By response with a string of > 64 characters.
Fix
The fix for this could come in many different varieties, but two valid patches might be:
memcpy(data->req.xpoweredby, xpoweredby, 64);
memcpy(data->req.xpoweredby, xpoweredby, strlen(data->req.xpoweredby));
curl-008, "maniac difficulty" crash
Vulnerability Information
Author: David Wank
Harness: curl_fuzzer_ws
CWE Classification: CWE-476
What functions and functionality is relevant?
curl-008 is the final bug in the “extremelygoodprtcl” series specifically designed to test competitors abilities. It is an extension of curl-007, which worked by asking a CRS to mimic a series of manipulations on input data; see that documentation for details.
What makes it interesting?
This time, however, the CRS must perform just one manipulation— successfully encrypt the input with AES-CBC-256 given a hardcoded key and value, and then send that encrypted value encoded into base64.
This is intended to be an extreme test case for a CRSes adaptation, reasoning, and tool-usage abilities, hence the difficulty level of “maniac”.
Why this set of vulnerabilities?
curl-006, 007, and 008 are all evolutions of curl-005, intended to incrementally test competitors abilities with increasing difficulty. As such, they are all staged in their own challenges.
Delta vs Full and why?
All “verynormalprotocol” vulns are delta scan challenges.
