Vulsで脆弱性スキャンを自動化してSlackとメール通知させ、本番環境で実稼働させるレベルに持っていく




vuls-ogp
シンジです。サーバーの脆弱性をスキャンしてくれる無償ツールVulsは何かと便利なのはいいのですが、これを本番環境で実稼働させてPCIDSSの監査にまで使えるレベルへ持っていくところまでやってしまえという話です。

前提として

Vulsは無償でお手軽に脆弱性診断出来るツールとしては優秀だと思いますが、いわゆる「診断士」が行うようなカスタムやフルスクラッチのアプリケーションに対して診断を行うわけでは無いですし、あくまでCVEとして公開されている脆弱性情報と合致するかをお知らせしてくれるだけのツールですから、これだけに頼って「完璧だ」「安全だ」とかいう勘違いはしない方がよいです。

とはいえ、例えばPCI DSS監査においては、公開されている脆弱性情報への対応具合は聞かれますし、CSIRTで収集した情報が、例えば社内インフラに限ってみたときにどの程度対応出来ているかを判断する指標の材料にはなりますから、道具は使いようということで、うまく使いましょう。

とりあえずEC2使います

OSはAmazon Linuxです。まぁよしなに起動して下さい。起動時にyum updateすると、早速立ちあがるインスタンスで脆弱性が出るところが確認出来ないのでそのまま起動させるのがオススメです。面白いし。もちろんOS起動直後にもyum updateはしません。
今回はマジメな構成でマジメに稼働させることが前提なので、インターネットへの通信はNAT経由でしかさせませんし、パブリックIPも付けません。

Vulsをセットアップする

闇雲にコマンドを打ち続けます。全部で20分くらいで終わります。

[bash] sudo yum install sqlite git gcc
[/bash] [bash] wget https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz
[/bash] [bash] sudo tar -C /usr/local -xzf go1.6.linux-amd64.tar.gz
mkdir $HOME/go
[/bash] [bash] vi /etc/profile.d/goenv.sh
[/bash] [bash] export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
[/bash] [bash] source /etc/profile.d/goenv.sh
[/bash] [bash] sudo mkdir /var/log/vuls
sudo chown ec2-user /var/log/vuls
sudo chmod 700 /var/log/vuls
mkdir vuls
cd vuls
go get github.com/kotakanbe/go-cve-dictionary
[/bash] [bash] for i in {2002..2016}; do go-cve-dictionary fetchnvd -years $i; done
[/bash] [bash] go get github.com/future-architect/vuls
[/bash]

で、コンフィグファイルがミソです。この記述通りに書きましょう。

[bash] vi config.toml
[/bash] [bash] [default] port = "22"
user = "ec2-user"
keyPath = "/home/ec2-user/sshkey/xxxxxxxxxxx.pem"

[slack] hookURL = "https://hooks.slack.com/services/xxxxxxxx/xxxxxxxxxx/xxxxxxxxxxxxxxxxxxxxx"
channel = "time-shinji-shinji"
iconEmoji = ":ghost:"
authUser = "vuls"
notifyUsers = ["@here"] [mail] smtpAddr = "smtp.gmail.com"
smtpPort = "465"
user = "username"
password = "password"
from = "from@address.com"
to = ["to@address.com"] cc = ["cc@address.com"] subjectPrefix = "[vuls]"

[servers] [servers.xxx-xxx-xxx-xxx] host = "xxx.xxx.xxx.xxx"

[servers.xxx-xxx-xxx-xxx] host = "xxx.xxx.xxx.xxx"

[servers.xxx-xxx-xxx-xxx] host = "xxx.xxx.xxx.xxx"

[servers.xxx-xxx-xxx-xxx] host = "xxx.xxx.xxx.xxx"
[/bash]

sshの鍵をVulsのサーバーに転送

scpなりで適当に転送しましょう。上の記述のkeyPathと合致するパスにおいてあればOKです。

ちなみにSlack通知を使いますが

Incoming WebHooksです。で、初回のチャンネル設定以外は触らないで下さい。下手にSlack側を触ると正しく動かないことを確認しています。

メール通知設定も書きましたが

シンジはメールを見ない宗教なので実際には消してあります。

続きます

[bash] vuls prepare
[/bash]

問題があれば(サーバーと疎通が取れないとかは)ここでエラーを吐きます。頑張って解決して下さいwww

実際のスキャンに入る前に、コマンドヘルプを見ておきましょう。実はログをS3にアップロードできたりとか、いろんなことが出来るのが確認出来ます。

[bash] vuls scan -help
[/bash] [bash] scan:
scan
[-lang=en|ja] [-config=/path/to/config.toml] [-dbpath=/path/to/vuls.sqlite3] [-cve-dictionary-dbpath=/path/to/cve.sqlite3] [-cve-dictionary-url=http://127.0.0.1:1323] [-cvss-over=7] [-ignore-unscored-cves] [-ssh-external] [-report-json] [-report-mail] [-report-s3] [-report-slack] [-report-text] [-http-proxy=http://192.168.0.1:8080] [-ask-sudo-password] [-ask-key-password] [-debug] [-debug-sql] [-aws-profile=default] [-aws-region=us-west-2] [-aws-s3-bucket=bucket_name] -ask-key-password
Ask ssh privatekey password before scanning
-ask-sudo-password
Ask sudo password of target servers before scanning
-aws-profile string
AWS Profile to use (default "default")
-aws-region string
AWS Region to use (default "us-east-1")
-aws-s3-bucket string
S3 bucket name
-config string
/path/to/toml (default "/home/ec2-user/vuls/config.toml")
-cve-dictionary-dbpath string
/path/to/sqlite3 (For get cve detail from cve.sqlite3)
-cve-dictionary-url string
http://CVE.Dictionary (default "http://127.0.0.1:1323")
-cvss-over float
-cvss-over=6.5 means reporting CVSS Score 6.5 and over (default: 0 (means report all))
-dbpath string
/path/to/sqlite3 (default "/home/ec2-user/vuls/vuls.sqlite3")
-debug
debug mode
-debug-sql
SQL debug mode
-http-proxy string
http://proxy-url:port (default: empty)
-ignore-unscored-cves
Don’t report the unscored CVEs
-lang string
[en|ja] (default "en")
-report-json
Write report to JSON files (/home/ec2-user/vuls/results/current)
-report-mail
Send report via Email
-report-s3
Write report to S3 (bucket/yyyyMMdd_HHmm)
-report-slack
Send report via Slack
-report-text
Write report to text files (/home/ec2-user/vuls/results/current)
-ssh-external
Use external ssh command. Default: Use the Go native implementation
-use-unattended-upgrades
[Deprecated] For Ubuntu. Scan by unattended-upgrades or not (use apt-get upgrade –dry-run by default)
-use-yum-plugin-security
[Deprecated] For CentOS 5. Scan by yum-plugin-security or not (use yum check-update by default)
[/bash]

では実行します

今回はSlack通知のみ有効にしています。引数で指定します。

[bash] vuls scan –cve-dictionary-dbpath /home/ec2-user/vuls/cve.sqlite3 -report-slack
[/bash] [bash] INFO[0000] Start scanning
INFO[0000] config: /home/ec2-user/vuls/config.toml
INFO[0000] cve-dictionary: /home/ec2-user/vuls/cve.sqlite3
[Jul 1 04:44:38] INFO [localhost] Validating Config…
[Jul 1 04:44:38] INFO [localhost] Detecting Server OS…
[Jul 1 04:44:38] INFO [localhost] (1/1) Detected xxx-xxx-xxx-xxx: amazon 2016.03
[Jul 1 04:44:38] INFO [localhost] Detecting Container OS…
[Jul 1 04:44:38] INFO [localhost] Detecting Platforms…
[Jul 1 04:44:39] INFO [localhost] (1/1) xxx-xxx-xxx-xxx is running on aws
[Jul 1 04:44:39] INFO [localhost] Scanning vulnerabilities…
[Jul 1 04:44:39] INFO [localhost] Check required packages for scanning…
[Jul 1 04:44:39] INFO [localhost] Scanning vulnerable OS packages…
[Jul 1 04:44:41] INFO [xxx-xxx-xxx-xxx] Fetching CVE details…
[Jul 1 04:44:41] INFO [xxx-xxx-xxx-xxx] Done
[Jul 1 04:44:41] INFO [localhost] Scanning vulnerable software specified in the CPE…
[Jul 1 04:44:41] INFO [localhost] Insert to DB…
[Jul 1 04:44:42] INFO [localhost] Reporting…
xxx-xxx-xxx-xxx (amazon2016.03)
==========================
CVE-2016-4997 ?

CVE-2016-4997
————-
Score ?
NVD https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-4997
CVE Details http://www.cvedetails.com/cve/CVE-2016-4997
RHEL-CVE https://access.redhat.com/security/cve/CVE-2016-4997
ALAS-2016-718 https://alas.aws.amazon.com/ALAS-2016-718.html
[/bash]

Slackではこう見えます

vuls-slack01

最高。

Slack最高!!!!!!!

そして突如訪れる世界平和。

さて後はVuls稼働を自動化してやりましょう

やることはこんな感じです。
1. go-cve-dictionaryを最新にして
2. Vulsを最新にして
3. CVEの情報を最新に更新して
4. Vulsでスキャン

を、毎日やる。ということにする。

  1. go-cve-dictionaryの更新
    [bash] cd $GOPATH/src/github.com/kotakanbe/go-cve-dictionary
    go install github.com/kotakanbe/go-cve-dictionary
    [/bash]
  2. Vulsの更新
    [bash] cd $GOPATH/src/github.com/future-architect/vuls
    go install github.com/future-architect/vuls
    [/bash]

  3. CVE情報の最新化
    [bash] go-cve-dictionary fetchnvd -last2y
    [/bash]

  4. Vulsでスキャン
    [bash] vuls scan –cve-dictionary-dbpath /home/ec2-user/vuls/cve.sqlite3 -report-slack
    [/bash]

これを一発で実行させるスクリプトを用意します

[bash] vi hogehoge.sh
[/bash] [bash] #!/bin/bash
echo "####################"
echo "vuls update & scan start!"
echo "####################"

cd /home/ec2-user

# CVE更新
go get -u github.com/kotakanbe/go-cve-dictionary

# Vulsの更新
go get -u github.com/future-architect/vuls

# CVE情報の最新化
go-cve-dictionary fetchnvd -last2y

cd /home/ec2-user/vuls

# Vulsでスキャン
vuls scan –cve-dictionary-dbpath /home/ec2-user/vuls/cve.sqlite3 -report-slack

echo "####################"
echo "vuls update & scan finish!"
echo "####################"
[/bash]

こんなかんじ?

毎日、自動実行するようにします

[bash] sudo vi /etc/cron.d/scan-vuls
[/bash] [bash] SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
HOME=/

30 09 * * * ec2-user /home/ec2-user/vuls/vuls.sh
[/bash]

crontab -e でもいい気がしてきたけどまぁいいか。
とりあえずこんなかんじ?

というわけで

自社でCSIRT始めたいけどよーわからんとかいう方には、Vulsはいいきっかけになるかもしれませんね。実際に上がってきた脆弱性を評価議論して、対応方針を決めて、実行する。その結果どうだったか評価する。この繰り返しです。

ただ単純に、「脆弱性があった、yum updateした、なおった、ワーイヽ(・∀・)ノ」で終わらないように、組織だった活動に生かせるツールとして有効利用しましょう〜