DOJO CHALLENGE #11 Winners!

June 28, 2021

The #11th DOJO CHALLENGE was to find a way to bypass all of MongoDB’s security filters to recover the administrator’s password.

WINNERS!

We are glad to announce the #11 DOJO Challenge winners list.

3 BEST WRITE-UP REPORTS

  • The best writeups reports were submitted by: k4rqd0c, Al-Madjus and w31rd0

Subscribe to our Twitter or Linkedin feeds to be notified of the upcoming challenges.

Read on to find the best write-up as well as the challenge author’s recommendations.

The challenge

You have just discovered a tool to read user information. Unfortunately for you, several filters have been set up to prevent the extraction of admin information. Can you find a way to disclose the password of the user “admin”?

We asked you to produce a qualified write-up report explaining the logic allowing such exploitation. This write-up serves two purposes:

  • Ensure no copy-paste would occur.
  • Determine the contestant ability to properly describe a vulnerability and its vectors inside a professionally redacted report. This capacity gives us invaluable hints on your own, unique, talent as a bug hunter.

BEST WRITE-UP REPORT

K4rqd0c‘sreport was detailed, informative, and good at explaining the logic to bypass the different security filters.

The others reports, notably Al-Madjus‘s and w31rd0‘s were also very nice, we’re sorry can’t publish them all because that’s where you clearly witness the outstanding creativity of our community.

Thank you all for playing with us!

K4rqd0c‘s Write-Up


————– START OF K4rqd0c REPORT ——————

Description

The challenge consists of a mongo request which takes two parameters as input.

$user : the name of the user
$eq : a parameter that corresponds to a mongo logical operator equals

The goal is to retrieve the password of the account name called “admin”

Exploitation

I broke the problem down into 2 steps

  1. try to bypass the condition on the info.role field by injecting a mongo operator
  2. try to bypass the filters on admin

For the $eq field we can try to replace it with another mongo operator like $ne and change the condition on the role.
Unfortunately a lot of operators are filtered and in particular $ne.

You have to look at the unfiltered Mongo operators that could be injected.
the $exists operator looks interesting. It tests whether a field is present or not in a document.

Syntax: {field: {$ exists: }}

The problem then is to replace the USER string with a boolean (True) which does not seem possible.
But many languages considers a none empty string as True
Does it work with mongo?

I don’t have a document back but no error so it works (we can check it with the playground).

For the $user field, we cannot proceed in the same way but this field is vulnerable to manipulation on strings

For example :

We are able to add fields in the mongo query.

Note: each field is interpreted as AND conditions in the query.

We should try to make a OR condition but this is not possible in our case given the mongo syntax and anyway $or is filtered.

The parameter of method find() is a “dictionary” which will then be transformed into a bson object (binary json)

This is interesting because there can only be unique keys and so if i inject the same key twice one will be overwritten.

dict('user':'foo','user':'bar') -> {'user':'bar'}

Does it work as we want in our case

After several tests we can have

Yes!

PoC

$name : ","info.name": {"$nin":[""]},"info.role":"
$eq : $exists

Risk

get admin password!

Remediation

Add more filters as quote,$exists,$in,snin…
Use input type validation
Remove $eq as parameter


————– END OF K4rqd0c REPORT ——————