Lab: Detecting NoSQL injection

Intro

The difficulty level of this exercise is APPRENTICE and the goal is to display all the products in the shop, whether they are published or not. The database backend is MongoDB.

To solve this exercise, we need Burp Suite, whether in the Community or Professional Edition.

Walkthrough

After starting the exercise, the shop should look similar to the screenshot. However, it is possible that the products within the shop are different, because the Web Security Academy exercises are regenerated again and again. The important thing, however, is that this has no influence on the solution.

The product category filters can be seen in the upper left-hand corner. At least one category should be selected here in order to proceed with the solution.

Now we switch to Burp Suite and open Burp Proxy there. In Burp Proxy, there is a tab called HTTP history, which we now open. In the HTTP history, we see all the requests that have been routed through Burp so far. However, we are only interested in the requests that were sent to our application, so we scroll down until we see them in the window. Your requests should look similar to the ones shown in the screenshot.

We will now send one of these requests to the Burp Repeater. To do this, move the mouse over the request and right-click. A context menu will appear, in which you select Send to Repeater. In the following screenshot, the request for the product category Gifts is sent to the Burp Repeater.

Now let's switch to Burp Repeater and take a closer look at the request in the Request section. The first line of the request GET /filter?category=Gifts HTTP/2 is important for us. In the course materials, we learned about a fuzz string ('"`{;$Foo}$Foo \xYZ) for MongoDB. If we apply this here, we have to evaluate each individual character to identify the correct parameter. For the sake of simplicity, we will use the single quote character (') and append it to our product category (Gifts). Your first line in the request should now look like this:

GET /filter?category=Gifts' HTTP/2

If we now send this request, we receive a HTTP/2 500 Internal Server Error in the Response section. Now we scroll down a bit in the response and see a JavaScript error message. This reads: SyntaxError: unterminated string literal. This means that a string has not been properly closed. This may indicate that the user input has not been correctly filtered or sanitized.

Now we want to send a valid JavaScript payload to the application. To do this, we insert a plus sign and close the input with another single quote.

GET /filter?category=Gifts'+' HTTP/2

But before we can send this request, we first have to URL-encode it. To do this, select the expression Gifts'+' and press CTRL+U in Burp. Your first line in the request should now look like this:

GET /filter?category=Gifts'%2b' HTTP/2

After sending, we see an HTTP/2 200 OK in the Response section. It seems that everything is fine with our request now. This indicates that there may be a form of server-side injection.

Now we want to try to change the response by inserting Boolean conditions. We start with a Boolean condition that is false. To do this, we insert the following operators in the first line of the request:

' && 0 && 'x

The complete line then looks like this:

GET /filter?category=Gifts' && 0 && 'x HTTP/2

Don't forget: before the request is sent, it must be URL-encoded again. To do this, select the payload and press CTRL+U.

GET /filter?category=Gifts'+%26%26+0+%26%26+'x HTTP/2

After sending, we again see an HTTP/2 200 OK in the Response section. Now we scroll down a bit in the response and see that no products are displayed. So we were actually able to influence the response with our Boolean condition.

Now we will use a Boolean condition that is true. This condition is very similar to the previous condition, except that we are inserting a 1 instead of a 0. The condition should look like this:

' && 1 && 'x

The complete line then looks like this:

GET /filter?category=Gifts' && 1 && 'x HTTP/2

Don't forget: before the request is sent, it must be URL-encoded again. To do this, select the payload and press CTRL+U.

GET /filter?category=Gifts'+%26%26+1+%26%26+'x HTTP/2

After sending, we again see an HTTP/2 200 OK in the Response section. If we now scroll down, we see the products from the Gifts category. An excerpt can be seen in the following screenshot.

However, since we want all products to be displayed in the shop, we now have to use a Boolean condition that is always true. The condition Gifts'||1||' is suitable for this. We now insert this condition into the first line of the request:

GET /filter?category=Gifts'||1||' HTTP/2

The good thing is that we don't have to URL-encode this request and can send it directly. We again receive an HTTP/2 200 OK. Now we move the mouse over the response and right-click. In the context menu, we now select Show response in browser. In the window that appears, we click on Copy.

In the browser, we now open a new tab and insert the response we just copied. The result should look similar to the following screenshot.

Video solution

Last updated