はじめに
Vuls、勝手に脆弱性のあるパッケージを見つけてくれて便利ですよね。
リモートスキャンを使えば、スキャン対象のサーバにインストールする必要もなく、SSHで入って勝手になんか見つけてきてくれます。
でも、本番サーバにSSHで入られるのは少し怖い…
もし問題が起きたときに、スキャンしたせいじゃ無いですよ!と言える根拠が欲しいと思ったので、具体的にどんなことをスキャン対象サーバで行っているのか、調べてみました。
調査方法は以下の通りです。auditctl
でローカル側で実行されたコマンドを全てログし、後から解析してみました。
auditctl -a always,exit -F arch=b64 -S execve
vuls サブコマンド
auditctl -D
cat /var/log/audit/audit.log | grep "EXECVE"
環境
ローカル
# cat /etc/centos-release
CentOS Linux release 7.7.1908 (Core)
# go version
go version go1.14.2 linux/amd64
# vuls -v
vuls v0.9.5 build-20200518_192222_466ec93
スキャン対象
# cat /etc/centos-release
CentOS Linux release 7.7.1908 (Core)
結果
コマンドの実行方法
リモートサーバでコマンドを実行するときは、以下のような手法で行っているようです。
ControlMaster
を用いてTCPコネクションを集約したり、ログイン後のウィンドウ幅を1000にしたりしています。
/usr/bin/ssh
-tt
-o StrictHostKeyChecking=yes
-o LogLevel=quiet
-o ConnectionAttempts=3
-o ConnectTimeout=10
-o ControlMaster=auto
-o ControlPath=/root/.vuls/controlmaster-%r-hoge.%p
-o Controlpersist=10m vuls@ホスト名
-p 22
-i /root/.ssh/id_hoge
-o PasswordAuthentication=no
stty cols 1000; 実行するコマンド
コマンド本体は、以下のように16進数で送られているようです。記号とかで予期しない動作になるのを防いでいると思われます。
7374747920636F6C7320313030303B206C73202F6574632F64656269616E5F76657273696F6E
-> stty cols 1000; ls /etc/debian_version
以下では、stty cols 1000;
までを省略して(SSH)
と書きます。
configtest
configtestでは、以下のコマンドが実行されていました。
単純にOSのバージョン情報を取得しているだけですね。今回は、対象サーバがCentOSだったので、それをcat
しているようです。(いつもredhat-releaseを見ていたのですが、centos-releaseもあるんですね…)
vuls configtest
(SSH) ls /etc/debian_version
(SSH) ls /etc/fedora-release
(SSH) ls /etc/oracle-release
(SSH) ls /etc/centos-release
(SSH) cat /etc/centos-release
fast-offline
fast-offlineモードでは、以下のコマンドが実行されていました。
前半はconfigtestと同じで、対象サーバのOSバージョンを取得しています。
その後、IPアドレスの取得、カーネルのバージョン?の取得、インストールされているパッケージの列挙となっています。IPアドレスはofflineの有無に関わらず、ここで取得しているようです。
vuls scan hoge
(SSH) ls /etc/debian_version
(SSH) ls /etc/fedora-release
(SSH) ls /etc/oracle-release
(SSH) ls /etc/centos-release
(SSH) cat /etc/centos-release
(SSH) /sbin/ip -o addr
(SSH) uname -r
(SSH) rpm -qa --queryformat "%{NAME} %{EPOCHNUM} %{VERSION} %{RELEASE} %{ARCH}\n"
(SSH) rpm -q --last kernel
fast
fastモードでは、以下のコマンドが実行されていました。
fast-offlineモードに加え、
1. AWSで動いているかの確認、動いていればインスタンスIDの取得?
2. yumリポジトリデータのダウンロード
3. dnfが入っているかのチェック(yumの代わりにdnfが入っていたらコマンドが変わる…?)
4. repoqueryでアップデート可能なバージョンを検索する(dnfだったらオプションが微妙に違う)
オンプレで動いていても169.254.169.254
に通信を飛ばそうとするんですね。
vuls scan hoge
(SSH) ls /etc/debian_version
(SSH) ls /etc/fedora-release
(SSH) ls /etc/oracle-release
(SSH) ls /etc/centos-release
(SSH) cat /etc/centos-release
(SSH) type curl
(SSH) curl --max-time 1 --noproxy 169.254.169.254 http://169.254.169.254/latest/meta-data/instance-id
(SSH) /sbin/ip -o addr
(SSH) uname -r
(SSH) rpm -qa --queryformat "%{NAME} %{EPOCHNUM} %{VERSION} %{RELEASE} %{ARCH}\n"
(SSH) rpm -q --last kernel
(SSH) yum makecache --assumeyes
(SSH) repoquery --version | grep dnf
(SSH) repoquery --all --pkgnarrow=updates --qf='%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{REPO}'
まとめ
いかがでしたか?特に環境を変えるようなことはしていないことが分かりましたね!(当然)
強いて言えばIPアドレスやインスタンスIDの取得は必要でない場合もあると思うので、オプションでコマンドを発行しないようにできると、不必要な情報が取得されず安心かなと思いました。
もちろん変なことはしていないと思っていましたが、今回自分で確認してより安心できました。