GNU GPLv3の脆弱性スキャナ：Vulsを使ってみた

# GNU GPLv3の脆弱性スキャナ：Vulsを使ってみた  

## はじめに  
"Vuls"という、GNU GPLv3の脆弱性スキャナが使いやすそうだったので試してみました。
Vulsの詳細はこちら
https://github.com/future-architect/vuls/blob/master/README.ja.md

## 検証環境
CentOS 6.7 64bit minimul
※Vulsをインストール後、自分自身を脆弱性スキャンをしようと思ったので、意図的に少し古いバージョンを使用してみます。
## Vulsのインストール 
### EPELの有効化  

```
# yum install epel-release
```
### 動作要件になっているソフトのインストール  
以下のソフトが動作要件となっています。  

  - SQLite3  
  - git v2  
  - gcc  
  - go v1.6  

#### SQLiteのインストール  

```
# yum install sqlite
```

#### gccのインストール  

```
# yum install gcc
```

#### gitのインストール  
CentOSの標準リポジトリだとv1.7のため動作要件から外れる。
一旦、標準リポジトリからgitをインスールし、その後本家のソースに入れ替える。

1. 標準リポジトリからgitをインストール

    ```
    # yum install git
    ```

2. この後のgitのコンパイルに必要なものをインストール  
    参考：[Git ソースからのインストール](https://git-scm.com/book/ja/v2/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-Git%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)  

    ```
    # yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker
    ```

3. 本家gitのソース取得  

    ```
    # git clone https://git.kernel.org/pub/scm/git/git.git
    ```

4. RPMのGITをアンインストール  

    ```
    # yum remove git
    ```

5. コンパイル、インストール

    ```
    # cd git
    # make prefix=/usr/local all
    # make prefix=/usr/local install
    # git --version
    ```

#### goのインストール
EPELリポジトリだとｖ1.5のため動作要件から外れる。
本家のバイナリを展開してインストールする。  

1. goのダウンロード
    https://golang.org/doc/install → Download Go → v1.6.3 Linux 64bitのリンク先を確認。  
    ダウンロードする。

    ```
    # curl -O  https://storage.googleapis.com/golang/go1.6.3.linux-amd64.tar.gz
    ```

2. ファイルの展開

    ```
    # tar -C /usr/local -xzf go1.6.3.linux-amd64.tar.gz
    ```

3. 実行の為の環境変数設定  

    ```
    # 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
    # go version
    ```

### VulsRepo(WebUI)のインストール
WebUIとしてVulsRepoがあるので、こちらをインストールします。

1. apacheのインストール  

    ```
# yum install httpd perl-CGI perl-JSON
# vi /etc/httpd/conf/httpd.conf
ServerName localhost.localdomain
    ```

2. VulsRepo(WebUI)のインストール  

    ```
# cd /var/www/html/
# git clone https://github.com/usiusi360/vulsrepo.git
# cp -p vulsrepo/dist/cgi/vulsrepo.conf.sample /etc/httpd/conf.d/vulsrepo.conf
# lokkit -p 80:tcp
    ```

### vuls実行ユーザの作成 

1. vuls実行ユーザの作成  

    ```
    # useradd vulstest
    # passwd vulstest
    ```

2. SSHの暗号鍵の設定
    vulsは、検査対象のサーバにSSHで鍵認証方式で接続できる必要がありますので、鍵の設定を行います。

    ```    
    # su - vulstest
    $ ssh-keygen -t rsa
    $ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
    $ chmod 600 ~/.ssh/authorized_keys
    $ exit
    ```

    今回は自分自身にSSHで接続するので、ローカルで鍵の設定をしています。  
    リモートの場合には、ssh-copy-id等を使って適宜設定をしてください。  

3. sudoの設定
    vulsでSSH接続に使用するユーザは、sudoがパスワードなしで実行できる必要があるので、
    リモートにsudoの設定をします。

    ```
    # visudo
    vulstest        ALL=(ALL)       NOPASSWD: ALL
    ```

### vulsのインストール  
vuls実行ユーザで実行します。  

1. vuls用のディレクトリ作成

    ```
    $ sudo mkdir /var/log/vuls
    $ sudo chown vulstest /var/log/vuls
    $ sudo chmod 700 /var/log/vuls
    $ sudo mkdir /var/www/html/vulsrepo/results
    $ sudo chown vulstest:vulstest /var/www/html/vulsrepo/results
    $ ln -s /var/www/html/vulsrepo/results /home/vulsrepo/
    ```

2. go-cve-dictionaryのインストール、脆弱性DBの更新

    ```
    $ go get github.com/kotakanbe/go-cve-dictionary
    $ for i in {2002..2016}; do go-cve-dictionary fetchnvd -years $i; done
    $ for i in {2002..2016}; do go-cve-dictionary fetchjvn -years $i; done
    ```

3. vulsのインストール

    ```
    $ go get github.com/future-architect/vuls
    ```

4. 設定ファイルの作成

    ```
    $ vi config.toml
    [servers]
          
    [servers.172-23-141-65]
    host         = "172.23.141.65"
    port        = "22"
    user        = "vulstest"
    keyPath     = "/home/vulstest/.ssh/id_rsa"
    cpeNames = [
      "cpe:/a:php:php:5.6.22",
      "cpe:/a:apache:http_server:2.2.20",
      "cpe:/o:cisco:ios:15.3",
    ]
    ```

    [servers.172-23-141-65]となっているところは、[servers.ホスト名]みたいにすれば、レポートにはホスト名で表示されます。
    yumのchangelogで管理できるもの以外、たとえば、自分でコンパイルしたものや、言語のライブラリ、フレームワーク、さらに検査対象の機器以外（ネットワーク機器等）でも、CPE登録されているものであればチェック可能。上記では、ソースからphp5.6.22 apche2.2.20をインストールしていると仮定して設定している。ついでにcisco:ios:15.3をルータとして使っているとして追記。  

    CPEの検索方法
    https://web.nvd.nist.gov/view/cpe/search
    Check CPE Naming Format: 2.2

5. 設定ファイルでのSSHの接続テスト

    ```
    $ vuls configtest
    ```

6. 接続先の環境設定
    ※以下のコマンドを実行すると、SSHの接続先でyum-changelog、yum-plugin-changelog等がないと、その場でインストールが始まる。  

    ```
    $ vuls prepare
    ```

### 脆弱性のスキャン、結果確認  

#### 脆弱性スキャン  
CUIのレポート機能(tui)は日本語表示未対応、WebUI(VulsRepo)は日本語対応。  

- 英語でレポート出力

    ```
    $ vuls scan -cve-dictionary-dbpath=$PWD/cve.sqlite3 -results-dir=/home/vulstest/results -report-json -report-text
    ```  

- 日本語レポート出力  

    ```
    $ vuls scan -cve-dictionary-dbpath=$PWD/cve.sqlite3 -results-dir=/home/vulstest/results -report-json -report-text -lang=ja
    ```

#### CUIでの結果確認
 
 ```
 $ vuls tui
 ```

直近の一つのレポートしか表示できないのかな？CTRL+Cで抜ける。
![VulsTUI001.png](https://qiita-image-store.s3.amazonaws.com/0/129763/43afc624-0f9e-ab70-95db-52ba2d69a0f6.png)
 
#### GUIでの結果確認

1. Apacheの起動  
まだ、Apacheを起動していないので起動
   
    ```
    # sudo /etc/init.d/httpd start
    ```

2. ブラウザでアクセス
    ブラウザでhttp://IPアドレス/vulsrepo/にアクセス  

- スキャンしたレポートが選択できる。複数選択もできるので、過去の物や、複数のサーバをまとめて表示もできる。  

![VulsRepo001.png](https://qiita-image-store.s3.amazonaws.com/0/129763/65cc9d49-b545-5a5f-ac42-97193785f2e7.png)

- 一番左の列の項目をドラック＆ドロップすることで、縦軸、横軸に自由に選択できる。各項目にはフィルタリング機能もあるので、特定のものだけ表示することも可能。以下は縦軸、横軸をいじったり、フィルタリングしたもの。CiscoIOSの情報も表示できている。

![VulsRepo002.png](https://qiita-image-store.s3.amazonaws.com/0/129763/0db17103-edf4-8c03-9e46-d599252391e4.png)
![VulsRepo003.png](https://qiita-image-store.s3.amazonaws.com/0/129763/cc972a8a-1af3-59a4-7a94-2b94892d3ef4.png)
![VulsRepo004.png](https://qiita-image-store.s3.amazonaws.com/0/129763/8992cd47-2274-b739-126e-7131ba4130de.png)
![VulsRepo005.png](https://qiita-image-store.s3.amazonaws.com/0/129763/21746ac4-3844-6f25-9f9d-a4605062f4ec.png)

## 運用について
定期的に脆弱性スキャンをかけるとか、スキャン結果をどのように通知するとか、運用面についても考える必要がある。

定期的にスキャンしたとして、運用側としては差分だけ通知があればよいとかあると思うので、その辺は自前で作りこむ必要がある。

changelogを使っているということは、yumで管理しているパッケージはchangelogに書かれているCVE番号を見ているのかな？⇒修正が終わったパッチが提供された物のみ表示されるのかな？⇒もしそうなら、まだ修正が終わっていないとか、影響が小さいので修正しないとか、そういったものは表示されないのかな？

検査対象のサーバが直接インターネットにyumでアクセスできる必要があるので、クローズドの環境では使えないのかな。

## この記事の情報に関して  
この記事が提供している情報に関しては、合法性、正確性、安全性等、いかなる保証もされません。この記事を利用することによって生ずるいかなる損害に対しても一切責任を負いません。