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

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

前提として

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

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

とりあえずEC2使います

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

Vulsをセットアップする

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

sudo yum install sqlite git gcc
wget https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.6.linux-amd64.tar.gz
mkdir $HOME/go
vi /etc/profile.d/goenv.sh
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
source /etc/profile.d/goenv.sh
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
for i in {2002..2016}; do go-cve-dictionary fetchnvd -years $i; done
go get github.com/future-architect/vuls

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

vi config.toml
[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"

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

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

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

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

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

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

続きます

vuls prepare

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

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

vuls scan -help
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)

では実行します

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

vuls scan --cve-dictionary-dbpath /home/ec2-user/vuls/cve.sqlite3 -report-slack
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

Slackではこう見えます

vuls-slack01

最高。

Slack最高!!!!!!!

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

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

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

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

  1. go-cve-dictionaryの更新
    cd $GOPATH/src/github.com/kotakanbe/go-cve-dictionary
    go install github.com/kotakanbe/go-cve-dictionary
    

  2. Vulsの更新

    cd $GOPATH/src/github.com/future-architect/vuls
    go install github.com/future-architect/vuls
    

  3. CVE情報の最新化

    go-cve-dictionary fetchnvd -last2y
    

  4. Vulsでスキャン

    vuls scan --cve-dictionary-dbpath /home/ec2-user/vuls/cve.sqlite3 -report-slack
    

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

vi hogehoge.sh
#!/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 "####################"

こんなかんじ?

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

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

30 09 * * * ec2-user /home/ec2-user/vuls/vuls.sh

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

というわけで

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

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