Containment Forever

Web [266 pts]

When we first visit the web page, we don’t get much information about the server or client. No cookies, no hidden directories, or anything. Therefore, to work with what we have, we navigate to the tabs given.

Main page:

Looking at the flag page, we see an arrangement that looks like a document used on a NoSQL database, like MongoDB.

The ObjectId is “not indexed at the moment”, but in the “Confinement” tab, it is indexed and all the information seems there and accessible.

Clicking on one of the links leads us to a page with the following url: /item/objectId:

So in MongoDB, ObjectId’s are calculated by a 4-byte timestamp value, 5-byte random value, and 3-byte incremental counter.

Resource: https://docs.mongodb.com/manual/reference/method/ObjectId/

So knowing this, in the flag page, we are only given the timestamp. There is a way to retrieve an ObjectId if you have a timestamp. Using this link, we can use the given timestamp to get an ObjectId.

Resource: https://steveridout.github.io/mongo-object-time/

We notice that the middle 5-bytes are all the same, so this must be the system Id being used for all objects. Therefore, the last piece is to find the incremental counter to get a valid objectId for our flag.

We only need to do a small brute-force on the last digit, using the new ObjectId calculated from the given timestamp and the same SystemId used for all objects.

Doing so, we are able to retrieve the first and second flag by following this process:

XXExternalXX

Web [70 pts]

This challenge, as hinted by its name, involves an XXE attack. The goal, as described in the challenge, is to find the flag.txt file in the root directory of the PHP server.

Resource: XXE docs

Step 1

When we first visit the site, our landing page looks like this:

We assume that it takes an xml payload eventually, but when we test LFI on the query, we get this result:


(This is an error page, named error.xml)

Step 2

After messing around some more, we see that the PHP function calls loadXML() and expects a string: Resource: loadxml() docs

Step 3

We now attempt to try RFI. First, we check to see if their server visits our “website.” We test this with a webhooks site from webhooks.site.

From these results, it looks like they do visit our webhook site. The only thing now is to find a way to include our xml payload that will be available in the url. My first instinct was to find a file upload site that can be shared (filebin).

Using the XML payload:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "file:///flag.txt" >]>
<root><data>&xxe;</data></root>

We can upload this using filebin and include the entire website in the query, giving us our flag: