GO
BACK
MORE
PDF

BLOGブログ

カテゴリー

キーワード

【Tech Blog】Vulsを用いた脆弱性検出・管理フローの構築①

文責:山本 和幸

  • 脆弱性検出

弊社では、クラウド・オンプレ問わず様々な環境でサービスを開発・運用しています。

プロダクトリリース前に第三者機関による脆弱性診断を実施していますが、万が一、リリース直前に重大な脆弱性が発見された場合、その対応によるスケジュールの逼迫というリスクが挙げられます。また、プロジェクトによって AWS では Security Inspector を用いたり、AWS Security Center の CVE 情報を Feed 経由で取得し特定タイミングで反映するなど、運用の統一ができていないという課題もありました。

これらの課題解決の為、脆弱性情報を検出するOSSである" Vuls "の構築を行いました。
導入・運用の方法、そして注意点などを2回に分けてお伝えさせていただこうと思います。

■Vulsとは

Vuls を簡単にまとめると、OS やミドルウェア等、またアプリケーションフレームワークに至るまでの脆弱性情報を DB として保持し、簡単な設定でスキャンからレポートまでを行うことができる国産 OSS で、特徴は下記のようなものが挙げられます。

エージェントが不要
通知チャネルが豊富なため、様々なものと連携がとりやすい
運用コストが低いので開発者の負担をかけずにすむ
CI等にも組み込みやすいので開発フローにも組み込みやすく運用時においても意識することなく保守しやすくなる
 

■インストール

今回は Amazon Linux 2 上に Docker を利用して環境を構築し、最低限の稼働を行える状態にもっていくまでをまとめます。また、この記事においては下記を前提としています。

初期設定などに関しては省略し、構築に必要なものにフォーカスして記載します
運用用のユーザーを作成するべきですが、検証用 + (ec2-user ALL=(ALL) NOPASSWD:ALL) と sudo 権限を持つためこのままデフォルトの ec2-uesr を利用します
NW や Firewall においては特に記載していませんが、一定の設定は行っている(適切に最低限の通信許可のみ行っている)状態とします
 

■Docker インストール

[ec2-user@~]$ sudo amazon-linux-extras install docker=latest
[ec2-user@~]$ sudo curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
[ec2-user@~]$ sudo chmod +x /usr/local/bin/docker-compose 

■Vuls インストール

[ec2-user@~]$ mkdir /opt/vuls && cd /opt/vuls
[ec2-user@vuls]$ vim docker-compse.yml

下記がdocker-compose.ymlの中身となります。

version: '3'
services:
  nginx:
    build: nginx
    ports:
      - "80:80"
    depends_on:
      - vulsrepo
  # vuls本体
  # Volumesのところでホストの/home/ec2-userのKeyをContainer上のキーとして扱うようにしている
  vuls:
    image: vuls/vuls
    volumes:
      - /home/ec2-user/.ssh:/root/.ssh:ro
      - ./:/vuls
      - ./vuls-log:/var/log/vuls
  # 公開されている cve を DB にて管理する
  # https://github.com/kotakanbe/go-cve-dictionary
  cve:
    image: vuls/go-cve-dictionary
    volumes:
      - ./:/vuls
      - ./vuls-log:/var/log/vuls
  # OS 固有の OVAL 情報を保持する
  # https://github.com/kotakanbe/goval-dictionary
  oval:
    image: vuls/goval-dictionary
    volumes:
      - ./:/vuls
      - ./vuls-log:/var/log/vuls
  # 未修正の脆弱性の検知
  # https://github.com/knqyf263/gost
  gost:
    image: vuls/gost
    volumes:
      - ./:/vuls
      - ./vuls-log:/var/log/vuls
  # 脆弱性に対する攻撃コードを管理する
  # https://github.com/vulsio/go-exploitdb
  go-exploitdb:
    image: vuls/go-exploitdb
    volumes:
      - ./:/vuls
      - ./vuls-log:/var/log/vuls
  # Metasploit 情報を DB 管理する
  # https://github.com/takuzoo3868/go-msfdb
  go-msfdb:
    image: vuls/go-msfdb
    volumes:
      - ./:/vuls
      - ./vuls-log:/var/log/vuls
  # WebGUI。Port は 5111 で上がるので Tonnel するときは任意の Port にする。(自分は手間なのでそのまま 5111 を nginx で Proxy している)
  # https://vuls.io/docs/ja/vulsrepo.html
  vulsrepo:
    image: vuls/vulsrepo
    volumes:
      - ./results:/vuls/results/
      - ./:/vuls
      - ./vuls-log:/var/log/vuls
    ports:
      - "5111:5111"
  # composer.lock などアプリケーションライブラリの脆弱性を検知する
  # https://vuls.io/docs/ja/usage-scan-non-os-packages.html
  trivy:
    image: aquasec/trivy
    volumes:
      - ./results:/vuls/results/
      - ./:/vuls
      - ./vuls-log:/var/log/vuls

完了後、nginx の設定ファイルを作成します。

[ec2-user@vuls]$ mkdir nginx && cd nginx
[ec2-user@nginx]$ vim Dockerfile

Dockerfile の中身は以下になります。

FROM nginx
COPY ./default.conf /etc/nginx/conf.d/default.conf 
[ec2-user@nginx]$ vim default.conf 
server{
listen 80;
server_name localhost;

location / {
proxy_pass http://vulsrepo:5111;
}
}

ここまで設定が完了すれば一旦コンテナを起動します。

[ec2-user@nginx]$ cd ../
[ec2-user@vuls]$ sudo docker-compose up -d
[ec2-user@vuls]# docker-compose ps
   Name          Command         State       Ports
--------------------------------------------------------------------------------------
vuls_cve_1     go-cve-dictionary --help      Exit 0
vuls_go-exploitdb_1 go-exploitdb --help         Exit 0
vuls_go-msfdb_1   go-msfdb --help           Exit 0
vuls_gost_1     gost --help             Exit 0
vuls_nginx_1     /docker-entrypoint.sh ngin ...   Up  0.0.0.0:80->80/tcp
vuls_oval_1     goval-dictionary --help       Exit 0
vuls_trivy_1     trivy                Exit 0
vuls_vuls_1     vuls --help             Exit 0
vuls_vulsrepo_1   vulsrepo-server           Up  0.0.0.0:5111->5111/tcp

■脆弱性情報の取得

Vuls では脆弱性の情報をローカルのDBに保持します。以下はその手順となります。
データの取得に関しては初回は割と時間がかかります。

# cvn
[ec2-user@vuls]$ for i in `seq 2002 $(date +"%Y")`; do /usr/local/bin/docker-compose -f /opt/vuls/docker-compose.yml run --rm cve fetchnvd -years $i; done
# jvn
[ec2-user@vuls]$ for i in `seq 1998 $(date +"%Y")`; do /usr/local/bin/docker-compose -f /opt/vuls/docker-compose.yml run --rm cve fetchjvn -years $i; done
# oval
※弊社では基本的にAmazon Linuxでの運用となるのでこの例ではそうしていますが、それぞれのPlatformに合わせた形で取得
[ec2-user@vuls]$ /usr/local/bin/docker-compose -f /opt/vuls/docker-compose.yml run --rm oval fetch-amazon
# gost
[ec2-user@vuls]$ /usr/local/bin/docker-compose -f /opt/vuls/docker-compose.yml run --rm gost fetch redhat
# expliotdb
[ec2-user@vuls]$ /usr/local/bin/docker-compose -f /opt/vuls/docker-compose.yml run --rm go-exploitdb fetch exploitdb
# msfdb
[ec2-user@vuls]$ /usr/local/bin/docker-compose -f /opt/vuls/docker-compose.yml run --rm go-msfdb fetch msfdb

■設定

Vuls は設定ファイルの情報( config.toml )をもとに対象サーバーのチェックを行います。
弊社では、現状複数プロジェクトで運用するにあたり、設定ファイルをそれぞれ分割して保持するような運用を行っています。プロジェクト用ディレクトリでは config.toml やその他プロジェクト固有のデータを置くイメージです。

/opt/vuls
├── cve.sqlite3
├── db (directory)
├── docker-compose.yml
├── go-exploitdb.sqlite3
├── go-msfdb.sqlite3
├── gost.sqlite3
├── nginx
│ ├── Dockerfile
│ └── default.conf
├── oval.sqlite3
├── project
│ ├── project_a
│ │ ├── config.toml
│ │ ├── dependency.xml
│ │ └── src
│ │ └── project_a_api (directory)
│ └── project_b (directory. project_aと同等の構成となる。)
├── results (directory)
├── vuln-list (directory)
└── vuls-log (directory)
[ec2-user@vuls]$ mkdir -p project/example_project
[ec2-user@vuls]$ vim project/example_project/config.toml

以下設定ファイルの中身です。今回は最低限の稼働ということで、とりあえずサーバー1台の設定となります。チェックするサーバーが増える場合などは、[servers.XXX]を増やすことでチェック台数を増やすことができます。

[servers]
 
[servers.example-project-prod-api]
host = "XXX.XXX.XXX.XXX"
user = "ec2-user"
# サーバーにログインするための鍵。docker-compose.ymlで設定しましたが、/home/ec2-user/.ssh/の中にファイルが存在する前提です。
keyPath = "/root/.ssh/project_example.pem"
# アプリケーションで利用しているライブラリの脆弱性をチェックします。パッケージ管理を利用しているのであれば、その管理ファイルを設定します。
findLock = true
lockfiles = [
 "/path/to/src/package.json"
]
scanMode = ["fast-root"]

■実行

設定がようやく完了しましたので、実行していきます。まずは設定ファイルに不備がないか、サーバーに接続できる状態であるかなどを確認するために `vuls configtest` を実行します。ここでは docker 上で実行するためにコマンドが長くなっていますが、基本 `vuls hoge` で一通りのことを実施します。

[ec2-user@vuls]$ /usr/local/bin/docker-compose -f /opt/vuls/docker-compose.yml run --rm vuls configtest -config=./project/example_project/config.toml
Creating vuls_vuls_run ... done
[Dec 8 19:31:42] INFO [localhost] Validating config...
[Dec 8 19:31:42] INFO [localhost] Detecting Server/Container OS...
[Dec 8 19:31:42] INFO [localhost] Detecting OS of servers...
[Dec 8 19:31:42] INFO [localhost] (1/1) Detected: example-project-prod-api: amazon 2 (Karoo)
[Dec 8 19:31:42] INFO [localhost] Detecting OS of containers...
[Dec 8 19:31:42] INFO [localhost] Checking Scan Modes...
[Dec 8 19:31:42] INFO [localhost] Checking dependencies...
[Dec 8 19:31:42] INFO [example-project-prod-api] Dependencies ... Pass
[Dec 8 19:31:42] INFO [localhost] Checking sudo settings...
[Dec 8 19:31:42] INFO [example-project-prod-api] Checking... sudo needs-restarting
[Dec 8 19:31:43] INFO [example-project-prod-api] Checking... sudo which which
[Dec 8 19:31:43] INFO [example-project-prod-api] Checking... sudo stat /proc/1/exe
[Dec 8 19:31:43] INFO [example-project-prod-api] Checking... sudo ls -l /proc/1/exe
[Dec 8 19:31:43] INFO [example-project-prod-api] Checking... sudo cat /proc/1/maps
[Dec 8 19:31:43] INFO [example-project-prod-api] Checking... sudo lsof -i -P
[Dec 8 19:31:43] INFO [example-project-prod-api] Sudo... Pass
[Dec 8 19:31:43] INFO [localhost] It can be scanned with fast scan mode even if warn or err messages are displayed due to lack of dependent packages or sudo settings in fast-root or deep scan mode
[Dec 8 19:31:43] INFO [localhost] Scannable servers are below...

特に問題は見当たらなそうなので、スキャン開始します。

[ec2-user@vuls]$ /usr/local/bin/docker-compose -f /opt/vuls/docker-compose.yml run --rm vuls scan -config=./project/example_project/config.toml
Creating vuls_vuls_run ... done
[Dec 8 19:35:57] INFO [localhost] Start scanning
[Dec 8 19:35:57] INFO [localhost] config: ./project/example_project/config.toml
[Dec 8 19:35:57] INFO [localhost] Validating config...
[Dec 8 19:35:57] INFO [localhost] Detecting Server/Container OS...
[Dec 8 19:35:57] INFO [localhost] Detecting OS of servers...
[Dec 8 19:35:57] INFO [localhost] (1/1) Detected: example-project-prod-api: amazon 2 (Karoo)
[Dec 8 19:35:57] INFO [localhost] Detecting OS of containers...
[Dec 8 19:35:57] INFO [localhost] Checking Scan Modes...
[Dec 8 19:35:57] INFO [localhost] Detecting Platforms...
[Dec 8 19:35:57] INFO [localhost] (1/1) example-project-prod-api is running on aws
[Dec 8 19:35:57] INFO [localhost] Detecting IPS identifiers...
[Dec 8 19:35:57] INFO [localhost] (1/1) example-project-prod-api has 0 IPS integration
[Dec 8 19:35:57] INFO [localhost] Scanning vulnerabilities...
[Dec 8 19:35:57] INFO [localhost] Scanning vulnerable OS packages...
[Dec 8 19:35:57] INFO [example-project-prod-api] Scanning in fast-root mode
 
Scan Summary
================
example-project-prod-api amazon2 (Karoo) 551 installed, 99 updatable
スキャン完了しました。結果下部に現在のサーバーの状況が出力されました。
スキャン結果をもとにレポートを生成します。

 

[ec2-user@vuls]$ / sudo /usr/local/bin/docker-compose -f /opt/vuls/docker-compose.yml run --rm vuls report -ignore-unfixed -lang ja -config=./project/example_project/config.toml

スキャン完了しました。結果下部に現在のサーバーの状況が出力されました。
スキャン結果をもとにレポートを生成します。

[ec2-user@vuls]$ / sudo /usr/local/bin/docker-compose -f /opt/vuls/docker-compose.yml run --rm vuls report -ignore-unfixed -lang ja -config=./project/example_project/config.toml

結果画面は省略しますが、正常に完了するとレポートが生成され、画面に表示されるかと思います。また、実行コマンドの引数に応じて一定の条件に応じたレポートが生成されたり、設定ファイルで通知チェネルを定義しておけばレポートを通知することが可能です。

レポートが生成されたので、コンソール上からレポートを確認したいと思います。 `vuls tui` を実行することで、コンソール上でレポートの確認が行えます。

[ec2-user@vuls]$ /usr/local/bin/docker-compose -f /opt/vuls/docker-compose.yml run --rm vuls tui -config=./project/example_project/config.toml

操作方法は割愛しますが、これでコンソール上でレポートの確認ができるようになりました。
ただ、もっと気軽に確認したり、例えば開発(運用担当)以外が確認したいという場合においては vulsrepo というプロダクトを用いて、Web ブラウザ経由でグラフィカルにスキャン結果を確認することが可能です。

既に docker-compose.yml で vulsrepo 及び nginx の定義を行っているので、正常に動いているのであればそのまま稼働サーバーに対してブラウザで Port80 でアクセスすることによって結果が確認できます。

 

■備考

構築にあたり引っかかった部分や運用に関しての軽い注意点です。

  • vuls scan 時にエラーが発生する
  • 下記パターンが考えらえます。
  • ログインユーザーが鍵認証ではない(and パスワードが設定されている)
  • fingerprint がサーバー上に登録されていない(事前にログインしておく)
  • vuls discover [cidr] コマンドを用いることで、検知できたサーバー一覧をリスト化し、設定ファイルを生成する機能があるが、 ICMP に反応しない場合は検出できませんでした。
 (弊社の場合は対象サーバーはほぼクラウド環境になるので、それぞれ提供されている cli ( SDK ) からインスタンスデータを取得して雛形を生成しています。)
 

 

■まとめ

以上、ここまでで最低限程度とはなりますが、稼働できる状態になりました。次回は弊社にてどの様に運用を行っているか、また運用における解決に関して紹介できればと考えています。

   
セガ エックスディーでは一緒に働く仲間を募集しています!
少しでも興味をお持ちの方は、お気軽にお問合せください。


最後まで読んでいただきありがとうございます。
この記事の内容について詳しく聞きたい方は、以下よりお気軽にお問い合わせください。

※記載されている会社名、製品名は、各社の登録商標または商標です。

文責:山本 和幸 株式会社セガ エックスディー システム開発部 DevOpsエンジニア
「セガ エックスディーで、様々な技術を活用し開発推進・効率化に関して取り組んでいます。」

ナレッジ一覧にもどる