##はじめに
2021年、最後の最後で登場した脆弱性問題であるLog4Shellについてのお話です。
Log4Shellって何?という方は以下の記事をご参照ください。
弊社では自社導入しているDevice42が日常的に機器情報を自動収集しています。
今回はその収集された情報からlog4j
が入っているサーバーを探す作業を行いましたので、その備忘録をここに残します。
※なおDevice42はPostgresSQLを使用していますので、後述するSQLクエリはPostgresSQLでの記述になっています。
Device42については以下で紹介していますので、ご興味のある方は是非。
##①使用中のソフトウェア情報を利用した検出方法
ひとつ目は関連性のあるソフトウェア名から対象機器を選別する方法です。
自動収集で使用中のソフトウェア(自動収集されたソフトウェア情報)
の情報がとれている場合、以下のSQLでlog4j
と関連のあるソフトウェア名で検索することで対象の機器を検出することができます。
WITH javacomp AS (
SELECT
sf1.software_pk,
sf1.name,
sf1.server_software_fk
FROM view_software_v1 sf1 -- ソフトウェア名の検索条件指定
WHERE LOWER(sf1.name) LIKE '%java%'
OR LOWER(sf1.name) LIKE '%log4j%'
)
SELECT
si1.device_fk AS "デバイスID",
d.name AS "デバイス名",
javacomp.name AS "ソフトウェア名"
FROM javacomp
INNER JOIN view_softwareinuse_v1 AS si1 ON javacomp.software_pk = si1.software_fk
LEFT JOIN view_device_v2 AS d ON si1.device_fk = d.device_pk
ORDER BY "デバイスID" ASC
これでjava
とlog4j
が使用中のソフトウェアとしてインストールされているデバイス(機器)が出力されます。
ただしこのやり方はあくまでソフトウェア名での検索をかけているため、後述の手法と比べると正確性で劣ります。
上記の例でいえばjava
と名の付く大量のソフトウェアコンポーネント群が抽出対象に引っかかってしまうので、出力結果をさらに精査する必要が出てきます。
##②サービスインスタンス情報を利用した検出方法
こちらの手法が本命となります。
Device42ではオプションのADMライセンスをつけることによって、サービスインスタンスのパス(環境変数)情報を取得してくれます。
SQLクエリで抽出する場合は以下のように記述します。
SELECT
d.name AS "デバイス名",
s.displayname AS "サービスインスタンス名",
si.cmd_paths AS "コマンドパス"
FROM view_serviceinstance_v2 AS si
LEFT JOIN view_device_v2 AS d ON d.device_pk = si.device_fk
LEFT JOIN view_service_v2 AS s ON s.service_pk = si.service_fk
WHERE (si.cmd_paths::text like '%log4j%')
パスにlog4j
が含まれているサービスインスタンスと、そのサービスが入っているデバイスを出力することができました。
##まとめ
①の使用中のソフトウェア単位で脆弱性を探し出す場合には有効ですが、今回のように対象ソフトウェア群が広範囲にわたる場合にはあまり有効な手法とは言えません。
最終的には②のサービスインスタンス情報から探し出す方法で、より正確な対象機器一覧を抽出できました。
これはlog4jはあくまでライブラリのため、ソフトウェア名で検索をかけても直接は出てこないことの方が多いからです
サービスのパスであればlog4jを使用している全く異なる名前のソフトウェアでも検出ができます
今回のように影響範囲が膨大な脆弱性ですと、都度各機器にログインして確認を行うというのはかなり手間がかかることかと思われます。
こういうときこそCMDBツールの利点を生かしていきたいですね。