OSSのセキュリティスキャナーTsunami(tsunami-security-scanner)をAmazon Linux 2で試してみた

先日知ったオープンソースソフトウェアのセキュリティスキャナー Tsunami(tsunami-security-scanner)をAmazon Linux 2で試してみました。
2020.07.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、コカコーラ大好きカジです。

先日知ったオープンソースソフトウェアのセキュリティスキャナー Tsunami(tsunami-security-scanner)をAmazon Linux 2で試してみました。

Tsunami(tsunami-security-scanner)とは

詳細はTsunami: An extensible network scanning engine for detecting high severity vulnerabilities with high confidence | Google Open Source Blogです。

現状は、開発者プレビューリリースのようです。私なりに3行でザックリまとめると

  • Amazon Inspetorなどのエージェントによる内部スキャンと異なり、ネットワーク経由でシステム外部からの脆弱性スキャンを実行するもの
  • コマンドライン実行のためスケールしやすい
  • プラグインを追加することにより色々なスキャンが行える

インストールされたフォルダのプラグインのところに以下のようなファイルがありました。

nmap_port_scanner-0.0.1-SNAPSHOT.jar
ncrack_weak_credential_detector-0.0.1-SNAPSHOT.jar
exposed_jupyter_notebook-0.0.1-SNAPSHOT.jar
exposed_jenkins_ui-0.0.1-SNAPSHOT.jar
exposed_hadoop_yarn_api-0.0.1-SNAPSHOT.jar

https://github.com/google/tsunami-security-scanner/blob/master/README.md

結果

ドキュメントのQuick Startの内容で検知できました。(2020/7/21時点)

私の方で、以下の内容を試しましたが、意図した結果が得られませんでした。(実施方法に問題があるかもしれません。また、これから修正される可能性もあります。)

  • 古いApacheのバージョン(httpd-2.4.37-1.amzn2.0.1.x86_64)をインストール
  • 古いバージョンのJenkins(jenkins-2.232-1.1.noarch)をインストールし、脆弱なユーザ作成(User:123456/Pass:123456)を作成

環境

以下のAMIを利用しました。古めのOSを利用して色々検知すること期待しましたが、外部スキャンのため特に意味がありませんでした。

amzn2-ami-hvm-2.0.20181024-x86_64-gp2 (ami-00f9d04b3b3092052)

インストール

sshでEC2にログインして以下を実行します。

必要なパッケージインストール

OpenJDKではなく、corretto8を利用してみました。

sudo yum install nmap
# 必要なパッケージであるncrackをインストールするためEPELリポジトリを有効
sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo yum install ncrack

# javaインストールのため
sudo amazon-linux-extras enable corretto8
sudo yum install java-1.8.0-amazon-corretto-devel

# gitインストールのため
sudo yum install git

ツールのインストール

こちらの通りに実行しました。

注意:実行時に以下のエラーで停止する場合、メモリ不足です。 t2.nanoで最初試したら以下のエラーが発生して停止しました。t2.smallでテストしました。

'Gradle Test Executor' finished with non-zero exit value 137

実際のインストールログ

$ 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.

Fetching source code for Tsunami scanner plugins ...
From https://github.com/google/tsunami-security-scanner-plugins
 * branch            master     -> FETCH_HEAD
Already up to date.

Building all Google plugins ...

Building detectors/credentials/ncrack ...
Starting a Gradle Daemon, 1 busy and 1 incompatible and 1 stopped Daemons could not be reused, use --status for details

<省略>

BUILD SUCCESSFUL in 1m 56s
14 actionable tasks: 14 executed

Build successful, execute the following command to scan 127.0.0.1:

cd /home/ec2-user/tsunami && \
java -cp "tsunami-main-0.0.2-SNAPSHOT-cli.jar:/home/ec2-user/tsunami/plugins/*" \
  -Dtsunami-config.location=/home/ec2-user/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
$

脆弱性を持つアプリケーションの起動

認証がされていない脆弱性を持つjupyter-notebookを起動

sudo yum install docker
sudo systemctl start docker
sudo systemctl status docker
sudo docker run --name unauthenticated-jupyter-notebook -p 8888:8888 -d jupyter/base-notebook start-notebook.sh --NotebookApp.token=''

スキャン実行

$ cd /home/ec2-user/tsunami && \
> java -cp "tsunami-main-0.0.2-SNAPSHOT-cli.jar:/home/ec2-user/tsunami/plugins/*" \
>   -Dtsunami-config.location=/home/ec2-user/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
7 21, 2020 9:29:45 午前 com.google.tsunami.main.cli.TsunamiCli main
情報: Full classpath scan took 6.245 s
7 21, 2020 9:29:46 午前 com.google.tsunami.common.config.ConfigModule configure

<省略>

情報: Tsunami scanning workflow traces:
  Port scanning phase (16.53 s) with 1 plugin(s):
    /Tsunami Team (tsunami-dev@google.com)/PORT_SCAN/NmapPortScanner/0.1
  Service fingerprinting phase (379.1 ms) with 0 plugin(s):

  Vuln detection phase (537.1 ms) with 5 plugin(s):
    /Tsunami Team (tsunami-dev@google.com)/VULN_DETECTION/NcrackWeakCredentialDetectorPlugin/0.1 was selected for the following services: ssh (TCP, port 22), smtp (TCP, port 25), rpcbind (TCP, port 111), tcpwrapped (TCP, port 8080), http-proxy (TCP, port 8888)
    /Tsunami Team (tsunami-dev@google.com)/VULN_DETECTION/YarnExposedManagerApiDetector/0.1 was selected for the following services: ssh (TCP, port 22), smtp (TCP, port 25), rpcbind (TCP, port 111), tcpwrapped (TCP, port 8080), http-proxy (TCP, port 8888)
    /Tsunami Team (tsunami-dev@google.com)/VULN_DETECTION/JenkinsExposedUiDetector/0.1 was selected for the following services: ssh (TCP, port 22), smtp (TCP, port 25), rpcbind (TCP, port 111), tcpwrapped (TCP, port 8080), http-proxy (TCP, port 8888)
    /Tsunami Team (tsunami-dev@google.com)/VULN_DETECTION/JupyterExposedUiDetector/0.1 was selected for the following services: ssh (TCP, port 22), smtp (TCP, port 25), rpcbind (TCP, port 111), tcpwrapped (TCP, port 8080), http-proxy (TCP, port 8888)
    /Tsunami Team (tsunami-dev@google.com)/VULN_DETECTION/WordPressInstallPageDetector/0.1 was selected for the following services: ssh (TCP, port 22), smtp (TCP, port 25), rpcbind (TCP, port 111), tcpwrapped (TCP, port 8080), http-proxy (TCP, port 8888)
  # of detected vulnerability: 1.
7 21, 2020 9:30:04 午前 com.google.tsunami.main.cli.TsunamiCli run
情報: Tsunami scan finished, saving results.
7 21, 2020 9:30:04 午前 com.google.tsunami.common.io.archiving.RawFileArchiver archive
情報: Archiving data to file system with filename '/tmp/tsunami-output.json'.
7 21, 2020 9:30:04 午前 com.google.tsunami.main.cli.TsunamiCli run
情報: TsunamiCli finished...
7 21, 2020 9:30:04 午前 com.google.tsunami.main.cli.TsunamiCli main
情報: Full Tsunami scan took 24.89 s.
$

結果確認

検知結果が、JSONで出力されます。

[ec2-user@ip-10-1-11-229 tmp]$ cat /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-proxy",
      "software": {
        "name": "sslstrip"
      }
    },
    "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-07-21T09:29:46.824Z",
  "scanDuration": "17.525s",
  "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-proxy",
        "software": {
          "name": "sslstrip"
        }
      },
      "detectionTimestamp": "2020-07-21T09:30:04.002Z",
      "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"
      }
    }]
  }
}

その他

ApacheやJenkinsの古いバージョンをスキャンした時に意図した検知結果が出なかったときの結果

$ cat /tmp/tsunami-output.json
{
  "scanStatus": "SUCCEEDED",
  "scanStartTimestamp": "2020-07-21T09:17:08.627Z",
  "scanDuration": "12.014s",
  "fullDetectionReports": {
  }

まとめ

  • Amazon Linux 2でも動作(現時点で)
  • nanoクラスのインスタンスはメモリ不足で動作不可
  • 今後のプラグインで拡張され、自動でいろいろな脆弱性診断できそう
  • 個人的な感覚ですが、スキャンスピードは高速(プラグインが少ないためかもしれません)

参考元

Google、セキュリティスキャナー「Tsunami」をオープンソースで公開。ポートスキャンなどで自動的に脆弱性を検出するツール - Publickey 話題のGoogle製OSS - Tsunamiを試してみた - Qiita