THM - Advent of Cyber [Day 7]

Today’s task deals with databases. I don’t know too much about databases, so I’m excited to learn something new today. The task deals mainly with NoSQL (non SQL) databases and specifically a type of NoSQL database called Mongo DB. The naming scheme is different between SQL and NoSQL, and here’s how the definitions translate:

MySQLMongoDB
Tables/ViewsCollections
Rows/RecordsDocuments
ColumnsFields
Some Translation across DB

The task also provides a graph that allows us to see what the flow of a NoSQL database looks like.


Here are some equivalent basic query operations in MongoDB and MySQL:

MySQLMongDB
AND$and
OR$or
=$eq
basic operators in each DB

Practice with MongoDB

The task wants to familiarize us with a MongoDB instance, which is great because I have no experience with MongoDB. Looks like the goal is to enumerate the DB at first and then create a new DB and documents. We can ssh into the box using the credentials thm:tryhackme on port 2222, so that full command is ssh thm@IP-ADDRESS -p 2222 and then typing the password when prompted. The first step after login is to run mongo to connect to the DB. then we can run show databases to get a list of databases.

That flagdb looks promising, but let’s not get hasty. I still need to poke around MongoDB. The task lets us know if you want to connect to an existing database or create a new one, run the use DB_NAME command. Once inside a DB, you can create collections by running db.createCollection("COLLECTION_NAME"). We can list the collections in a database by running db.getCollectionNames() inside a DB.

If we want to create a document and write some data to it within one of the collections that we’ve made, we can run:

db.COLLECTION_NAME.insert({id:"1", username: "USERNAME", email: "[email protected]", password: "PASSWORD"})

The command db.COLLECTION_NAME.find() will show all the documents and data within a collection. One of the cool things about MongoDB is that is autocreates a unique ID for each document. The data entry into the document can be updated with:

db.users.update({id:"2"}, {$set: {username: "NEW_USERNAME"}})

Where the id:"2" is the identifier of the data entry you wish to update.

Finally, we can remove documents and collections with db.users.remove({'id':'2'}) and db.users.drop().

Whew that was a lot of commands, but now I know enough to grab the flag for the first question. One of the interesting things I noticed about the way data was entered is that it seems to resemble python dictionary structure, so that made it easier for me to wrap my head around what was going on.

NoSQL Injection

NoSQL injection allows for an attacker to gain control over a database. This gives attackers the ability to modify data (potentially including credentials), perform DOS attacks, and make entries into DBs that allow for them to gain access to applications and information that contains sensitive data.

Login pages speak to databases in order to authenticate users. The process may be slightly different depending on what the database is, but typically when a login request is made, the username and password is packaged up as JSON or some other type of data format, and that JSON is passed into a query for the DB, something like db.users.find({username:"TEST", password:"PASSWORD"}). If a document is returned the the entry is good and the user is authenticated, otherwise, a null reply happens and the user is not allowed to login.

The task gives a list of MongoDB operators for us to use in the task:

  • $eq – matches records equal to value
  • $ne – matches records not equal to value
  • $gt – matches records greater than value
  • $where – matches records based on JavaScript condition
  • $exists – matches records that have certain field
  • $regex – matches records that satisfy RegEx

We can inject these operators into our login and force the logic to allow us into the application. For instance, the task gives the example of entering {"$ne": "xyz"} into the password field so the full query looks like this:

db.users.findOne({username:{"$ne":"admin"},password:{"$ne":"xyz"}})

This tells the DB to find a user named admin and if the admin password is NOT xzy to return the document and allow us into the application. Pretty clever right?

How to exploit NoSQL Injection

The first step of exploiting a NoSQL injection, much like the LFI vulnerability, is finding an entry point. A good place to look is in user input fields that are querying a DB like a search bar or login page. If the developer didn’t program to sanitize the user input, then we may be able to perform our NoSQL Injection. Next is to figure out how the DB is being queried by the input. Is the application using HTTP methods or JSON objects? We can look to tools like BurpSuite for info like this. In this task getting NoSQL injection from GET and POST requests involves injecting the URL with an array of a MongoDB operator. They also give an example of how this looks

http://example.thm.labs/search?username=admin&role[$ne]=user

This queries the DB for a user named admin that does not have a role of user.

The Tasks

We’re tasked with logging in as the admin user into the web application via a NoSQL Injection. We can change the query to something that checks what the password is not instead of what it is. It is important to note that we are changing the query, not the password, so if your [$ne] is not blue in burpsuite then you are actually changing the password not the query to the DB.

burpsuite editing the request

Once in the application, the task wants us to query the gift search to get all the users with the guest role. Here’s the URL that we can inject with a new query:

http://10.10.163.8/search?username=guest&role=user

Now we can inject [$eq] and [$ne] into the url and make it return all the users with guest roles. Here’s what the new URL will look like:

http://10.10.163.8/search?username[$ne]=guest&role[$eq]=guest

THM guest user flag

It wants a similar query for the specific McSkidy user. Here’s what that URL looks like

http://10.10.163.8/search?username=mcskidy&role[$ne]=user

And here’s the ID that we can submit for the task:

Final task
Follow Me on Mastodon! Follow Me on Twitter