Vulnerability scanner for Linux/FreeBSD, agentless, written in golang.
README in English
Slackチームはこちらから参加できます。(日本語でオッケーです)
毎日のように発見される脆弱性の調査やソフトウェアアップデート作業は、システム管理者にとって負荷の高いタスクである。 プロダクション環境ではサービス停止リスクを避けるために、パッケージマネージャの自動更新機能を使わずに手動更新で運用するケースも多い。 だが、手動更新での運用には以下の問題がある。
- システム管理者がNVDなどで新着の脆弱性をウォッチし続けなければならない
- サーバにインストールされているソフトウェアは膨大であり、システム管理者が全てを把握するのは困難
- 新着の脆弱性がどのサーバに該当するのかといった調査コストが大きく、漏れる可能性がある
Vulsは上に挙げた手動運用での課題を解決するツールであり、以下の特徴がある。
- システムに関係ある脆弱性のみ教えてくれる
- その脆弱性に該当するサーバを教えてくれる
- 自動スキャンのため脆弱性検知の漏れを防ぐことができる
- CRONなどで定期実行、レポートすることで脆弱性の放置を防ぐことできる
- Linuxサーバに存在する脆弱性をスキャン
- Ubuntu, Debian, CentOS, Amazon Linux, RHELに対応
- クラウド、オンプレミス、Docker
- OSパッケージ管理対象外のミドルウェアをスキャン
- プログラミング言語のライブラリやフレームワーク、ミドルウェアの脆弱性スキャン
- CPEに登録されているソフトウェアが対象
- エージェントレスアーキテクチャ
- スキャン対象サーバにSSH接続可能なマシン1台にセットアップするだけで動作
- 非破壊スキャン(SSHでコマンド発行するだけ)
- AWSでの脆弱性/侵入テスト事前申請は必要なし
- 設定ファイルのテンプレート自動生成
- CIDRを指定してサーバを自動検出、設定ファイルのテンプレートを生成
- EmailやSlackで通知可能(日本語でのレポートも可能)
- 付属するTerminal-Based User Interfaceビューアでは、Vim風キーバインドでスキャン結果を参照可能
- Web UI(VulsRepo)を使えばピボットテーブルのように分析可能
- Vulsはソフトウェアアップデートは行わない
Vulsのセットアップは以下の3パターンがある
- Dockerコンテナ上にセットアップ
see https://github.com/future-architect/vuls/tree/master/setup/docker
日本語README - Chefでセットアップ
see https://github.com/sadayuki-matsuno/vuls-cookbook - 手動でセットアップ
Hello Vulsチュートリアルでは手動でのセットアップ方法で説明する
本チュートリアルでは、Amazon EC2にVulsをセットアップし、自分に存在する脆弱性をスキャンする方法を説明する。 手順は以下の通り
- Amazon Linuxを新規作成
- 自分自身にSSH接続できるように設定
- 必要なソフトウェアをインストール
- go-cve-dictionaryをデプロイ
- Vulsをデプロイ
- 設定
- Prepare
- Scan
- Reporting
- TUI(Terminal-Based User Interface)で結果を参照する
- Web UI(VulsRepo)で結果を参照する
-
今回は説明のために、脆弱性を含む古いAMIを使う (amzn-ami-hvm-2015.09.1.x86_64-gp2 - ami-383c1956)
-
EC2作成時に自動アップデートされるとVulsスキャン結果が0件になってしまうので、cloud-initに以下を指定してEC2を作成する。
#cloud-config repo_upgrade: none
ローカルホストにSSH接続できるようにする。
SSHキーペアを作成し、公開鍵をauthorized_keysに追加する。
$ ssh-keygen -t rsa
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
VulsはSSHパスワード認証をサポートしていない。SSH公開鍵鍵認証を使う必要がある。 また、パスワードありのSUDOもセキュリティ上の理由によりサポートしていないため、スキャン対象サーバに/etc/sudoersにNOPASSWDを設定して、パスワードなしでSUDO可能にする必要がある。
Vulsセットアップに必要な以下のソフトウェアをインストールする。
- SQLite3 or MySQL
- git
- gcc
- go v1.7.1 or later (The latest version is recommended)
$ ssh [email protected] -i ~/.ssh/private.pem
$ sudo yum -y install sqlite git gcc
$ wget https://storage.googleapis.com/golang/go1.7.1.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.7.1.linux-amd64.tar.gz
$ mkdir $HOME/go
/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
Step4. Deploy go-cve-dictionary
$ sudo mkdir /var/log/vuls
$ sudo chown ec2-user /var/log/vuls
$ sudo chmod 700 /var/log/vuls
$
$ mkdir -p $GOPATH/src/github.com/kotakanbe
$ cd $GOPATH/src/github.com/kotakanbe
$ git clone https://github.com/kotakanbe/go-cve-dictionary.git
$ cd go-cve-dictionary
$ make install
バイナリは、$GOPATH/bin
いかに生成される
NVDから脆弱性データベースを取得する。
環境によって異なるが、AWS上では10分程度かかる。
$ cd $HOME
$ for i in {2002..2016}; do go-cve-dictionary fetchnvd -years $i; done
... snip ...
$ ls -alh cve.sqlite3
-rw-r--r-- 1 ec2-user ec2-user 7.0M Mar 24 13:20 cve.sqlite3
新規にターミナルを起動し、先ほど作成したEC2にSSH接続する。
$ mkdir -p $GOPATH/src/github.com/future-architect
$ cd $GOPATH/src/github.com/future-architect
$ git clone https://github.com/future-architect/vuls.git
$ cd vuls
$ make install
vulsを既にインストール済みでupdateしたい場合は
$ go get -u github.com/future-architect/vuls
で可能である。
go getでエラーが発生した場合は、以下の点を確認する。
- Gitのバージョンがv2以降か?
- Go依存パッケージの問題でgo getに失敗する場合は deploying with glide を試す。
Vulsの設定ファイルを作成する(TOMLフォーマット) 設定ファイルのチェックを行う
$ cd $HOME
$ cat config.toml
[servers]
[servers.172-31-4-82]
host = "172.31.4.82"
port = "22"
user = "ec2-user"
keyPath = "/home/ec2-user/.ssh/id_rsa"
$ vuls configtest
$ vuls prepare
詳細は Usage: Prepare を参照
$ vuls scan
... snip ...
Scan Summary
============
172-31-4-82 amazon 2015.09 94 CVEs 103 updatable packages
View one-line summary
$ vuls report -format-one-line-text -cvedb-path=$PWD/cve.sqlite3
One Line Summary
================
172-31-4-82 Total: 94 (High:19 Medium:54 Low:7 ?:14) 103 updatable packages
View short summary.
$ vuls report -format-short-text -cvedb-path=$PWD/cve.sqlite3
172-31-4-8 (amazon 2015.09)
===========================
Total: 94 (High:19 Medium:54 Low:7 ?:14) 103 updatable packages
CVE-2016-0705 10.0 (High) Double free vulnerability in the dsa_priv_decode function in
crypto/dsa/dsa_ameth.c in OpenSSL 1.0.1 before 1.0.1s and 1.0.2 before 1.0.2g
allows remote attackers to cause a denial of service (memory corruption) or
possibly have unspecified other impact via a malformed DSA private key.
http://www.cvedetails.com/cve/CVE-2016-0705
http://people.ubuntu.com/~ubuntu-security/cve/CVE-2016-0705
libssl1.0.0-1.0.2f-2ubuntu1 -> libssl1.0.0-1.0.2g-1ubuntu4.5
openssl-1.0.2f-2ubuntu1 -> openssl-1.0.2g-1ubuntu4.5
... snip ...
View full report.
$ vuls report -format-full-text -cvedb-path=$PWD/cve.sqlite3
172-31-4-82 (amazon 2015.09)
============================
Total: 94 (High:19 Medium:54 Low:7 ?:14) 103 updatable packages
CVE-2016-0705
-------------
Score 10.0 (High)
Vector (AV:N/AC:L/Au:N/C:C/I:C/A:C)
Summary Double free vulnerability in the dsa_priv_decode function in
crypto/dsa/dsa_ameth.c in OpenSSL 1.0.1 before 1.0.1s and 1.0.2 before 1.0.2g
allows remote attackers to cause a denial of service (memory corruption) or
possibly have unspecified other impact via a malformed DSA private key.
CWE https://cwe.mitre.org/data/definitions/.html
NVD https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-0705
MITRE https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0705
CVE Details http://www.cvedetails.com/cve/CVE-2016-0705
CVSS Claculator https://nvd.nist.gov/cvss/v2-calculator?name=CVE-2016-0705&vector=(AV:N/AC:L/...
Ubuntu-CVE http://people.ubuntu.com/~ubuntu-security/cve/CVE-2016-0705
Package libssl1.0.0-1.0.2f-2ubuntu1 -> libssl1.0.0-1.0.2g-1ubuntu4.5
openssl-1.0.2f-2ubuntu1 -> openssl-1.0.2g-1ubuntu4.5
... snip ...
Vulsにはスキャン結果の詳細を参照できるイカしたTUI(Terminal-Based User Interface)が付属している。
$ vuls tui
VulsRepoはスキャン結果をビボットテーブルのように分析可能にするWeb UIである。
Online Demoがあるので試してみて。
Vulsをスキャン対象サーバにデプロイする。Vulsはローカルホストにコマンドを発行する(SSH経由ではない)。スキャン結果のJSONを別サーバに集約する。スキャン結果の詳細化のためにはCVEデータベースへのアクセスが必要なので、事前にgo-cve-dictionaryをserver modeで起動しておく。 その集約サーバ上で、あなたはWebUIやTUIを用いて各スキャン対象サーバのスキャン結果を参照することが可能。
- NVDとJVN(日本語)から脆弱性データベースを取得し、SQLite3に格納する。
- SSHでサーバに存在する脆弱性をスキャンし、CVE IDのリストを作成する
- Dockerコンテナのスキャンする場合、VulsはまずDockerホストにSSHで接続する。その後、Dockerホスト上で
docker exec
経由でコマンドを実効する。Dockerコンテナ内にSSHデーモンを起動する必要はない
- Dockerコンテナのスキャンする場合、VulsはまずDockerホストにSSHで接続する。その後、Dockerホスト上で
- 検出されたCVEの詳細情報をgo-cve-dictionaryから取得する
- スキャン結果レポートを生成し、SlackやEmailなどで送信する
- スキャン結果をJSONファイルに出力すると詳細情報をターミナル上で参照可能
-
Ubuntu, Debian
apt-get changelog
でアップデート対象のパッケージのチェンジログを取得し、含まれるCVE IDをパースする。 アップデート対象のパッケージが沢山ある場合、チェンジログの取得に時間がかかるので、初回のスキャンは遅い。
ただ、2回目以降はキャッシュしたchangelogを使うので速くなる。 -
CentOS
アップデート対象すべてのchangelogを一度で取得しパースする。スキャンスピードは速い、サーバリソース消費量は小さい。 -
Amazon, RHEL and FreeBSD
高速にスキャンし、スキャン対象サーバのリソース消費量は小さい。
Distribution | Scan Speed |
---|---|
Ubuntu | 初回は遅い / 2回目以降速い |
Debian | 初回は遅い / 2回目以降速い |
CentOS | 速い |
Amazon | 速い |
RHEL | 速い |
FreeBSD | 速い |
web/app server in the same configuration under the load balancer
Distribution | Release |
---|---|
Ubuntu | 12, 14, 16 |
Debian | 7, 8 |
RHEL | 5, 6, 7 |
CentOS | 5, 6, 7 |
Amazon Linux | All |
FreeBSD | 10 |
Discoveryサブコマンドは指定されたCIDRレンジ内でpingが返ってくるサーバを発見して、ターミナル上にVulsの設定ファイルのテンプレートを出力する。
$ vuls discover -help
discover:
discover 192.168.0.0/24
$ vuls discover 172.31.4.0/24
# Create config.toml using below and then ./vuls --config=/path/to/config.toml
[slack]
hookURL = "https://hooks.slack.com/services/abc123/defghijklmnopqrstuvwxyz"
channel = "#channel-name"
#channel = "${servername}"
iconEmoji = ":ghost:"
authUser = "username"
notifyUsers = ["@username"]
[email]
smtpAddr = "smtp.gmail.com"
smtpPort = "587"
user = "username"
password = "password"
from = "[email protected]"
to = ["[email protected]"]
cc = ["[email protected]"]
subjectPrefix = "[vuls]"
[default]
#port = "22"
#user = "username"
#keyPath = "/home/username/.ssh/id_rsa"
#cpeNames = [
# "cpe:/a:rubyonrails:ruby_on_rails:4.2.1",
#]
#containers = ["${running}"]
#optional = [
# ["key", "value"],
#]
[servers]
[servers.172-31-4-82]
host = "172.31.4.82"
#port = "22"
#user = "root"
#keyPath = "/home/username/.ssh/id_rsa"
#cpeNames = [
# "cpe:/a:rubyonrails:ruby_on_rails:4.2.1",
#]
#containers = ["${running}"]
#optional = [
# ["key", "value"],
#]
このテンプレート使ってVulsの設定ファイルを作ってもよい。
-
Slack section
[slack] hookURL = "https://hooks.slack.com/services/abc123/defghijklmnopqrstuvwxyz" channel = "#channel-name" #channel = "${servername}" iconEmoji = ":ghost:" authUser = "username" notifyUsers = ["@username"]
-
hookURL : Incoming webhook's URL
-
channel : channel name.
channelに${servername}
を指定すると、結果レポートをサーバごとに別チャネルにすることが出来る。 以下のサンプルでは、#server1
チャネルと#server2
チャネルに送信される。スキャン前にチャネルを作成する必要がある。[slack] channel = "${servername}" ...snip... [servers] [servers.server1] host = "172.31.4.82" ...snip... [servers.server2] host = "172.31.4.83" ...snip...
-
iconEmoji: emoji
-
authUser: username of the slack team
-
notifyUsers: ここにユーザ名を指定すると、Slackで通知を受け取ることができる。たとえば
["@foo", "@bar"]
を指定すると、Slackのテキストに@foo
と@bar
が含まれるのでスマホなどにPush通知が可能。
-
-
Mail section
[email] smtpAddr = "smtp.gmail.com" smtpPort = "587" user = "username" password = "password" from = "[email protected]" to = ["[email protected]"] cc = ["[email protected]"] subjectPrefix = "[vuls]"
-
Default section
[default] #port = "22" #user = "username" #keyPath = "/home/username/.ssh/id_rsa" #cpeNames = [ # "cpe:/a:rubyonrails:ruby_on_rails:4.2.1", #] #containers = ["${running}"] #ignoreCves = ["CVE-2016-6313"] #optional = [ # ["key", "value"], #]
下記serversセクションで値が指定されなかった場合のデフォルト値
-
servers section
[servers] [servers.172-31-4-82] host = "172.31.4.82" #port = "22" #user = "root" #keyPath = "/home/username/.ssh/id_rsa" #cpeNames = [ # "cpe:/a:rubyonrails:ruby_on_rails:4.2.1", #] #ignoreCves = ["CVE-2016-6314"] #optional = [ # ["key", "value"], #] #containers = ["${running}"] #[servers.172-31-4-82.container] #type = "lxd"
serversセクションの値は、defaultセクションの値よりも優先される。 defaultセクションの値を使いたい場合は
#
でコメントアウトする。- host: IP address or hostname of target server
- port: SSH Port number
- user: SSH username
- keyPath: SSH private key path
- cpeNames: see Usage: Scan vulnerability of non-OS package
- ignoreCves: CVE IDs that will not be reported. But output to JSON file.
- optional: JSONレポートに含めたい追加情報
- containers: see Usage: Scan Docker containers
Vulsは各サーバにSSHで接続するが、Goのネイティブ実装と、OSコマンドの2種類のSSH接続方法をサポートしている。 詳細は -ssh-external option を参照。
また、以下のSSH認証をサポートしている。
- SSH agent
- SSH public key authentication (with password, empty password) SSH Password認証はサポートしていない
configtestサブコマンドは、config.tomlで定義されたサーバ/コンテナに対してSSH可能かどうかをチェックする。
$ vuls configtest --help
configtest:
configtest
[-config=/path/to/config.toml]
[-log-dir=/path/to/log]
[-ask-key-password]
[-ssh-external]
[-debug]
[SERVER]...
-ask-key-password
Ask ssh privatekey password before scanning
-config string
/path/to/toml (default "/Users/kotakanbe/go/src/github.com/future-architect/vuls/config.toml")
-debug
debug mode
-log-dir string
/path/to/log (default "/var/log/vuls")
-ssh-external
Use external ssh command. Default: Use the Go native implementation
また、スキャン対象サーバに対してパスワードなしでSUDO可能な状態かもチェックする。
スキャン対象サーバ上の/etc/sudoers
のサンプル
- CentOS, RHEL, Amazon Linux (CentOS 5の場合は
/bin/echo
も必要)
vuls ALL=(root) NOPASSWD: /usr/bin/yum (, /bin/echo)
- Ubuntu, Debian
vuls ALL=(root) NOPASSWD: /usr/bin/apt-get, /usr/bin/apt-cache
- Amazon Linux, FreeBSDはRoot権限なしでスキャン可能
Prepareサブコマンドは、Vuls内部で利用する以下のパッケージをスキャン対象サーバにインストールする。
Distribution | Release | Requirements |
---|---|---|
Ubuntu | 12, 14, 16 | - |
Debian | 7, 8 | aptitude |
CentOS | 5 | yum-changelog |
CentOS | 6, 7 | yum-plugin-changelog |
Amazon | All | - |
RHEL | 5, 6, 7 | - |
FreeBSD | 10 | - |
$ vuls prepare -help
prepare:
prepare
[-config=/path/to/config.toml]
[-log-dir=/path/to/log]
[-ask-key-password]
[-debug]
[-ssh-external]
[SERVER]...
-ask-key-password
Ask ssh privatekey password before scanning
-config string
/path/to/toml (default "$PWD/config.toml")
-debug
debug mode
-log-dir string
/path/to/log (default "/var/log/vuls")
-ssh-external
Use external ssh command. Default: Use the Go native implementation
$ vuls scan -help
scan:
scan
[-config=/path/to/config.toml]
[-results-dir=/path/to/results]
[-log-dir=/path/to/log]
[-cachedb-path=/path/to/cache.db]
[-ssh-external]
[-containers-only]
[-skip-broken]
[-http-proxy=http://192.168.0.1:8080]
[-ask-key-password]
[-debug]
[-pipe]
[SERVER]...
-ask-key-password
Ask ssh privatekey password before scanning
-cachedb-path string
/path/to/cache.db (local cache of changelog for Ubuntu/Debian)
-config string
/path/to/toml
-containers-only
Scan containers only. Default: Scan both of hosts and containers
-debug
debug mode
-http-proxy string
http://proxy-url:port (default: empty)
-log-dir string
/path/to/log (default "/var/log/vuls")
-pipe
Use stdin via PIPE
-results-dir string
/path/to/results
-skip-broken
[For CentOS] yum update changelog with --skip-broken option
-ssh-external
Use external ssh command. Default: Use the Go native implementation
Vulsは2種類のSSH接続方法をサポートしている。
デフォルトでは、Goのネイティブ実装 (crypto/ssh) を使ってスキャンする。 これは、SSHコマンドがインストールされていない環境でも動作する(Windowsなど)
外部SSHコマンドを使ってスキャンするためには、-ssh-external
を指定する。
SSH Configが使えるので、ProxyCommandを使った多段SSHなどが可能。
CentOSでは、スキャン対象サーバの/etc/sudoersに以下を追加する必要がある(user: vuls)
Defaults:vuls !requiretty
SSH key password | -ask-key-password | |
---|---|---|
empty password | - | |
with password | required | or use ssh-agent |
$ vuls scan -ask-key-password
この例では、
- SSH公開鍵認証(秘密鍵パスフレーズ)を指定
- configに定義された全サーバをスキャン
$ vuls scan server1 server2
この例では、
- SSH公開鍵認証(秘密鍵パスフレーズなし)
- ノーパスワードでsudoが実行可能
- configで定義されているサーバの中の、server1, server2のみスキャン
ローカルホストのスキャンする場合、SSHではなく直接コマンドの発行が可能。
config.tomlのhostにlocalhost または 127.0.0.1
かつ、portにlocal
を設定する必要がある。
For more details, see Architecture section
- config.toml
[servers] [servers.localhost] host = "localhost" # or "127.0.0.1" port = "local"
コンテナはSSHデーモンを起動しないで運用するケースが一般的。
Docker Blog:Why you don't need to run SSHd in your Docker containers
Vulsは、DockerホストにSSHで接続し、docker exec
でDockerコンテナにコマンドを発行して脆弱性をスキャンする。
詳細は、Architecture sectionを参照
-
全ての起動中のDockerコンテナをスキャン
"${running}"
をcontainersに指定する[servers] [servers.172-31-4-82] host = "172.31.4.82" user = "ec2-user" keyPath = "/home/username/.ssh/id_rsa" containers = ["${running}"]
-
あるコンテナのみスキャン
コンテナID、または、コンテナ名を、containersに指定する。
以下の例では、container_name_a
と、4aa37a8b63b9
のコンテナのみスキャンする
スキャン実行前に、コンテナが起動中か確認すること。もし起動してない場合はエラーメッセージを出力してスキャンを中断する。[servers] [servers.172-31-4-82] host = "172.31.4.82" user = "ec2-user" keyPath = "/home/username/.ssh/id_rsa" containers = ["container_name_a", "4aa37a8b63b9"]
-
コンテナのみをスキャンする場合(ホストはスキャンしない)
--containers-onlyオプションを指定する
Vulsは、ホストにSSHで接続し、lxc exec
でLXDコンテナにコマンドを発行して脆弱性をスキャンする。
[servers]
[servers.172-31-4-82]
host = "172.31.4.82"
user = "ec2-user"
keyPath = "/home/username/.ssh/id_rsa"
containers = ["${running}"]
[servers.172-31-4-82.container]
type = "lxd"
report:
report
[-lang=en|ja]
[-config=/path/to/config.toml]
[-results-dir=/path/to/results]
[-log-dir=/path/to/log]
[-refresh-cve]
[-cvedb-type=sqlite3|mysql]
[-cvedb-path=/path/to/cve.sqlite3]
[-cvedb-url=http://127.0.0.1:1323 or mysql connection string]
[-cvss-over=7]
[-ignore-unscored-cves]
[-to-email]
[-to-slack]
[-to-localfile]
[-to-s3]
[-to-azure-blob]
[-format-json]
[-format-xml]
[-format-one-line-text]
[-format-short-text]
[-format-full-text]
[-gzip]
[-aws-profile=default]
[-aws-region=us-west-2]
[-aws-s3-bucket=bucket_name]
[-azure-account=accout]
[-azure-key=key]
[-azure-container=container]
[-http-proxy=http://192.168.0.1:8080]
[-debug]
[-debug-sql]
[-pipe]
[SERVER]...
-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
-azure-account string
Azure account name to use. AZURE_STORAGE_ACCOUNT environment variable is used if not specified
-azure-container string
Azure storage container name
-azure-key string
Azure account key to use. AZURE_STORAGE_ACCESS_KEY environment variable is used if not specified
-config string
/path/to/toml
-cvedb-path string
/path/to/sqlite3 (For get cve detail from cve.sqlite3)
-cvedb-type string
DB type for fetching CVE dictionary (sqlite3 or mysql) (default "sqlite3")
-cvedb-url string
http://cve-dictionary.com:8080 or mysql connection string
-cvss-over float
-cvss-over=6.5 means reporting CVSS Score 6.5 and over (default: 0 (means report all))
-debug
debug mode
-debug-sql
SQL debug mode
-format-full-text
Detail report in plain text
-format-json
JSON format
-format-one-line-text
One line summary in plain text
-format-short-text
Summary in plain text
-format-xml
XML format
-gzip
gzip compression
-http-proxy string
http://proxy-url:port (default: empty)
-ignore-unscored-cves
Don't report the unscored CVEs
-lang string
[en|ja] (default "en")
-log-dir string
/path/to/log (default "/var/log/vuls")
-pipe
Use stdin via PIPE
-refresh-cve
Refresh CVE information in JSON file under results dir
-results-dir string
/path/to/results
-to-azure-blob
Write report to Azure Storage blob (container/yyyyMMdd_HHmm/servername.json/xml/txt)
-to-email
Send report via Email
-to-localfile
Write report to localfile
-to-s3
Write report to S3 (bucket/yyyyMMdd_HHmm/servername.json/xml/txt)
-to-slack
Send report via Slack
$ vuls report \
-to-slack \
-cvss-over=7 \
-cvedb-path=$PWD/cve.sqlite3
With this sample command, it will ..
- Slack通知
- CVSS score が 7.0以上のもののみ通知
事前にAWS関連の設定を行う
- S3バケットを作成 Creating a Bucket
- アクセスキーを作成し、S3バケットへのREAD/WRITE権限をつけておく Managing Access Keys for IAM Users
- security credentialsを設定 Configuring the AWS Command Line Interface
$ vuls scan \
-cvedb-path=$PWD/cve.sqlite3 \
-to-s3 \
-format-json \
-aws-region=ap-northeast-1 \
-aws-s3-bucket=vuls \
-aws-profile=default
この例では、
- 結果をJSON形式でS3に格納する。
- バケット名 ... vuls
- リージョン ... ap-northeast-1
- 利用するProfile ... default
事前にAzure Blob関連の設定を行う
- Azure Blob Containerを作成
$ vuls scan \
-cvedb-path=$PWD/cve.sqlite3 \
-to-azure-blob \
-format-xml \
-azure-container=vuls \
-azure-account=test \
-azure-key=access-key-string
この例では、
- 結果をXML形式でBlobに格納する。
- コンテナ名 ... vuls
- ストレージアカウント名 ... test
- アクセスキー ... access-key-string
また、アカウント名とアクセスキーは環境変数でも定義が可能
$ export AZURE_STORAGE_ACCOUNT=test
$ export AZURE_STORAGE_ACCESS_KEY=access-key-string
$ vuls scan \
-cve-dictionary-dbpath=$PWD/cve.sqlite3 \
-report-azure-blob \
-azure-container=vuls
Slack, EMail, テキスト出力しないくないCVE IDがある場合は、設定ファイルに定義することでレポートされなくなる。 ただ、JSONファイルには以下のように出力される。
- config.toml
[default]
ignoreCves = ["CVE-2016-6313"]
[servers.bsd]
host = "192.168.11.11"
user = "kanbe"
ignoreCves = ["CVE-2016-6314"]
- bsd.json
[
{
"ServerName": "bsd",
"Family": "FreeBSD",
"Release": "10.3-RELEASE",
"IgnoredCves" : [
"CveDetail" : {
"CVE-2016-6313",
...
},
"CveDetail" : {
"CVE-2016-6314",
...
}
]
}
]
追加情報をJSONに含めることができる。
デフォルトセクションのkey-valueはserversセクションのもので上書きされる。
使い方の例として、AzureリソースグループやVM名を指定しておくことで、結果のJSONをスクリプトでパースしてAzure VMの操作をする、などが可能。
- config.toml
[default]
optional = [
["key1", "default_value"],
["key3", "val3"],
]
[servers.bsd]
host = "192.168.11.11"
user = "kanbe"
optional = [
["key1", "val1"],
["key2", "val2"],
]
- bsd.json
[
{
"ServerName": "bsd",
"Family": "FreeBSD",
"Release": "10.3-RELEASE",
.... snip ...
"Optional": [
[ "key1", "val1" ],
[ "key2", "val2" ],
[ "key3", "val3" ]
]
}
]
$ vuls scan \
-cve-dictionary-dbtype=mysql \
-cve-dictionary-dbpath="user:pass@tcp(localhost:3306)/dbname?parseTime=true"
Vulsは、CPEに登録されているソフトウェアであれば、OSパッケージ以外のソフトウェアの脆弱性もスキャン可能。
たとえば、自分でコンパイルしたものや、言語のライブラリ、フレームワークなど。
-
CPEの検索方法
-
NVD: Search Common Platform Enumerations (CPE)
Check CPE Naming Format: 2.2 -
go-cpe-dictionary is a good choice for geeks.
ターミナル上でCPEをインクリメンタル検索出来るツール
-
-
Configuration
例えば、Ruby on Rails v4.2.1の脆弱性を検知したい場合は、serversセクションに以下のように定義する。[servers] [servers.172-31-4-82] host = "172.31.4.82" user = "ec2-user" keyPath = "/home/username/.ssh/id_rsa" cpeNames = [ "cpe:/a:rubyonrails:ruby_on_rails:4.2.1", ]
Usage: Integrate with OWASP Dependency Check to Automatic update when the libraries are updated (Experimental)
OWASP Dependency check は、プログラミング言語のライブラリを特定し(CPEを推測)、公開済みの脆弱性を検知するツール。
VulsとDependency Checkを連携させる方法は以下
-
Dependency Checkを、--format=XMLをつけて実行する
-
そのXMLをconfig.toml内で以下のように定義する
[servers] [servers.172-31-4-82] host = "172.31.4.82" user = "ec2-user" keyPath = "/home/username/.ssh/id_rsa" dependencyCheckXMLPath = "/tmp/dependency-check-report.xml"
VulsとDependency Checkの連携すると以下の利点がある
- ライブラリを更新した場合に、config.tomlのCPEの定義を変更しなくても良い
- Vulsの機能でSlack, Emailで通知可能
- 日本語のレポートが可能
- Dependency Checkは日本語レポートに対応していない
$ vuls tui -h
tui:
tui
[-cvedb-type=sqlite3|mysql]
[-cvedb-path=/path/to/cve.sqlite3]
[-cvedb-url=http://127.0.0.1:1323 or mysql connection string]
[-results-dir=/path/to/results]
[-refresh-cve]
[-debug-sql]
[-pipe]
-cvedb-path string
/path/to/sqlite3 (For get cve detail from cve.sqlite3)
-cvedb-type string
DB type for fetching CVE dictionary (sqlite3 or mysql)
-cvedb-url string
http://cve-dictionary.com:8080 or mysql connection string
-debug-sql
debug SQL
-pipe
Use stdin via PIPE
-refresh-cve
Refresh CVE information in JSON file under results dir
-results-dir string
/path/to/results
Key binding is below.
| key | | |:-----------------|:-------|:------| | TAB | move cursor among the panes | | Arrow up/down | move cursor to up/down | | Ctrl+j, Ctrl+k | move cursor to up/down | | Ctrl+u, Ctrl+d | page up/down |
For details, see https://github.com/future-architect/vuls/blob/master/report/tui.go
- Display the list of scan results.
$ vuls history
20160524_1950 scanned 1 servers: amazon2
20160524_1940 scanned 2 servers: amazon1, romantic_goldberg
- Display the result of scan 20160524_1949
$ vuls tui 20160524_1950
- Display the result of scan 20160524_1948
$ vuls tui 20160524_1940
$ vuls history | peco | vuls tui -pipe
Run go-cve-dictionary as server mode before scanning on 192.168.10.1
$ go-cve-dictionary server -bind=192.168.10.1 -port=1323
Run Vuls with -cve-dictionary-url option.
$ vuls scan -cve-dictionary-url=http://192.168.0.1:1323
see go-cve-dictionary#usage-fetch-nvd-data
see go-cve-dictionary#usage-fetch-jvn-data
fetchjvn -> fetchnvdの順番だとすごく時間がかかる (2016年9月現在)
fetchnvd -> fetchjvnの順番で実行すること
$ for i in {2002..2016}; do go-cve-dictionary fetchnvd -years $i; done
$ for i in {1998..2016}; do go-cve-dictionary fetchjvn -years $i; done
の順でやった場合、最初のコマンドが15分程度、二つ目のコマンドが10分程度(環境依存)
$ for i in {1998..2016}; do go-cve-dictionary fetchjvn -years $i; done
$ for i in {2002..2016}; do go-cve-dictionary fetchnvd -years $i; done
の順で行うと、最初のコマンドは1時間くらいで終わるが二つ目のコマンドが21時間かかることもある(環境依存)。
$ vuls scan -lang=ja
Scan時にlang=jaを指定すると脆弱性レポートが日本語になる
slack, emailは日本語対応済み TUIは日本語表示未対応
- Update go-cve-dictionary
If the DB schema was changed, please specify new SQLite3 or MySQL DB file.
$ cd $GOPATH/src/github.com/kotakanbe/go-cve-dictionary
$ git pull
$ mv vendor /tmp/foo
$ make install
- Update vuls
$ cd $GOPATH/src/github.com/future-architect/vuls
$ git pull
$ mv vendor /tmp/bar
$ make install
- バイナリファイルは
$GOPARH/bin
以下に作成される
-
go get時にエラーが出る
Gitをv2にアップデートしてお試しを
see https://groups.google.com/forum/#!topic/mgo-users/rO1-gUDFo_g -
HTTP Proxy サポート プロキシ環境下では、-http-proxyオプションを指定
-
go-cve-dictionaryのデーモン化
Use Systemd, Upstart or supervisord, daemontools... -
NVD, JVNの脆弱性データベースの自動更新
CRONなどを使えば可能 -
自動定期スキャン
CRONなどを使い、自動化のためにsudoと、秘密鍵のパスワードなしでも実行可能なようにする- スキャン対象サーバの /etc/sudoers に NOPASSWORD を設定する
- 秘密鍵パスフレーズなしの公開鍵認証か、ssh-agentを使う
-
スキャンが重く感じる
vulsのスキャン対象に脆弱性が溜まりすぎると実行時間が長くなります 脆弱性のある状態は溜めすぎないようにしましょう -
クロスコンパイル
$ cd /path/to/your/local-git-reporsitory/vuls $ GOOS=linux GOARCH=amd64 go build -o vuls.amd64
-
Logging
Log is under /var/log/vuls/ -
Debug
Run with --debug, --sql-debug option. -
Adjusting Open File Limit
Riak docs is awesome. -
Does Vuls accept ssh connections with fish-shell or old zsh as the login shell?
No, Vuls needs a user on the server for bash login. see also #8 -
Windows
Use Microsoft Baseline Security Analyzer. MBSA
-
k1LoW/ssh_config_to_vuls_config
ssh_config to vuls config TOML format -
usiusi360/vulsrepo
VulsRepo is visualized based on the json report output in vuls.
Youtube
kotakanbe (@kotakanbe) created vuls and these fine people have contributed.
- fork a repository: github.com/future-architect/vuls to github.com/you/repo
- get original code: go get github.com/future-architect/vuls
- work on original code
- add remote to your repo: git remote add myfork https://github.com/you/repo.git
- push your changes: git push myfork
- create a new Pull Request
Please see CHANGELOG.
Please see LICENSE.