MacでLinuxサーバにVULSのスキャンをかけて安全にしたい

Mac

“macOS VULS”でググるとちょっと引くぐらい面倒臭い手順が結果に出てくるけれど、このご時世にこんな面倒なことないやろ?と思って公式ドキュメントを見ると、Dockerとvulsctlのおかげでえらい簡単になってるので自宅鯖をスキャンしてみる、と。

#簡単とはいえそれぞれのステップの詳細な動作確認手順などは説明しません。ある程度、分かってる前提で書きます。

Dockerのインストール

まずはDockerをmacOSに入れないと話は始まらないので、Docker Desktop for MacからIntel / Apple Siliconを選んでインストール。

gitのインストール

vulsctlを使うにはgitが必要なんで(普通入ってるだろうけど)macOSにbrew入れてgitをインストール。

% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
% brew install git

vulsctlをクローン

適当なディレクトリに移動してgit cloneでvulsctlを持ってくる。

% git clone https://github.com/vulsio/vulsctl.git
Cloning into 'vulsctl'...
remote: Enumerating objects: 386, done.
remote: Counting objects: 100% (270/270), done.
remote: Compressing objects: 100% (198/198), done.
remote: Total 386 (delta 178), reused 125 (delta 71), pack-reused 116
Receiving objects: 100% (386/386), 68.15 KiB | 8.52 MiB/s, done.
Resolving deltas: 100% (233/233), done.

update-all.shを実行

vulsctl/dockerに移動してupdate-all.shを実行する。見ての通りDockerのイメージ・vuls/goval-dictionaryなどをpullしてupdateをかけていく。nist.govが遅いので時間がかかる。CDN(Content Delivery Network)にしてくれないかなぁ。

% cd vulsctl/docker
% ./update-all.sh
Using default tag: latest
latest: Pulling from vuls/goval-dictionary
a0d0a0d46f8b: Already exists 
6fc7dd87dc1c: Pull complete 
3911c969c793: Pull complete 
Digest: sha256:a5b6e08500f16c97e7b8e27c9310f4d06045c70c942560aba780e088f9615e7d
Status: Downloaded newer image for vuls/goval-dictionary:latest
docker.io/vuls/goval-dictionary:latest
goval-dictionary  
INFO[11-02|23:43:12] Fetching...                              URL=https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL8.xml.bz2
INFO[11-02|23:43:12] Fetching...                              URL=https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL6.xml.bz2
INFO[11-02|23:43:12] Fetching...                              URL=https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL7.xml.bz2
INFO[11-02|23:43:12] Fetched...                               URL=https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL8.xml.bz2
INFO[11-02|23:43:12] Fetched...                               URL=https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL6.xml.bz2
INFO[11-02|23:43:12] Fetched...                               URL=https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL7.xml.bz2
<<snip>>

実はupdate-all.shをバカ正直に実行する必要は全く無い。中身は以下の通りでスキャンするターゲットに合わせてコメントアウトするのが良いかと。

#!/bin/bash

./oval.sh --redhat ${@}
./oval.sh --amazon ${@}
./oval.sh --debian ${@}
./oval.sh --ubuntu ${@}
./oval.sh --alpine ${@}
./oval.sh --oracle ${@}
./gost.sh --redhat --batch-size 500 ${@}
./gost.sh --debian --batch-size 500 ${@}
./gost.sh --ubuntu --batch-size 15 ${@}
./nvd.sh ${@}
./jvn.sh ${@}
./exploitdb.sh ${@}
./msfdb.sh ${@}

で、このoval.shとかgost.shとかは何やってるかというと、公式ドキュメントのScan using Dockerに書かれている手順そのものなので、冒頭に「Dockerとvulsctlのおかげでえらい簡単」と書いた。
なおvolumeとして$PWD:/goval-dictionaryを指定してるけど、上記Scan using Dockerの名残りであって先にupdate-all.shmkdir -pなどしてないのでこれは不要なんじゃないかと。

#!/bin/bash

if [ $# -eq 0 ]; then
        echo "specify [--redhat --amazon --debian --ubuntu --alpine --oracle]"
        exit 1
fi

target=$1
shift

if [[ -z "${DOCKER_NETWORK}" ]]; then
        DOCKER_NETWORK_OPT=""
else
        DOCKER_NETWORK_OPT="--network ${DOCKER_NETWORK}"
fi


docker pull vuls/goval-dictionary
docker run --rm -it vuls/goval-dictionary version

case "$target" in
        --redhat) docker run --rm -it \
                ${DOCKER_NETWORK_OPT} \
                -v $PWD:/goval-dictionary \
                vuls/goval-dictionary fetch redhat ${@} 6 7 8
                ;;
<<snip>>

公式ドキュメントは以下のようになってるけど、上で見た通りupdate-all.sh./jvn.shも実行してるのでここは必要なし。

config.tomlを作る

update-all.shの実行が完了したら、以下のconfig.tomlファイルをvulsctl/docker/に作成する。

[servers]
[servers.hostos]
host        = "192.168.1.2"
port        = "22"
user        = "rio"

公式ドキュメントではローカルスキャンの前提になっているからhostがスキャン対象なのかDockerホストなのか分かりにくいけれど、ここでhostに指定するのはスキャン対象、つまり自宅鯖のIPアドレス。userは自宅鯖のユーザアカウントのこと。パスワード無しでログイン出来る設定になっていれば、このままscan.shその他を実行出来る。つまり、macOSの~/.ssh/id_rsa.pubが自宅鯖のユーザ、うちの場合だと/home/rio/.ssh/authorized_keysに含まれていて、ssh rio@192.168.1.2にパスワード無しでログインできる状態になっていれば良い。

スキャンを実行

./scan.shを実行する

% ./scan.sh
Using default tag: latest
latest: Pulling from vuls/vuls
Digest: sha256:e53edc8f24458f443699e9eff2d0414c14bff361e005dfb1f719d4b48c5b5638
Status: Image is up to date for vuls/vuls:latest
docker.io/vuls/vuls:latest
[Nov  3 01:36:52]  INFO [localhost] vuls--build-20211029_022527_
[Nov  3 01:36:52]  INFO [localhost] Validating config...
[Nov  3 01:36:52]  INFO [localhost] Detecting Server/Container OS... 
[Nov  3 01:36:52]  INFO [localhost] Detecting OS of servers... 
[Nov  3 01:36:52]  INFO [localhost] (1/1) Detected: hostos: redhat 8.4
[Nov  3 01:36:52]  INFO [localhost] Detecting OS of containers... 
[Nov  3 01:36:52]  INFO [localhost] Checking Scan Modes...
[Nov  3 01:36:52]  INFO [localhost] Checking dependencies...
[Nov  3 01:36:52]  INFO [hostos] Dependencies ... Pass
[Nov  3 01:36:52]  INFO [localhost] Checking sudo settings...
[Nov  3 01:36:52]  INFO [hostos] Sudo... Pass
[Nov  3 01:36:52]  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
[Nov  3 01:36:52]  INFO [localhost] Scannable servers are below...
hostos 
[Nov  3 01:36:53]  INFO [localhost] vuls--build-20211029_022527_
[Nov  3 01:36:53]  INFO [localhost] Start scanning
[Nov  3 01:36:53]  INFO [localhost] config: /vuls/config.toml
[Nov  3 01:36:53]  INFO [localhost] Validating config...
[Nov  3 01:36:53]  INFO [localhost] Detecting Server/Container OS... 
[Nov  3 01:36:53]  INFO [localhost] Detecting OS of servers... 
[Nov  3 01:36:53]  INFO [localhost] (1/1) Detected: hostos: redhat 8.4
[Nov  3 01:36:53]  INFO [localhost] Detecting OS of containers... 
[Nov  3 01:36:53]  INFO [localhost] Checking Scan Modes... 
[Nov  3 01:36:53]  INFO [localhost] Detecting Platforms... 
[Nov  3 01:36:54]  INFO [localhost] (1/1) hostos is running on other
[Nov  3 01:36:54]  INFO [hostos] Scanning OS pkg in fast mode
[Nov  3 01:36:56]  INFO [hostos] Scanning listen port...
[Nov  3 01:36:56]  INFO [hostos] Using Port Scanner: Vuls built-in Scanner


Scan Summary
================
[Reboot Required] hostos	redhat8.4	1033 installed





To view the detail, vuls tui is useful.
To send a report, run vuls report -h.

[Reboot Require]と表示されたのは、新しいkernelがインストールされているけれど、古いkernelのまま動作しているから。ちゃんと検出出来てる。

# rpm -qa kernel
kernel-4.18.0-305.25.1.el8_4.x86_64
kernel-4.18.0-305.19.1.el8_4.x86_64
# uname -r
4.18.0-305.19.1.el8_4.x86_64

じゃあ、再起動してもう一度スキャン。

Scan Summary
================
hostos	redhat8.4	1033 installed

はい、今度は問題なし。

report.shを実行

そのまま実行すればOK。

% ./report.sh 
Using default tag: latest
latest: Pulling from vuls/vuls
Digest: sha256:e53edc8f24458f443699e9eff2d0414c14bff361e005dfb1f719d4b48c5b5638
Status: Image is up to date for vuls/vuls:latest
docker.io/vuls/vuls:latest
time="Nov  3 01:43:05" level=info msg="vuls--build-20211029_022527_" 
time="Nov  3 01:43:05" level=info msg="Validating config..." 
time="Nov  3 01:43:05" level=info msg="cveDict.type=sqlite3, cveDict.url=, cveDict.SQLite3Path=/vuls/cve.sqlite3" 
time="Nov  3 01:43:05" level=info msg="ovalDict.type=sqlite3, ovalDict.url=, ovalDict.SQLite3Path=/vuls/oval.sqlite3" 
time="Nov  3 01:43:05" level=info msg="gost.type=sqlite3, gost.url=, gost.SQLite3Path=/vuls/gost.sqlite3" 
time="Nov  3 01:43:05" level=info msg="exploit.type=sqlite3, exploit.url=, exploit.SQLite3Path=/vuls/go-exploitdb.sqlite3" 
time="Nov  3 01:43:05" level=info msg="metasploit.type=sqlite3, metasploit.url=, metasploit.SQLite3Path=/vuls/go-msfdb.sqlite3" 
time="Nov  3 01:43:05" level=info msg="Loaded: /vuls/results/2021-11-03T01:42:21Z" 
time="Nov  3 01:43:05" level=info msg="OVAL redhat 8.4 found. defs: 672" 
time="Nov  3 01:43:05" level=info msg="OVAL redhat 8.4 is fresh. lastModified: 2021-11-02T23:43:13Z" 
time="Nov  3 01:43:08" level=info msg="hostos: 0 CVEs are detected with OVAL" 
time="Nov  3 01:43:14" level=info msg="hostos: 224 unfixed CVEs are detected with gost" 
time="Nov  3 01:43:14" level=info msg="hostos: 0 CVEs are detected with CPE" 
time="Nov  3 01:43:23" level=info msg="hostos: 0 PoC are detected" 
time="Nov  3 01:43:23" level=info msg="hostos: 1 exploits are detected" 
time="Nov  3 01:43:23" level=info msg="hostos: total 217 CVEs detected" 
time="Nov  3 01:43:23" level=info msg="hostos: 0 CVEs filtered by --confidence-over=80" 
hostos (redhat8.4)
==================
Total: 217 (Critical:17 High:62 Medium:125 Low:13 ?:0)
0/217 Fixed, 61 poc, 1 exploits, en: 0, ja: 1 alerts
1033 installed

+----------------+------+--------+-----+------+---------+-------------------------------------------------+
|     CVE-ID     | CVSS | ATTACK | POC | CERT |  FIXED  |                       NVD                       |
+----------------+------+--------+-----+------+---------+-------------------------------------------------+
| CVE-2018-19325 |  9.8 |  AV:N  |     |      | unfixed | https://nvd.nist.gov/vuln/detail/CVE-2018-19325 |
<<snip>>

CVE-2018-19325はtcpdumpのvulnerability。使ってないのでdnf removeしちまうか、といった具合でCVEのドキュメントを見ながら修正していけばOKです(といっても、ここが中々大変なのだけど)。

tui.shを実行

report.shだとURLを自分で開いて、みたいなことになるのでtui.shを実行すればかなり楽に。

では、安全な自宅鯖ライフを!