From a32e49c042748e9d5d27c3ab36de1512e28ee527 Mon Sep 17 00:00:00 2001 From: Harry Crawford Date: Fri, 7 Oct 2022 18:25:07 +0200 Subject: [PATCH] Dockerized the included vulnerable application to make running on the local machine easier. Also updated the README.md file to provide instructions on use. --- README.md | 57 +++++++++++++++++------- vuln_apps/acct.php | 39 ---------------- vuln_apps/cust.html | 21 --------- vuln_apps/docker-compose.yml | 27 +++++++++++ vuln_apps/docker/apache/Dockerfile | 6 +++ vuln_apps/docker/apache/apache.conf | 16 +++++++ vuln_apps/docker/mongo/Dockerfile | 5 +++ vuln_apps/docker/mongo/import.sh | 2 + vuln_apps/{ => docker/mongo}/mongo.nosql | 2 - vuln_apps/docker/php/Dockerfile | 13 ++++++ vuln_apps/orderdata.php | 51 --------------------- vuln_apps/src/acct.php | 42 +++++++++++++++++ vuln_apps/src/index.html | 17 +++++++ vuln_apps/src/orderdata.php | 49 ++++++++++++++++++++ vuln_apps/{ => src}/populate_db.php | 2 +- vuln_apps/src/userdata.php | 48 ++++++++++++++++++++ vuln_apps/userdata.php | 50 --------------------- 17 files changed, 266 insertions(+), 181 deletions(-) delete mode 100644 vuln_apps/acct.php delete mode 100644 vuln_apps/cust.html create mode 100644 vuln_apps/docker-compose.yml create mode 100644 vuln_apps/docker/apache/Dockerfile create mode 100644 vuln_apps/docker/apache/apache.conf create mode 100644 vuln_apps/docker/mongo/Dockerfile create mode 100644 vuln_apps/docker/mongo/import.sh rename vuln_apps/{ => docker/mongo}/mongo.nosql (99%) create mode 100644 vuln_apps/docker/php/Dockerfile delete mode 100644 vuln_apps/orderdata.php create mode 100644 vuln_apps/src/acct.php create mode 100644 vuln_apps/src/index.html create mode 100644 vuln_apps/src/orderdata.php rename vuln_apps/{ => src}/populate_db.php (99%) create mode 100644 vuln_apps/src/userdata.php delete mode 100644 vuln_apps/userdata.php diff --git a/README.md b/README.md index 6841632..50abb20 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,73 @@ -NoSQLMap -======== -[![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) +# NoSQLMap + +[![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv3-red.svg)](https://github.com/codingo/NoSQLMap/blob/master/COPYING) [![Twitter](https://img.shields.io/badge/twitter-@codingo__-blue.svg)](https://twitter.com/codingo_) 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 and web applications using NoSQL in order to disclose or clone data from the database. -Originally authored by [@tcsstool](https://twitter.com/tcstoolHax0r) and now maintained by [@codingo_](https://twitter.com/codingo_) NoSQLMap is named as a tribute to Bernardo Damele and Miroslav's Stampar's popular SQL injection tool [sqlmap](http://sqlmap.org). 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). - +Originally authored by [@tcsstool](https://twitter.com/tcstoolHax0r) and now maintained by [@codingo\_](https://twitter.com/codingo_) NoSQLMap is named as a tribute to Bernardo Damele and Miroslav's Stampar's popular SQL injection tool [sqlmap](http://sqlmap.org). 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). ## NoSQLMap MongoDB Management Attack Demo. -NoSQLMap MongoDB Management Attack Demo +NoSQLMap MongoDB Management Attack Demo ## Screenshots + ![NoSQLMap](https://github.com/codingo/NoSQLMap/blob/master/screenshots/NoSQLMap-v0-5.jpg) # Summary + ## 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. ## DBMS Support + Presently the tool's exploits are focused around MongoDB, and CouchDB but additional support for other NoSQL based platforms such as 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. +## 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: -- Metasploit Framework, -- Python with PyMongo, -- httplib2, -- and urllib available. -- A local, default MongoDB instance for cloning databases to. Check [here](http://docs.mongodb.org/manual/installation/) for installation instructions. -There are some various other libraries required that a normal Python installation should have readily available. Your milage may vary, check the script. +- Metasploit Framework, +- Python with PyMongo, +- httplib2, +- and urllib available. +- A local, default MongoDB instance for cloning databases to. Check [here](http://docs.mongodb.org/manual/installation/) for installation instructions. + +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 ``` + Alternatively you can build a Docker image by changing to the docker directory and entering: + ``` docker build -t nosqlmap . ``` or you can use Docker-compose to run Nosqlmap: + ``` docker-compose build docker-compose run nosqlmap ``` + ## Usage Instructions + Start with + ``` python NoSQLMap ``` -NoSQLMap uses a menu based system for building attacks. Upon starting NoSQLMap you are presented with with the main menu: +NoSQLMap uses a menu based system for building attacks. Upon starting NoSQLMap you are presented with with the main menu: ``` 1-Set options (do this first) @@ -66,11 +78,12 @@ x-Exit ``` Explanation of options: + ``` 1. Set target host/IP-The target web server (i.e. www.google.com) or MongoDB server you want to attack. 2. Set web app port-TCP port for the web application if a web application is the target. 3. Set URI Path-The portion of the URI containing the page name and any parameters but NOT the host name (e.g. /app/acct.php?acctid=102). -4. Set HTTP Request Method (GET/POST)-Set the request method to a GET or POST; Presently only GET is implemented but working on implementing POST requests exported from Burp. +4. Set HTTP Request Method (GET/POST)-Set the request method to a GET or POST; Presently only GET is implemented but working on implementing POST requests exported from Burp. 5. Set my local Mongo/Shell IP-Set this option if attacking a MongoDB instance directly to the IP of a target Mongo installation to clone victim databases to or open Meterpreter shells to. 6. Set shell listener port-If opening Meterpreter shells, specify the port. 7. Load options file-Load a previously saved set of settings for 1-6. @@ -79,4 +92,14 @@ Explanation of options: x. Back to main menu-Use this once the options are set to start your attacks. ``` -Once options are set head back to the main menu and select DB access attacks or web app attacks as appropriate for whether you are attacking a NoSQL management port or web application. The rest of the tool is "wizard" based and fairly self explanatory, but send emails to codingo@protonmail.com or find me on Twitter [@codingo_](https://twitter.com/codingo_) if you have any questions or suggestions. +Once options are set head back to the main menu and select DB access attacks or web app attacks as appropriate for whether you are attacking a NoSQL management port or web application. The rest of the tool is "wizard" based and fairly self explanatory, but send emails to codingo@protonmail.com or find me on Twitter [@codingo\_](https://twitter.com/codingo_) if you have any questions or suggestions. + +## Vulnerable Applications + +This repo also includes an intentionally vulnerable web application to test NoSQLMap with. To run this application, you need Docker installed. Then you can run the following commands from the /vuln_apps directory. + +``` +docker-compose build && docker-compose up +``` + +Once that is complete, you should be able to access the vulnerable application by visiting: https://127.0.0.1/index.html diff --git a/vuln_apps/acct.php b/vuln_apps/acct.php deleted file mode 100644 index c03feef..0000000 --- a/vuln_apps/acct.php +++ /dev/null @@ -1,39 +0,0 @@ - - -Payment information - - -customers; - $collection = $db->paymentinfo; - $search = $_GET['acctid']; -// $criteria = array('id' => $search); -// $fields = array('name','id','cc','cvv2'); - - - $cursor = $collection->find(array('id' => $search)); - -// echo $search; - echo $cursor->count() . ' document(s) found.
'; - - foreach ($cursor as $obj) { - echo 'Name: ' . $obj['name'] . '
'; - echo 'Customer ID: ' . $obj['id'] . '
'; - echo 'Card Number: ' . $obj['cc'] . '
'; - echo 'CVV2 Code: ' . $obj['cvv2'] . '
'; - echo '
'; - } - -$conn->close(); -} catch (MongoConnectionException $e) { - die('Error connecting to MongoDB server : ' . $e->getMessage()); -} catch (MongoException $e) { - die('Error: ' . $e->getMessage()); -} -?> - - - - \ No newline at end of file diff --git a/vuln_apps/cust.html b/vuln_apps/cust.html deleted file mode 100644 index ed80d22..0000000 --- a/vuln_apps/cust.html +++ /dev/null @@ -1,21 +0,0 @@ - - -Customer Info - - - -

Customer Information

-

Enter your customer ID to show your account information:

- -
-Customer ID: - -
- -
- - - \ No newline at end of file diff --git a/vuln_apps/docker-compose.yml b/vuln_apps/docker-compose.yml new file mode 100644 index 0000000..468c294 --- /dev/null +++ b/vuln_apps/docker-compose.yml @@ -0,0 +1,27 @@ +version: "3.8" +services: + apache: + container_name: apache + build: ./docker/apache + links: + - php + ports: + - "80:80" + volumes: + - ./src:/usr/local/apache2/htdocs + php: + container_name: php + build: ./docker/php + ports: + - "9000:9000" + volumes: + - ./src:/usr/local/apache2/htdocs + working_dir: /usr/local/apache2/htdocs + mongo: + container_name: mongo + environment: + MONGO_INITDB_ROOT_USERNAME: root + MONGO_INITDB_ROOT_PASSWORD: prisma + build: ./docker/mongo + ports: + - "27017:27017" diff --git a/vuln_apps/docker/apache/Dockerfile b/vuln_apps/docker/apache/Dockerfile new file mode 100644 index 0000000..9562989 --- /dev/null +++ b/vuln_apps/docker/apache/Dockerfile @@ -0,0 +1,6 @@ +FROM httpd:2.4.51 + +COPY apache.conf /usr/local/apache2/conf/apache.conf + +RUN echo "Include /usr/local/apache2/conf/apache.conf" \ + >> /usr/local/apache2/conf/httpd.conf \ No newline at end of file diff --git a/vuln_apps/docker/apache/apache.conf b/vuln_apps/docker/apache/apache.conf new file mode 100644 index 0000000..76f67dd --- /dev/null +++ b/vuln_apps/docker/apache/apache.conf @@ -0,0 +1,16 @@ +LoadModule deflate_module /usr/local/apache2/modules/mod_deflate.so +LoadModule proxy_module /usr/local/apache2/modules/mod_proxy.so +LoadModule proxy_fcgi_module /usr/local/apache2/modules/mod_proxy_fcgi.so + + + ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/usr/local/apache2/htdocs/$1 + + DocumentRoot /usr/local/apache2/htdocs + + + Options -Indexes +FollowSymLinks + DirectoryIndex index.php + AllowOverride All + Require all granted + + \ No newline at end of file diff --git a/vuln_apps/docker/mongo/Dockerfile b/vuln_apps/docker/mongo/Dockerfile new file mode 100644 index 0000000..6920c0c --- /dev/null +++ b/vuln_apps/docker/mongo/Dockerfile @@ -0,0 +1,5 @@ +FROM mongo:latest + +ADD ./mongo.nosql /tmp/mongo.nosql +ADD ./import.sh /tmp/import.sh +RUN chmod +x /tmp/import.sh diff --git a/vuln_apps/docker/mongo/import.sh b/vuln_apps/docker/mongo/import.sh new file mode 100644 index 0000000..a845618 --- /dev/null +++ b/vuln_apps/docker/mongo/import.sh @@ -0,0 +1,2 @@ +#!/bin/bash +cat /tmp/mongo.nosql | mongosh "mongodb://root:prisma@mongo:27017" \ No newline at end of file diff --git a/vuln_apps/mongo.nosql b/vuln_apps/docker/mongo/mongo.nosql similarity index 99% rename from vuln_apps/mongo.nosql rename to vuln_apps/docker/mongo/mongo.nosql index 45bfcbc..577f0ed 100644 --- a/vuln_apps/mongo.nosql +++ b/vuln_apps/docker/mongo/mongo.nosql @@ -5,7 +5,6 @@ db.orders.insert({"id":"1","name":"Robin","item":"Music gift cards","quantity":" 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"}) @@ -13,7 +12,6 @@ db.paymentinfo.insert({"name":"Robin","id":"1","cc":"3333444455556666","cvv2":"2 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"}) diff --git a/vuln_apps/docker/php/Dockerfile b/vuln_apps/docker/php/Dockerfile new file mode 100644 index 0000000..a266475 --- /dev/null +++ b/vuln_apps/docker/php/Dockerfile @@ -0,0 +1,13 @@ +FROM php:8.1-fpm + +RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" +RUN echo "extension=mongodb.so" >> "$PHP_INI_DIR/php.ini" + +RUN apt-get update \ + && apt-get install -y libcurl4-openssl-dev pkg-config libssl-dev \ + && apt-get install -y git zip unzip \ + && pecl install mongodb \ + && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ + && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \ + && rm composer-setup.php \ + && composer require mongodb/mongodb \ No newline at end of file diff --git a/vuln_apps/orderdata.php b/vuln_apps/orderdata.php deleted file mode 100644 index 427359f..0000000 --- a/vuln_apps/orderdata.php +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -Order Lookup - - - -shop; - $collection = $db->orders; - $search = $_GET['ordersearch']; - $js = "function () { var query = '". $search . "'; return this.id == query;}"; - //print $js; - print '
'; - - $cursor = $collection->find(array('$where' => $js)); - echo $cursor->count() . ' order(s) found.
'; - - foreach ($cursor as $obj) { - echo 'Order ID: ' . $obj['id'] . '
'; - echo 'Name: ' . $obj['name'] . '
'; - echo 'Item: ' . $obj['item'] . '
'; - echo 'Quantity: ' . $obj['quantity']. '
'; - echo '
'; - } - -$conn->close(); -} catch (MongoConnectionException $e) { - die('Error connecting to MongoDB server : ' . $e->getMessage()); -} catch (MongoException $e) { - die('Error: ' . $e->getMessage()); -} -} -?> - - -Use the Order ID to locate your order:
-
-

Search

-
-
- -
- - diff --git a/vuln_apps/src/acct.php b/vuln_apps/src/acct.php new file mode 100644 index 0000000..21725a7 --- /dev/null +++ b/vuln_apps/src/acct.php @@ -0,0 +1,42 @@ + + + + Payment information + + + + [], + ]; + $filter = ['id' => $_GET['acctid']]; + $query = new MongoDB\Driver\Query($filter, $options); + + $cursor = $conn->executeQuery('customers.paymentinfo', $query); + $counter = 0; + + foreach ($cursor as $obj) { + $counter++; + echo 'Name: ' . $obj->name . '
'; + echo 'Customer ID: ' . $obj->id . '
'; + echo 'Card Number: ' . $obj->cc . '
'; + echo 'CVV2 Code: ' . $obj->cvv2 . '
'; + echo '
'; + } + + echo $counter . ' document(s) found.
'; + + } catch (MongoConnectionException $e) { + die('Error connecting to MongoDB server : ' . $e->getMessage()); + } catch (MongoException $e) { + die('Error: ' . $e->getMessage()); + } + ?> + + + + + \ No newline at end of file diff --git a/vuln_apps/src/index.html b/vuln_apps/src/index.html new file mode 100644 index 0000000..62996f1 --- /dev/null +++ b/vuln_apps/src/index.html @@ -0,0 +1,17 @@ + + + Customer Info + + + +

Customer Information

+

Enter your customer ID to show your account information:

+ +
+ Customer ID: + +
+ +
+ + diff --git a/vuln_apps/src/orderdata.php b/vuln_apps/src/orderdata.php new file mode 100644 index 0000000..0430cc2 --- /dev/null +++ b/vuln_apps/src/orderdata.php @@ -0,0 +1,49 @@ + + + + Order Lookup + + + shop; + $collection = $db->orders; + $search = $_GET['ordersearch']; + $js = "function () { var query = '". $search . "'; return this.id == query;}"; + //print $js; + print '
'; + + $cursor = $collection->find(array('$where' => $js)); + echo $cursor->count() . ' order(s) found.
'; + + foreach ($cursor as $obj) { + echo 'Order ID: ' . $obj['id'] . '
'; + echo 'Name: ' . $obj['name'] . '
'; + echo 'Item: ' . $obj['item'] . '
'; + echo 'Quantity: ' . $obj['quantity']. '
'; + echo '
'; + } + $conn->close(); + } catch (MongoConnectionException $e) { + die('Error connecting to MongoDB server : ' . $e->getMessage()); + } catch (MongoException $e) { + die('Error: ' . $e->getMessage()); + } + } + ?> + + + Use the Order ID to locate your order:
+
+

Search

+
+
+ +
+ + + \ No newline at end of file diff --git a/vuln_apps/populate_db.php b/vuln_apps/src/populate_db.php similarity index 99% rename from vuln_apps/populate_db.php rename to vuln_apps/src/populate_db.php index 44d2576..c058543 100644 --- a/vuln_apps/populate_db.php +++ b/vuln_apps/src/populate_db.php @@ -104,4 +104,4 @@ echo $obj["email"] . "
"; } -?> +?> \ No newline at end of file diff --git a/vuln_apps/src/userdata.php b/vuln_apps/src/userdata.php new file mode 100644 index 0000000..bf74313 --- /dev/null +++ b/vuln_apps/src/userdata.php @@ -0,0 +1,48 @@ + + + + User Profile Lookup + + + appUserData; + $collection = $db->users; + $search = $_GET['usersearch']; + $js = "function () { var query = '". $usersearch . "'; return this.username == query;}"; + print $js; + print '
'; + + $cursor = $collection->find(array('$where' => $js)); + echo $cursor->count() . ' user found.
'; + + foreach ($cursor as $obj) { + echo 'Name: ' . $obj['name'] . '
'; + echo 'Username: ' . $obj['username'] . '
'; + echo 'Email: ' . $obj['email'] . '
'; + echo '
'; + } + + $conn->close(); + } catch (MongoConnectionException $e) { + die('Error connecting to MongoDB server : ' . $e->getMessage()); + } catch (MongoException $e) { + die('Error: ' . $e->getMessage()); + } + } + ?> + + + Enter your username:
+
+

Search

+
+
+ +
+ + \ No newline at end of file diff --git a/vuln_apps/userdata.php b/vuln_apps/userdata.php deleted file mode 100644 index 0fc8165..0000000 --- a/vuln_apps/userdata.php +++ /dev/null @@ -1,50 +0,0 @@ - - - - - -User Profile Lookup - - - -appUserData; - $collection = $db->users; - $search = $_GET['usersearch']; - $js = "function () { var query = '". $usersearch . "'; return this.username == query;}"; - print $js; - print '
'; - - $cursor = $collection->find(array('$where' => $js)); - echo $cursor->count() . ' user found.
'; - - foreach ($cursor as $obj) { - echo 'Name: ' . $obj['name'] . '
'; - echo 'Username: ' . $obj['username'] . '
'; - echo 'Email: ' . $obj['email'] . '
'; - echo '
'; - } - -$conn->close(); -} catch (MongoConnectionException $e) { - die('Error connecting to MongoDB server : ' . $e->getMessage()); -} catch (MongoException $e) { - die('Error: ' . $e->getMessage()); -} -} -?> - - -Enter your username:
-
-

Search

-
-
- -
- -