Prompt
Our favorite grocery store allegedly has a vulnerability, can you replicate it?
Walk-Through
This challenge requires you to identify a vulnerability in the web application that leaks (pun intended) some sensitive information from the server.
To start, let’s inspect the web server for any interesting files or behavior. Generally, we recommend trying to access /robots.txt
to see if there are any files that the web developer does not want search engines to index, which is usually a good sign of something interesting to probe. However, /robots.txt
returns a 404 on this web server so there is nothing for us to look at there.
Now let’s try to probe the server’s normal functionality to see how it’s communicating information between the browser and the remote web server. To do this, open the browser developer tools, usually the F12 key, or right click and choose Inspect Element, and switch to the network tab to monitor the network connections. We can try to add an item to the grocery list, let’s say we add an item called “Banana” and observe the HTTP request that’s made to the server. Once you’ve made the request, it’ll show up in the developer tools “Network” tab, click on the “add” request to view details and switch to the “Payload” tab to view the request body.
So here we see that our request to add a “Banana” to the grocery list was encoded using JSON as { content: "Banana" }
. Now let’s also inspect the response body by switching to the “Preview” tab.
Now this response is peculiar. The initial request was sent out as a String
type, but the response type is a Buffer
which we can potentially assume is a node.js Buffer type (this can be validated by inspecting the “Headers” tab to identify that the remote server is using a node.js runtime as it is powered by Express.js which is a node.js library).
On the documentation page for Buffer, we find that there are a lot of deprecated methods which could be potential attack vectors for us.
We can try to send some data to the server to see if we can generate some unexpected behavior. From the documentation here, we know that Buffers accept at least 5 different kinds of types:
- Array - standard JavaScript array object
- ArrayBuffer - more modern array object used to store a “byte array”
- Buffer - same type as itself
- Number - as indicated by the
size
constructor - String - which is what we see with the request we just made above
The intuition here would be to try to craft requests using these different types to see how the server responds and if it responds with unexpected data. You can craft the request using your favorite HTTP request tool like BurpSuite, ZAP, or curl
. We’ll use curl
as the example as we can actually have the browser developer tools duplicate the request and construct the curl
command for us by using the “Copy as cURL” menu option.
Once copied, you can paste it into a bash/zsh terminal and tweak the JSON payload, and you may eventually try a numeric payload like the following:
curl 'https://[hostname]/add' \
-H 'Accept: */*' \
-H 'Content-Type: application/json' \
-H 'sec-ch-ua: "Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"' \
-H 'sec-ch-ua-platform: "macOS"' \
--data-raw '{"content":10}' \
--compressed
Once you make this request and refresh the page, you’ll see a partial flag which indicates that you’re somehow leaking sensitive server-side information with the numeric request.
This is because the numeric request instantiates a new Buffer and the web developer in this case may be using an unsafe constructor to instantiate the Buffer which leads to discarded server-side memory being unintentionally incorporated into the new Buffer. As we only got a partial flag, we can increase the Buffer size to perhaps 100
to see if we can leak a full flag out.
Questions
What is the flag?
©️ 2024 Cyber Skyline. All Rights Reserved. Unauthorized reproduction or distribution of this copyrighted work is illegal.