
スマートなLog4Shell/Log4j/CVE-2021-44228スキャナー
組織が重要な Log4J / CVE-2021-44228 脆弱性に対して脆弱なアプリケーションを環境内でスキャンするのに役立つ優れたツールがいくつかリリースされていますが、私は次のように感じました:
そこで Log4Shell Sentinel が誕生しました。Log4Shell Sentinel は、いくつかの独自機能を備えたファイルベースのスキャナーです。他の利用可能なツールを置き換えることを意図しているわけではありませんが、それらを補完することができます。
Log4Shell Sentinel はファイルベースのスキャナーです。対象システムをスキャンして以下のファイル形式のアーティファクトを探すことで、Javaベースのアプリケーションを検索します。
| ファイルタイプ | 詳細 |
|---|---|
| シンプルなjar | これは、log4j-core ファイルが埋め込まれていないケースです。 |
| Fat / Uber jar | uber jar は、クラス/パッケージとアプリケーションのすべての依存関係(ライブラリ、リソース、メタデータファイル)を単一の jar ファイルに含む jar です。これは最も一般的に使用されるデプロイオプションです。 |
| WAR | war(Web Application Archive)ファイルは、ライブラリやその他のリソースに加えて、JSP、HTML、JavaScript コードを含むファイルです。この形式はあまり一般的ではありません。 |
| EAR | ear(Enterprise Application Archive)は、Jakarta EE でのデプロイでより一般的に使用されていたもう1つの形式です。 |
そして、脆弱な log4j-core jar のインスタンスを検索します。次に以下の処理を行います:
アーティファクトの MD5 ハッシュを計算します。これにより、アナリストは異なるマシン / コンテナで実行されている同じアプリケーションを特定し、それらを単一の検出結果として扱うことができます
/var/lib/docker/overlay2/192768f471818601094bf4edd96d14bfc0e2b178a04a2efd00b2231ad4e46b33/merged/app/spring-boot-application.jar のようなコンテナに属することが判明したファイルについて、ファイルを対応するイメージにマッピングする重い処理を行います。例えば、上記を次のイメージに変換します:ghcr.io/christophetd/log4shell-vulnerable-app:latest。さまざまなコンテナランタイムがこのマッピングを異なる方法で保存するため、これによりアナリストの何時間ものフラストレーションが軽減されます。また、アナリストは単一のアプリケーションを実行している複数のコンテナを単一の検出結果として扱うこともできます
キャッシュされたイメージを含め、現在実行されていないコンテナに対応するマッチなど、役に立たないマッチを削除します。これにより、アナリストは重要なことに集中でき、やはり何時間もの無駄な作業を節約できます
アナリストは以下に基づいてマッチを無視できます:
これにより、アナリストは脆弱ではないと分かっているアプリケーションや、脅威とならないCLIベースのアプリケーションに対応するものを削除できます。例えば、Logstash のインスタンスが検出された場合、アナリストはそのツールを実行しない場合や、CLIから時々実行するだけの場合には、それを無視することを選択できます。
設定管理ツール(Ansible など)と連携するように最適化されており、環境を数分で迅速にスキャンできます
Log4Shell Sentinel によって追加されたメタデータのエンリッチメントの詳細については、私のブログ 記事 を参照してください。
最も簡単な方法は、プリコンパイル済みバイナリをダウンロードすることです。
これも簡単です。ただし、環境におけるGLIBC関連の差異を回避するために、静的コンパイル版をビルドしたいと思うでしょう。このツールは、デフォルトでCGOを使用する以下のモジュールを使用しています:
os/usernetこれらのライブラリのGoバージョンを使用する静的コンパイル版をビルドするには、リポジトリをクローンしてから次のコマンドを実行するだけです:
$ CGO_ENABLED=0 go build -ldflags="-s -w"
$ ldd log4shell_sentinel
not a dynamic executable
$ ./log4shell_sentinel -h
NAME:
Log4Shell Sentinel - by Osama Elnaggar
USAGE:
log4shell_sentinel [global options] command [command options] [arguments...]
VERSION:
v1.0.0
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--path value, -p value Path to search (default: ".")
--no-banner, --nb Suppress banner (default: false)
--no-messages, --nm Suppress messages except for CSV output (default: false)
--no-header, --nh Suppress header in CSV output (default: false)
--imd5 value, --im value Ignore MD5 hashes. Refer to the GitHub page for expected format
--ipath value, --ip value Ignore file path matches. Refer to the GitHub page for expected format
--icimage value, --ic value Ignore container image matches. Refer to the GitHub page for expected format
--print-headers, --ph Print CSV Headers only (default: false)
--help, -h show help (default: false)
--version, -v print the version (default: false)
初期状態では、スキャンは単に現在のディレクトリをスキャンします。例:
$ ./log4shell_sentinel
░█░░░█▀█░█▀▀░█░█░█▀▀░█░█░█▀▀░█░░░█░░░░░█▀▀░█▀▀░█▀█░▀█▀░▀█▀░█▀█░█▀▀░█░░
░█░░░█░█░█░█░░▀█░▀▀█░█▀█░█▀▀░█░░░█░░░░░▀▀█░█▀▀░█░█░░█░░░█░░█░█░█▀▀░█░░
░▀▀▀░▀▀▀░▀▀▀░░░▀░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░▀▀▀░▀▀▀░▀░▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀
- A CVE-2021-44228/CVE-2021-45046/CVE-2021-45105 Scanner
- v1.0.0
- by Osama Elnaggar
[*] WARNING: Running as non-root user.
Non-readable files / dirs will be skipped
Container mapping will fail
[*] Starting shallow scan ............ [DONE]
[*] Starting deep scan ............... [DONE]
[*] Calculating MD5 hashes ........... [DONE]
[*] Performing container image lookups [DONE]
[*] Processing ignore list(s) ........ [DONE]
[*] Generating output ................ [DONE]
IP,Hostname,AppName,Team,Ignore (Y/N),Comments,MD5Hash,Timestamp,Container,ContainerImage,FullPath,Version
192.168.121.121,server3,,,,,4e615cd580758b70c49ade1f79103328,2021-12-21T07:38:09Z,true,ghcr.io/christophetd/log4shell-vulnerable-app:latest,/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,log4j-core-2.14.1.jar
root 以外のユーザーとして実行すると、すぐに 警告 が表示されます。このツールは root 権限を必要とするためです:
root 権限がなくても動作しますが、最良の結果が得られない可能性があります。
サンプルの検出結果は次のようになります:
IP,Hostname,AppName,Team,Ignore (Y/N),Comments,MD5Hash,Timestamp,Container,ContainerImage,FullPath,Version
192.168.121.121,server3,,,,,4e615cd580758b70c49ade1f79103328,2021-12-21T07:38:09Z,true,ghcr.io/christophetd/log4shell-vulnerable-app:latest,/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,log4j-core-2.14.1.jar
一部のフィールドは意図的に空のままにしてあり、アナリストがExcelなどで記入できるようにしています。各フィールドの簡単な説明は次のとおりです:
このツールには以下のオプションがあります:
Log4Shell Sentinel の他のツールにはない独自機能の1つは、ファイルシステムスキャンで見つかった jar を次のようなパスから対応するコンテナイメージに変換できることです:
/var/lib/docker/overlay2/192768f471818601094bf4edd96d14bfc0e2b178a04a2efd00b2231ad4e46b33/merged/app/spring-boot-application.jar
対応するコンテナイメージに変換します(上記は例えば ghcr.io/christophetd/log4shell-vulnerable-app:latest に変換されます)。さまざまなコンテナランタイムがこのマッピングを異なる方法で保存するため、アナリストの何時間ものフラストレーションが軽減されます。また、アナリストは単一のアプリケーションを実行している複数のコンテナを単一の検出結果として扱うこともできます。このソリューションは現在、以下のルックアップをサポートしています:
最初は特定されたアプリケーションの数が多すぎると感じるかもしれませんし、外部ユーザーに公開されているものなど、特定されたアプリケーションの特定のサブセットに最初に焦点を当てたいかもしれません。あるいは、特定のコンプライアンス範囲に焦点を当てたいかもしれません。これをサポートするために、アプリケーションはリストの指定をサポートしています。Log4Shell は現在、3つの無視リストをサポートしています:
単純なリストの代わりに、入力としてCSVファイルを期待します。これにより、アナリストは特定の検出結果を無視する理由を文書化するよう促されます。アナリストは、検出結果を処理し、手動または自動のソースコード分析やDASTツールなどを使用して、脆弱ではないアプリケーションを特定します。
リストは次の形式の単純なCSVファイルです:
MD5Sum,AppName,Reason
AppName と Reason 列は空でもかまいませんが、特定のアプリケーションを含めたり除外したりする理由を記録しておくためのものです。
注記 この機能はアプリケーションに対して計算されたMD5ハッシュを使用するため、fat / uber jar、EAR、WAR のアプリケーションでのみ機能します。
例えば、次のような検出結果があった場合:
IP,Hostname,AppName,Team,Ignore (Y/N),Comments,MD5Hash,Timestamp,Container,ContainerImage,FullPath,Version
192.168.121.121,server3,,,,,4e615cd580758b70c49ade1f79103328,2021-12-21T07:38:09Z,true,ghcr.io/christophetd/log4shell-vulnerable-app:latest,/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,log4j-core-2.14.1.jar
そして、そのアプリケーションが_脆弱ではない_と判断した場合、次の内容を hashes.csv に保存するだけです:
4e615cd580758b70c49ade1f79103328,Demo App,Not vulnerable
その後、再実行します:
# ./log4shell_sentinel --im hashes.csv --path /
上記の検出結果は抑制されます。
リストは次の形式の単純なCSVファイルです:
Container Image,AppName,Reason
前の例に基づいて、コンテナイメージが ghcr.io/christophetd/log4shell-vulnerable-app:latest である検出結果を無視するように設定できます。次のような images.csv ファイルを作成します:
ghcr.io/christophetd/log4shell-vulnerable-app:latest,,
そして、次のように実行します:
# ./log4shell_sentinel --ic images.csv -p /
再び、先ほどの検出結果は抑制されます。
これも、次の形式の単純なCSVファイルです:
Path,AppName,Reason
上記の例を使用して、次の paths.csv ファイルを作成すると:
/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,Demo App,Not vulnerable
先ほどの検出結果は抑制されます。
警告 可能であれば、パスは一意ではない可能性があるため、抑制にはMD5ハッシュまたはコンテナイメージ名を使用することをお勧めします。
Log4Shell Sentinel を単一のサーバーで実行してもまったく問題ありませんが、お気に入りの構成管理ツール(Ansible、Chef、Puppet、Salt、AWS SSM など)や、parellel-ssh のような単純な並列SSHツールと組み合わせると、真価を発揮します。
これにより、以下のような多くの利点が得られます:
実際の完全な例については、私のブログ 記事 を参照してください。
環境の一括スキャン のセクションを参照してください。
root ユーザーとして実行していないこと(アプリケーションがインストールされている可能性のある場所へのアクセスが必要です)または正しい path を指定していないことに関係している可能性があります。root ユーザーとして実行し、--path / を設定することをお勧めしますv1.0.0 の時点で、ツールは以下のマッピングをサポートしています:
これ以外を使用している場合、マッピングは機能しません。上記のいずれかを使用している場合、root ユーザーとしてツールを実行していないか、使用されるソケット / ファイルがデフォルト以外の場所にある可能性があります。
開発者:Osama Elnaggar
| フィールド | 例 | 説明 |
|---|
| IP | 192.168.121.121 | インスタンスに複数のIPがある場合、プライマリIPが追加されます |
| Hostname | server3 | ホスト名 |
| AppName | スキャン完了後にユーザーが記入するための項目です | |
| Team | スキャン完了後にユーザーが記入するための項目です | |
| Ignore (Y/N) | スキャン完了後にユーザーが記入するための項目です | |
| Comment | スキャン完了後にユーザーが記入するための項目です | |
| MD5Hash | 4e615cd580758b70c49ade1f79103328 | アプリケーションの一意のフィンガープリント |
| Timestamp | 2021-12-21T07:38:09Z | スキャンが実行されたタイムスタンプ。同じホストの複数のスキャンを集計する場合に便利です |
| Container | true | true = コンテナであることを示します |
| ContainerImage | ghcr.io/christophetd/log4shell-vulnerable-app:latest | コンテナが検出された場合、対応するイメージ |
| FullPath | /run/containerd/io.containerd. runtime.v2.task/k8s.io/.../spring-boot-application.jar | 検出結果のフルパス。この例では、脆弱なJARファイルはfat / uber jarの一部です |
| Version | log4j-core-2.14.1.jar | 検出された log4j-core のバージョン |
| オプション | 詳細 |
|---|
--path value, -p value | 検索するパスを指定します。デフォルトでは、現在のディレクトリを検索します。重要 ファイルシステム全体をカバーするために、これを / に設定することをお勧めします |
--no-banner, --nb | バナーを非表示にします |
--no-messages, --nm | 進行状況関連のメッセージなどのメッセージを非表示にします |
--no-header, --nh | CSV出力のヘッダーを非表示にします。複数のサーバーで実行する場合に推奨されます |
--imd5 value, --im value | MD5ハッシュを無視します。詳細は 無視リスト のセクションを参照してください |
--ipath value, --ip value | ファイルパスの一致を無視します。 詳細は 無視リスト のセクションを参照してください |
--icimage value, --ic value | コンテナイメージの一致を無視します。詳細は 無視リスト のセクションを参照してください |
--print-headers, --ph | CSVヘッダーのみを出力します。複数のサーバーで Log4Shell Sentinel を実行して結果を集約する場合、通常はヘッダー出力を無効にします。このコマンドはヘッダーのみを出力するため、Excelシートに追加できます |