話題のGoogle製OSS - Tsunamiを試してみた

# はじめに
先日発表された話題のGoogle製OSS - [Tsunami](https://github.com/google/tsunami-security-scanner)を触ってみたので，実行方法と概要を残したいと思います．

# TL;DR
- **サクッ**とコマンド叩くと**脆弱性**をjson形式で**返してくれる**ので便利
- ただ，**XSS**や**SQLインジェクション**といった内部のセキュリティーホールは**見てくれない**（これから対応するかもしれないが）
- どちらかと言うと，**システムたくさん**持ってる**企業向け**

しかし，実行まで３分もかからないので，試してみる価値はあると思います．

# Tsunamiとは
Tsunamiは，システムの脆弱性を**高い信頼性**のもと**最小の誤検知率**でRCE（遠隔からのコード実行）のような深刻度の高い**脆弱性の検出**を行います．
特徴としては，システム内部から実行することなく，**外部**から**高速に実行**でき，かつ，システムの規模に合わせて**簡単にスケール**することができます．

## 作られた背景
昨今，攻撃者は自動化に力を入れているため，従来の人手による脆弱性のチェックでは攻撃者の攻撃速度に対応することができません．
そのため，システムの脆弱性を高い信頼性のもと自動で検出し，情報セキュリティーチームをサーポートするためにTsunamiが作られました．

（背景が堅かったので要約しました．間違いがあればコメントでご指摘ください）

# スキャンしてみる
ドキュメントのQuick Startを参考に実行してみたいと思います．
https://github.com/google/tsunami-security-scanner#quick-start

## 準備
Ubuntu18.04の環境で実行しています．
また，実行には，以下のツールが必要です．

- nmap
- ncrack
- Java
- Docker (脆弱性を持ったアプリケーションを立ち上げるために必要です)

今回は，Dockerのインストールが事前に済んでいる前提とします．

### 環境構築
必要なものをインストールしていきます．

```bash:nmapとncrackのインストール
$ sudo apt update
$ sudo apt install -y nmap ncrack

# 入ったかチェック
$ which nmap
/usr/bin/nmap

$ which ncrack
/usr/bin/ncrack
```

```bash:Java8のインストール
$ sudo apt install openjdk-8-jdk

# 入ったかチェック
$ java -version
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (build 1.8.0_252-8u252-b09-1~18.04-b09)
OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)
```

## 実行

### 脆弱性を持つアプリケーションの起動
認証がされていない脆弱性を持つJupyterを起動します．

```bash
$ docker run --name unauthenticated-jupyter-notebook -p 8888:8888 -d jupyter/base-notebook start-notebook.sh --NotebookApp.token=''
```

### Tsunamiの用意
実行に必要なファイルを/home/user/配下に配置します．

```bash
$ bash -c "$(curl -sfL https://raw.githubusercontent.com/google/tsunami-security-scanner/master/quick_start.sh)"
Fetching source code for Tsunami scanner ...
From https://github.com/google/tsunami-security-scanner
 * branch            master     -> FETCH_HEAD
Already up to date.
・
・
・
Build successful, execute the following command to scan 127.0.0.1:

cd /home/user/tsunami && \
java -cp "tsunami-main-0.0.2-SNAPSHOT-cli.jar:/home/taro/tsunami/plugins/*" \
  -Dtsunami-config.location=/home/taro/tsunami/tsunami.yaml \
  com.google.tsunami.main.cli.TsunamiCli \
  --ip-v4-target=127.0.0.1 \
  --scan-results-local-output-format=JSON \
  --scan-results-local-output-filename=/tmp/tsunami-output.json
```
最後の行にはTsunami実行コマンドが表示されるので，cd以下を7行をコピーします．

### スキャン開始
先程コピーしたコマンドを貼り付けて実行します．

```bash
$ cd /home/user/tsunami && \
java -cp "tsunami-main-0.0.2-SNAPSHOT-cli.jar:/home/taro/tsunami/plugins/*" \
  -Dtsunami-config.location=/home/taro/tsunami/tsunami.yaml \
  com.google.tsunami.main.cli.TsunamiCli \
  --ip-v4-target=127.0.0.1 \
  --scan-results-local-output-format=JSON \
  --scan-results-local-output-filename=/tmp/tsunami-output.json
```

## 結果
スキャンの結果はコマンドの末尾で指定した，`/tmp/tsunami-output.json`に出力されるので，見てみましょう．

細かい解説は省きますが，レポートは以下のような構成になっています

- スキャンステータス
- ネットワークサービス情報
- 脆弱性情報
- 検出情報

致命的な脆弱性として**Jupyter Notebook is not password or token protected**が検出されていることがわかります．
その他は，問題ないようです．

```json:/tmp/tsunami-output.json
{
  "scanStatus": "SUCCEEDED",
  "scanFindings": [{
    "targetInfo": {
      "networkEndpoints": [{
        "type": "IP",
        "ipAddress": {
          "addressFamily": "IPV4",
          "address": "127.0.0.1"
        }
      }]
    },
    "networkService": {
      "networkEndpoint": {
        "type": "IP_PORT",
        "ipAddress": {
          "addressFamily": "IPV4",
          "address": "127.0.0.1"
        },
        "port": {
          "portNumber": 8888
        }
      },
      "transportProtocol": "TCP",
      "serviceName": "http",
      "software": {
        "name": "Tornado httpd"
      },
      "versionSet": {
        "versions": [{
          "type": "NORMAL",
          "fullVersionString": "6.0.4"
        }]
      }
    },
    "vulnerability": {
      "mainId": {
        "publisher": "GOOGLE",
        "value": "JUPYTER_NOTEBOOK_EXPOSED_UI"
      },
      "severity": "CRITICAL",
      "title": "Jupyter Notebook Exposed Ui",
      "description": "Jupyter Notebook is not password or token protected"
    }
  }],
  "scanStartTimestamp": "2020-06-26T16:04:43.448Z",
  "scanDuration": "21.928s",
  "fullDetectionReports": {
    "detectionReports": [{
      "targetInfo": {
        "networkEndpoints": [{
          "type": "IP",
          "ipAddress": {
            "addressFamily": "IPV4",
            "address": "127.0.0.1"
          }
        }]
      },
      "networkService": {
        "networkEndpoint": {
          "type": "IP_PORT",
          "ipAddress": {
            "addressFamily": "IPV4",
            "address": "127.0.0.1"
          },
          "port": {
            "portNumber": 8888
          }
        },
        "transportProtocol": "TCP",
        "serviceName": "http",
        "software": {
          "name": "Tornado httpd"
        },
        "versionSet": {
          "versions": [{
            "type": "NORMAL",
            "fullVersionString": "6.0.4"
          }]
        }
      },
      "detectionTimestamp": "2020-06-26T16:05:05.366Z",
      "detectionStatus": "VULNERABILITY_VERIFIED",
      "vulnerability": {
        "mainId": {
          "publisher": "GOOGLE",
          "value": "JUPYTER_NOTEBOOK_EXPOSED_UI"
        },
        "severity": "CRITICAL",
        "title": "Jupyter Notebook Exposed Ui",
        "description": "Jupyter Notebook is not password or token protected"
      }
    }]
  }
}
```

# おわりに
Tsunamiの概要と実行方法を紹介しました．
スキャン結果は，ポートやIPといったネットワーク情報やサービスの脆弱性が出力されました．
これらの情報をサービスリリース毎に人手でチェックするには時間がかかるため，
Tsunamiを使い客観的な情報を元に，脆弱性を自動で判断するのはとても効率が良いのではないでしょうか．