SANS Penetration Testing

NoSQL? No Problem! Pillaging MongoDB for Fun and Profit

By Josh Wright

Database technology continues to evolve to meet different application needs. One example of this is the adoption of NoSQL databases used by many different modern web applications. NoSQL databases depart from the traditional table-based storage mechanisms widely known and loved (mildly appreciated?), and instead store simple key-value data pairs, JSON documents, graph data, or tuples (and variations of these types).

A popular NoSQL database type is MongoDB. MongoDB falls under the document-based NoSQL storage model, requiring that all data is stored in JSON-formatted documents. This integrates nicely with lots of web applications that need fast access to data in a format that's convenient and easy to work with.

As a pen tester, I've run across some MongoDB databases. Here are some tips on effectively pillaging MongoDB.

MongoDB Files

From your shell, look for a MongoDB process running. Check for command-line arguments that indicate the location of the mongodb.conf configuration file. If the mongod process isn't running, still check the usual places for a mongodb.conf file (/etc, /usr/local/etc, et cetera).


The mongodb.conf file is straightforward, but it has a lot of whitespace and comments. The interesting entry is "dbpath", which points to the location of the database files.


The MongoDB files themselves require a little explanation:


  • cust.0, local.0 - These are database files for MongoDB. Each MongoDB instance has "local" as a database, and one or more additional user databases. Database files are preallocated in size and populated as needed, growing to "cust.1", "cust.2" as needed.
  • cust.ns, local.ns - Namespace files, which also store indexes and collections of data within a database (conveniently referred to as a "collection"; more on collections below).
  • journal/ - Used for transaction logging and recovery following a MongoDB crash.
  • mongod.lock - Present when MongoDB is running, removed when it stops cleanly.
  • storage.bson - MongoDB storage metadata resource.
  • _tmp - Temporary use directory by MongoDB.

MongoDB Data Replication

You can inspect data locally on the server, or tar up the mongodb directory and copy it to a local box for analysis.

Use any file transfer technique you have available; I'm using Netcat here. First, on my analysis system:



Next, tar and send the data to your listener:


Returning to the analysis system, we have the extracted data available:


I'm using a Mac for analysis with Homebrew for package management. Installing MongoDB is a simple "brew install mongodb" for me. Debian-based Linux users can use "apt-get install mongodb".

Once MongoDB is installed, create a simple configuration file as shown then start the mongod process with the "-config" argument. You can put it in the same directory as the database files:


With a local copy of the data, we can start to examine the database, collection, and document data.

Tip: If you get the error message "old lock file: ./mongod.lock. it probably means unclean shutdown" and mongod.lock exists, remove the mongod.lock file and start mongod again.

MongoDB Data Inspection

The "mongo" utility is used to access the local MongoDB data files locally. By default, this requires no authentication. First, we query the available databases (these names also match the *.ns files in the dbpath directory):


Here we see the two databases as expected: cust, and local. The local database is used for instance-specific data, while the cust database is data stored by the customer application. Next, we switch from the default database name of "test" to the "cust" database and enumerate the available collections:


In MongoDB, a collection is a grouping of documents within a database. Logically, it's like a table in a traditional RDBMS system, but without the rigid data formatting constraints. Using the constant "db" prefix, we can use the collection name and built-in collection methods available. The db.collection.findOne() method with no arguments will return the first entry in the collection:



Tip: None of these names, passwords, credit card numbers, or phone numbers are real. Thanks.

Now that we have some information about the document structure, we can apply query operators to focus on specific data. For example, if we want to search only for the first entry where the GivenName is "Joshua", we can use the following query with a simple JSON declaration:



If you want to collect all the matches for a given query, use the db.collection.find() method:


Here, the data is not "prettified", but we get more than one record in the results. For more examples of using the query() method with different data sets, see the Find or Query Data with the mongo Shell article.

Using findOne() and find() you can retrieve data from the collection and database, but it's not terribly convenient for large-scale pillaging. As an alternative, we can use the command-line tool "mongoexport". This tool requires a database and collection name, and will generate a JSON file as the output:


If you prefer, you can also export data in CSV format, but you have to specify each of the field names you want exported, as shown:


MongoDB And You

With a little background information on how to interact with a MongoDB instance, you can successfully pillage useful data. Keep these steps in mind, and apply them when you encounter a MongoDB instance in your next pen test.

-Josh Wright


Upcoming SANS Special Event - 2018 Holiday Hack Challenge


SANS Holiday Hack Challenge - KringleCon 2018

  • Free SANS Online Capture-the-Flag Challenge
  • Our annual gift to the entire Information Security Industry
  • Designed for novice to advanced InfoSec professionals
  • Fun for the whole family!!
  • Build and hone your skills in a fun and festive roleplaying like video game, by the makers of SANS NetWars
  • Learn more:
  • Play previous versions from free 24/7/365:

Player Feedback!

  • "On to level 4 of the #holidayhackchallenge. Thanks again @edskoudis / @SANSPenTest team." - @mikehodges
  • "#SANSHolidayHack Confession — I have never used python or scapy before. I got started with both today because of this game! Yay!" - @tww2b
  • "Happiness is watching my 12 yo meet @edskoudis at the end of #SANSHolidayHack quest. Now the gnomes #ProudHackerPapa" - @dnlongen


Posted December 14, 2015 at 7:09 PM | Permalink | Reply

Jeremy Druin

Thanks. Helpful article. Looks like some of the objects (such as collections) have a help() method. If your not sure what are the options, call the help method to see a list of eligible commands. For example,;
Using the collection above:;

Posted December 18, 2015 at 7:41 PM | Permalink | Reply


Great article Josh! You should mention configuration file format difference between versions 2.4 and 2.6. Both actually appear in your article.
I was quite puzzled today by mongod giving me an error with the simple config file "storage: dbPath: .". It appeared that my MongoDB version was 2.4.x, so I should have used the old format "dbpath=.".

Posted January 4, 2016 at 6:57 AM | Permalink | Reply

Asia commissioning

I think this is among the most important info for me.
And i'm glad reading your article. But want to remark
on few general things, The website style is ideal, the articles is really great : D.
Good job, cheers

Post a Comment


* Indicates a required field.