From 62c4be556c537ab3fd45bd41cb72d6ac550c4ea9 Mon Sep 17 00:00:00 2001 From: tcstool Date: Wed, 20 Jul 2016 20:55:24 -0500 Subject: [PATCH 01/11] setup.py corrections --- nsmweb.py | 2 +- setup.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nsmweb.py b/nsmweb.py index 21f9013..548d57d 100644 --- a/nsmweb.py +++ b/nsmweb.py @@ -759,7 +759,7 @@ def checkResult(baseSize,respSize,testNum,verb,postData): global httpMethod global neDict global gtDict - + delta = abs(respSize - baseSize) if (delta >= 100) and (respSize != 0) : diff --git a/setup.py b/setup.py index a51fbbc..0d78e7b 100644 --- a/setup.py +++ b/setup.py @@ -4,9 +4,9 @@ with open("README.md") as f: setup( name = "NoSQLMap", - version = "0.5", + version = "0.7", packages = find_packages(), - scripts = ['nosqlmap.py', 'nsmmongo.py', 'nsmcouch.py'], + scripts = ['nosqlmap.py', 'nsmmongo.py', 'nsmcouch.py','nsmscan.py','nsmweb.py'], entry_points = { "console_scripts": [ @@ -18,7 +18,7 @@ "NoSQLMap==0.5", "pbkdf2==1.3", "pymongo==2.7.2",\ "requests==2.5.0"], - author = "tcstools", + author = "tcstool", author_email = "nosqlmap@gmail.com", description = "Automated MongoDB and NoSQL web application exploitation tool", license = "GPLv3", From 2bccf32ab03972650aa9a31ac37468ea714b1695 Mon Sep 17 00:00:00 2001 From: tcstool Date: Wed, 20 Jul 2016 20:58:25 -0500 Subject: [PATCH 02/11] Installer script fix --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0d78e7b..c0d518b 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ }, install_requires = [ "CouchDB==1.0", "httplib2==0.9", "ipcalc==1.1.3",\ - "NoSQLMap==0.5", "pbkdf2==1.3", "pymongo==2.7.2",\ + "NoSQLMap==0.7", "pbkdf2==1.3", "pymongo==2.7.2",\ "requests==2.5.0"], author = "tcstool", From 9ecfd1b03a9567c4d2e40469928288b291d0f587 Mon Sep 17 00:00:00 2001 From: tcstool Date: Thu, 21 Jul 2016 16:43:37 -0500 Subject: [PATCH 03/11] Remove yes_tag and replace w/string conversion --- nsmweb.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/nsmweb.py b/nsmweb.py index 548d57d..4abd9d7 100644 --- a/nsmweb.py +++ b/nsmweb.py @@ -43,8 +43,6 @@ def getApps(webPort,victim,uri,https,verb,requestHeaders): possAddrs = [] timeVulnsStr = [] timeVulnsInt = [] - yes_tag = ['y', 'Y'] - no_tag = ['n', 'N'] appUp = False strTbAttack = False intTbAttack = False @@ -264,7 +262,7 @@ def getApps(webPort,victim,uri,https,verb,requestHeaders): doTimeAttack = raw_input("Start timing based tests (y/n)? ") - if doTimeAttack in yes_tag: + if doTimeAttack.lower() == "y": print "Starting Javascript string escape time based injection..." req = urllib2.Request(uriArray[18], None, requestHeaders) start = time.time() @@ -306,7 +304,7 @@ def getApps(webPort,victim,uri,https,verb,requestHeaders): if lt24 == True: bfInfo = raw_input("MongoDB < 2.4 detected. Start brute forcing database info (y/n)? ") - if bfInfo in yes_tag: + if bfInfo.lower == "y": getDBInfo() @@ -330,7 +328,7 @@ def getApps(webPort,victim,uri,https,verb,requestHeaders): fileOut = raw_input("Save results to file (y/n)? ") - if fileOut in yes_tag: + if fileOut.lower() == "y": savePath = raw_input("Enter output file name: ") fo = open(savePath, "wb") fo.write ("Vulnerable URLs:\n") @@ -692,7 +690,7 @@ def postApps(victim,webPort,uri,https,verb,postData,requestHeaders): fileOut = raw_input("Save results to file (y/n)? ") - if fileOut in yes_tag: + if fileOut.lower() == "y": savePath = raw_input("Enter output file name: ") fo = open(savePath, "wb") fo.write ("Vulnerable Requests:\n") @@ -974,7 +972,6 @@ def buildUri(origUri, randValue): def getDBInfo(): curLen = 0 - yes_tag = ['y', 'Y'] nameLen = 0 gotFullDb = False gotNameLen = False @@ -1039,7 +1036,7 @@ def getDBInfo(): getUserInf = raw_input("Get database users and password hashes (y/n)? ") - if getUserInf in yes_tag: + if getUserInf.lower() == "y": charCounter = 0 nameCounter = 0 #find the total number of users on the database @@ -1189,7 +1186,7 @@ def getDBInfo(): pwdHash = "" crackHash = raw_input("Crack recovered hashes (y/n)?: ") - while crackHash in yes_tag: + while crackHash.lower() == "y": menuItem = 1 for user in users: print str(menuItem) + "-" + user From 365997f095a513104af454004c6c5aaa35bd4dd7 Mon Sep 17 00:00:00 2001 From: Mhapankar123 Date: Thu, 13 Oct 2016 08:26:51 +0530 Subject: [PATCH 04/11] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3fe4146..857ec00 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Introduction NoSQLMap is an open source Python tool designed to audit for as well as automate injection attacks and exploit default configuration weaknesses in NoSQL databases as well as web applications using NoSQL in order to disclose data from the database. It is named as a tribute to Bernardo Damele and Miroslav's Stampar's popular SQL injection tool [sqlmap](http://sqlmap.org), and its concepts are based on and extensions of Ming Chow's excellent presentation at Defcon 21, ["Abusing NoSQL Databases"](https://www.defcon.org/images/defcon-21/dc-21-presentations/Chow/DEFCON-21-Chow-Abusing-NoSQL-Databases.pdf). Presently the tool's exploits are focused around MongoDB, but additional support for other NoSQL based platforms such as CouchDB, Redis, and Cassandra are planned in future releases. +A NoSQL (originally referring to "non SQL", "non relational" or "not only SQL") database provides a mechanism for storage and retrieval of data which is modeled in means other than the tabular relations used in relational databases. Such databases have existed since the late 1960s, but did not obtain the "NoSQL" moniker until a surge of popularity in the early twenty-first century, triggered by the needs of Web 2.0 companies such as Facebook, Google, and Amazon.com. NoSQL databases are increasingly used in big data and real-time web applications. NoSQL systems are also sometimes called "Not only SQL" to emphasize that they may support SQL-like query languages. Requirements ============ From dfbfee8098ecc458f5415e31d8d293fe14d123e4 Mon Sep 17 00:00:00 2001 From: August Detlefsen Date: Tue, 7 Feb 2017 17:29:32 -0800 Subject: [PATCH 05/11] Parse headers from saved request --- nosqlmap.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nosqlmap.py b/nosqlmap.py index b17dca8..8460457 100755 --- a/nosqlmap.py +++ b/nosqlmap.py @@ -423,6 +423,13 @@ def options(): else: print "unsupported method in request header." + # load the HTTP headers + for line in reqData[1:]: + print(line) + if not line.strip(): break + header = line.split(": "); + requestHeaders[header[0]] = header[1].strip() + victim = reqData[1].split( " ")[1].replace("\r\n","") optionSet[0] = True uri = methodPath[1].replace("\r\n","") From e5bbd611ec87e971ed36d0e44a521b643a9ca7b3 Mon Sep 17 00:00:00 2001 From: August Detlefsen Date: Tue, 7 Feb 2017 17:46:53 -0800 Subject: [PATCH 06/11] Merge pull request #1 from augustd/parse-burp-headers Parse headers from saved request --- nsmweb.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nsmweb.py b/nsmweb.py index 4abd9d7..c619137 100644 --- a/nsmweb.py +++ b/nsmweb.py @@ -56,13 +56,13 @@ def getApps(webPort,victim,uri,https,verb,requestHeaders): int24 = False #Verify app is working. - print "Checking to see if site at " + str(victim) + ":" + str(webPort) + str(uri) + " is up..." + print "Checking to see if site at " + str(victim).strip() + ":" + str(webPort).strip() + str(uri).strip() + " is up..." if https == "OFF": - appURL = "http://" + str(victim) + ":" + str(webPort) + str(uri) + appURL = "http://" + str(victim).strip() + ":" + str(webPort).strip() + str(uri).strip() elif https == "ON": - appURL = "https://" + str(victim) + ":" + str(webPort) + str(uri) + appURL = "https://" + str(victim).strip() + ":" + str(webPort).strip() + str(uri).strip() try: req = urllib2.Request(appURL, None, requestHeaders) appRespCode = urllib2.urlopen(req).getcode() From bafb608f755a0e94d25082662709f0e968923328 Mon Sep 17 00:00:00 2001 From: Adrien de Beaupre Date: Sun, 26 Mar 2017 11:41:34 -0400 Subject: [PATCH 07/11] Correction of error in code. Line 18 is $js = "function () { var query = '". $ordersearch . "'; return this.id == query;}"; Should be $js = "function () { var query = '". $search . "'; return this.id == query;}"; --- vuln_apps/orderdata.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vuln_apps/orderdata.php b/vuln_apps/orderdata.php index 39dfa32..427359f 100644 --- a/vuln_apps/orderdata.php +++ b/vuln_apps/orderdata.php @@ -15,7 +15,7 @@ $db = $conn->shop; $collection = $db->orders; $search = $_GET['ordersearch']; - $js = "function () { var query = '". $ordersearch . "'; return this.id == query;}"; + $js = "function () { var query = '". $search . "'; return this.id == query;}"; //print $js; print '
'; @@ -48,4 +48,4 @@ - \ No newline at end of file + From 598950d06a0c948313d6543cc1996c9aa98c487d Mon Sep 17 00:00:00 2001 From: Adrien de Beaupre Date: Sun, 26 Mar 2017 11:43:25 -0400 Subject: [PATCH 08/11] Change mongo to localhost Changed the mongoclient to localhost (127.0.0.1) line 14. --- vuln_apps/userdata.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vuln_apps/userdata.php b/vuln_apps/userdata.php index 303fbef..0fc8165 100644 --- a/vuln_apps/userdata.php +++ b/vuln_apps/userdata.php @@ -11,7 +11,7 @@ if (isset($_GET['usersearch']) && !empty($_GET['usersearch'])) { try { $result = ""; - $conn = new MongoClient('mongodb://192.168.87.157'); + $conn = new MongoClient('mongodb://127.0.0.1'); $db = $conn->appUserData; $collection = $db->users; $search = $_GET['usersearch']; @@ -47,4 +47,4 @@ - \ No newline at end of file + From 862c062ac573497fd91646031c421c2f2d32bd26 Mon Sep 17 00:00:00 2001 From: Adrien de Beaupre Date: Sun, 26 Mar 2017 12:36:37 -0400 Subject: [PATCH 09/11] Create mongo.nosql Schema for the three databases and collections for the sample vulnerable applications. --- vuln_apps/mongo.nosql | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 vuln_apps/mongo.nosql diff --git a/vuln_apps/mongo.nosql b/vuln_apps/mongo.nosql new file mode 100644 index 0000000..45bfcbc --- /dev/null +++ b/vuln_apps/mongo.nosql @@ -0,0 +1,23 @@ +use shop +db.orders.insert({"id":"42","name":"Adrien","item":"Fuzzy pink towel","quantity":"1"}) +db.orders.insert({"id":"99","name":"Justin","item":"Bird supplies","quantity":"4"}) +db.orders.insert({"id":"1","name":"Robin","item":"Music gift cards","quantity":"100"}) +db.orders.insert({"id":"1001","name":"Moses","item":"Miami Heat tickets","quantity":"1000"}) +db.orders.insert({"id":"66","name":"Rick","item":"Black hoodie","quantity":"1"}) +db.orders.insert({"id":"0","name":"Nobody","item":"Nothing","quantity":"0"}) + +use customers +db.paymentinfo.insert({"name":"Adrien","id":"42","cc":"5555123456789999","cvv2":"1234"}) +db.paymentinfo.insert({"name":"Justin","id":"99","cc":"5555123456780000","cvv2":"4321"}) +db.paymentinfo.insert({"name":"Robin","id":"1","cc":"3333444455556666","cvv2":"2222"}) +db.paymentinfo.insert({"name":"Moses","id":"2","cc":"4444555566667777","cvv2":"3333"}) +db.paymentinfo.insert({"name":"Rick","id":"3","cc":"5555666677778888","cvv2":"5678"}) +db.paymentinfo.insert({"name":"Nobody","id":"0","cc":"45009876543215555","cvv2":"9999"}) + +use appUserData +db.users.insert({"name":"Adrien","username":"adrien","email":"adrien@sec642.org"}) +db.users.insert({"name":"Justin","username":"justin","email":"justin@sec642.org"}) +db.users.insert({"name":"Robin","username":"digininja","email":"digininja@sec642.org"}) +db.users.insert({"name":"Moses","username":"adrien","email":"moses@sec642.org"}) +db.users.insert({"name":"Rick","username":"rick","email":"rick@sec642.org"}) +db.users.insert({"name":"Nobody","username":"administrator","email":"root@sec642.org"}) From aa1a475f95cacf776e24316ccca8fc7a0999f3b5 Mon Sep 17 00:00:00 2001 From: Adrien de Beaupre Date: Sun, 26 Mar 2017 13:05:46 -0400 Subject: [PATCH 10/11] Create populate_db.php Add a PHP script to populate the DBs for the vulnerable applications. --- vuln_apps/populate_db.php | 107 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 vuln_apps/populate_db.php diff --git a/vuln_apps/populate_db.php b/vuln_apps/populate_db.php new file mode 100644 index 0000000..44d2576 --- /dev/null +++ b/vuln_apps/populate_db.php @@ -0,0 +1,107 @@ +shop; + +// Drop the database +$response = $db->drop(); +//print_r($response); + +// select a collection (analogous to a relational database's table) +$collection = $db->orders; + +// add records +$obj = array( "id"=>"1234","name"=>"Russell","item"=>"ManCity Jersey","quantity"=>"2"); +$collection->insert($obj); +$obj = array( "id"=>"42","name"=>"Adrien","item"=>"Fuzzy pink towel","quantity"=>"1"); +$collection->insert($obj); +$obj = array( "id"=>"99","name"=>"Justin","item"=>"Bird supplies","quantity"=>"4"); +$collection->insert($obj); +$obj = array( "id"=>"1","name"=>"Robin","item"=>"Music gift cards","quantity"=>"100"); +$collection->insert($obj); +$obj = array( "id"=>"1001","name"=>"Moses","item"=>"Miami Heat tickets","quantity"=>"1000"); +$collection->insert($obj); +$obj = array( "id"=>"66","name"=>"Rick","item"=>"Black hoodie","quantity"=>"1"); +$collection->insert($obj); +$obj = array( "id"=>"0","name"=>"Nobody","item"=>"Nothing","quantity"=>"0"); +$collection->insert($obj); + +// find everything in the collection +$cursor = $collection->find(); + +// iterate through the results +foreach ($cursor as $obj) { + echo $obj["name"] . "
"; +} + +// select a database +$db = $m->customers; + +// Drop the database +$response = $db->drop(); +//print_r($response); + +// select a collection (analogous to a relational database's table) +$collection = $db->paymentinfo; + +$obj = array( "name"=>"Russell","id"=>"1000","cc"=>"0000000000000000","cvv2"=>"0000"); +$collection->insert($obj); +$obj = array( "name"=>"Adrien","id"=>"42","cc"=>"5555123456789999","cvv2"=>"1234"); +$collection->insert($obj); +$obj = array( "name"=>"Justin","id"=>"99","cc"=>"5555123456780000","cvv2"=>"4321"); +$collection->insert($obj); +$obj = array( "name"=>"Robin","id"=>"1","cc"=>"3333444455556666","cvv2"=>"2222"); +$collection->insert($obj); +$obj = array( "name"=>"Moses","id"=>"2","cc"=>"4444555566667777","cvv2"=>"3333"); +$collection->insert($obj); +$obj = array( "name"=>"Rick","id"=>"3","cc"=>"5555666677778888","cvv2"=>"5678"); +$collection->insert($obj); +$obj = array( "name"=>"Nobody","id"=>"0","cc"=>"4500987654321555","cvv2"=>"9999"); +$collection->insert($obj); + +// find everything in the collection +$cursor = $collection->find(); + +// iterate through the results +foreach ($cursor as $obj) { + echo $obj["cc"] . "
"; +} + + +// select a database +$db = $m->appUserData; + +// Drop the database +$response = $db->drop(); +//print_r($response); + +// select a collection (analogous to a relational database's table) +$collection = $db->users; + +$obj = array( "name"=>"Russell","username"=>"tcstoolHax0r","email"=>"nosqlmap@sec642.org"); +$collection->insert($obj); +$obj = array( "name"=>"Adrien","username"=>"adrien","email"=>"adrien@sec642.org"); +$collection->insert($obj); +$obj = array( "name"=>"Justin","username"=>"justin","email"=>"justin@sec642.org"); +$collection->insert($obj); +$obj = array( "name"=>"Robin","username"=>"digininja","email"=>"digininja@sec642.org"); +$collection->insert($obj); +$obj = array( "name"=>"Moses","username"=>"adrien","email"=>"moses@sec642.org"); +$collection->insert($obj); +$obj = array( "name"=>"Rick","username"=>"rick","email"=>"rick@sec642.org"); +$collection->insert($obj); +$obj = array( "name"=>"Nobody","username"=>"administrator","email"=>"root@sec642.org"); +$collection->insert($obj); + +// find everything in the collection +$cursor = $collection->find(); + +// iterate through the results +foreach ($cursor as $obj) { + echo $obj["email"] . "
"; +} + +?> From 37fd3c785cf39cd019ca9b917e01d57ff18ba6d8 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 23 Aug 2017 08:00:54 +1000 Subject: [PATCH 11/11] Update README.md --- README.md | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 857ec00..f69aa31 100644 --- a/README.md +++ b/README.md @@ -3,16 +3,19 @@ NoSQLMap [NoSQLMap](http://www.nosqlmap.net) v0.7 -Introduction -============ - +# Introduction NoSQLMap is an open source Python tool designed to audit for as well as automate injection attacks and exploit default configuration weaknesses in NoSQL databases as well as web applications using NoSQL in order to disclose data from the database. -It is named as a tribute to Bernardo Damele and Miroslav's Stampar's popular SQL injection tool [sqlmap](http://sqlmap.org), and its concepts are based on and extensions of Ming Chow's excellent presentation at Defcon 21, ["Abusing NoSQL Databases"](https://www.defcon.org/images/defcon-21/dc-21-presentations/Chow/DEFCON-21-Chow-Abusing-NoSQL-Databases.pdf). Presently the tool's exploits are focused around MongoDB, but additional support for other NoSQL based platforms such as CouchDB, Redis, and Cassandra are planned in future releases. +## What is NoSQL? A NoSQL (originally referring to "non SQL", "non relational" or "not only SQL") database provides a mechanism for storage and retrieval of data which is modeled in means other than the tabular relations used in relational databases. Such databases have existed since the late 1960s, but did not obtain the "NoSQL" moniker until a surge of popularity in the early twenty-first century, triggered by the needs of Web 2.0 companies such as Facebook, Google, and Amazon.com. NoSQL databases are increasingly used in big data and real-time web applications. NoSQL systems are also sometimes called "Not only SQL" to emphasize that they may support SQL-like query languages. -Requirements -============ +## Credits +NoSQLMap is named as a tribute to Bernardo Damele and Miroslav's Stampar's popular SQL injection tool [sqlmap](http://sqlmap.org), and its concepts are based on and extensions of Ming Chow's excellent presentation at Defcon 21, ["Abusing NoSQL Databases"](https://www.defcon.org/images/defcon-21/dc-21-presentations/Chow/DEFCON-21-Chow-Abusing-NoSQL-Databases.pdf). + +## DBMS Support +Presently the tool's exploits are focused around MongoDB, and CouchDB but additional support for other NoSQL based platforms such as CouchDB, Redis, and Cassandra are planned in future releases. + +# Requirements On a Debian or Red Hat based system, the setup.sh script may be run as root to automate the installation of NoSQLMap's dependencies. Varies based on features used: @@ -24,11 +27,12 @@ Varies based on features used: There are some various other libraries required that a normal Python installation should have readily available. Your milage may vary, check the script. -Setup -============ -``python setup.py install`` -Usage -===== +# Setup +``` +python setup.py install +``` + +# Usage -Start with @@ -69,8 +73,3 @@ Video NoSQLMap MongoDB Management Attack Demo. NoSQLMap MongoDB Management Attack Demo - -Contribute -========== - -If you'd like to contribute, please create [new issue](https://github.com/tcstool/NoSQLMap/issues) or [pull request](https://github.com/tcstool/NoSQLMap/pulls).