Skip to content

Tanium Threat ResponseによるApache Log4j脆弱性を狙った攻撃の追跡

本ブログではTanium Threat Response(THR)モジュールの機能を使って組織内で利用されているApache Log4jのインスタンスを検索する方法を紹介します。また、公開されているPoCを元に本脆弱性を検証し、Log4Shellを狙った攻撃や侵害の検知・調査や脅威ハンティングなどの考察についてご紹介します。『Tanium Threat Responseを使ったApache Log4j脆弱性の可視化』については、こちら

 

THRモジュールの機能を使ってLog4Shellの脆弱性を狙った攻撃の痕跡を理解

ここではTHRモジュール機能をつかってLog4Shellの脆弱性を狙った攻撃の痕跡を探す例をご紹介します。

攻撃の仕組みを理解するために、今回はPoCとして公開[3]されている情報を参考にして検証を行いました。Log4Shellの脆弱性を持つJavaのWebアプリケーション(Port8080で稼働)と悪意のあるLDAP+HTTPサーバを準備しました。脆弱なWebアプリケーションはJavaで実行可能なためWindow、Linuxマシンの両方で検証しています。

攻撃の流れとしてはまず、RCE (リモートコード実行) で実行したいコマンドをBase64でエンコードし、その値をCurlコマンドで脆弱なWeb アプリケーションに対してリクエストを送信します。

悪意のあるCurlリクエストを受け取ったJavaのWebアプリケーションはLog4jによるログ出力を行います。このときJNDL Lookup機能により悪意のあるLDAPサーバに対して外部参照を行います。

この参照では、受け取ったBase64でエンコードされたコマンドと一緒にLDAPリクエストを送信します。LDAPのリクエストを受け取った悪意のあるサーバは受け取ったBase64のコマンドをデコードし、そのコマンドを実行させるJavaのクラスを動的に作成します。そしてLDAPのレスポンスに作成したJavaのクラスをURLで指定された場所から参照するように回答します。

最後にJNDL Lookupは指定されたJavaのクラスを参照(HTTP経由でダウンロード)して実行する流れになります。実行したいコマンドをBase64でエンコードしてCurlリクエストに指定するだけですので任意のコマンドの指定が可能であり、非常に簡単にRCEが実行できてしまいます。

検証した攻撃シナリオの例

 

今回の場合、攻撃対象となるWebアプリケーションのLog4jのログの出力先は /var/log/spring-boot/ と指定しました。

まず、Recorder機能によるプロセスのイベント情報を確認してみます。Linuxマシンに対してRCEで送ったコマンドは “whoami” と “cat /etc/passwd > /tmp/out” です。Javaのプロセスから子プロセスとしてシェルが起動されてそれぞれのコマンドが実行されたことが確認できます。

Windowsマシンに対してのRCEで送ったコマンドは“whoami”, “net”, “PowerShell” のコマンドです。こちらの場合もjava.exeのプロセスから子プロセスとしてcmd.exeが起動されそれぞれのコマンドが実行されたことが確認できます。

どちらの場合もjavaのプロセスがLog4jのログファイルの出力及び、悪意のあるサーバ(IP: 192.168.0.152)に対して不審なLDAPとHTTP(Port 1389と80)の通信を発生させていたことも確認できます。本環境では悪意のあるLDAPサーバとHTTPサーバは同一アドレスのサーバですが、実際の攻撃では別々のサーバであるケースもあります。

Linux マシンのRecorderで記録された挙動の例

 

WindowsマシンのRecorderで記録された挙動の例

 


LinuxマシンでのLog4jのログ出力例

 


WindowsマシンでのLog4jのログ出力例

 

THRモジュールの機能を使ってLog4Shellの脆弱性を狙った攻撃の痕跡を理解

上記PoCの検証結果を元にしてTHRモジュールを使った攻撃の痕跡をハンティングする方法について考察したいと思います。まずは悪意のある文字列から含まれたログ・ファイルがないかYARAスキャンを使って検知を試みます。本脆弱性に対する攻撃があった場合、Log4jから出力されるログファイルにその痕跡が残っている場合があります。単純に “${jndi:” の文字列もしくはそれが難読化された文字列が含まれるログ・ファイルが存在すればアラート検知させる方法です。THRモジュールではYARAのルールを取り込み、スキャンを実行してアラート検知させることができます。今回はこちら[4]で公開されているYARAルールを参考にして取り込み “/var/log/”, “C:\\var\\log\\” 配下のファイルを対象(Search Scopeに設定)にスキャンを実施してみました。

YARAスキャンのSearch Scope設定の例

 

YARAスキャンの結果、Log4Shellの脆弱性を狙った文字列が記載されているファイルがアラートとして上がってきました。今回はPoCの検証で利用した端末の他に実際にInternet上に公開されているApache Webサーバも対象としました。その結果、今回の検証で作成されたログ・ファイル(spring-boot-logger-log4j2.log)の他にApache Webサーバのaccess.logにも攻撃の痕跡があることが判明しました。


YARAスキャンによるアラート

 

実際にApacheのログの一つを確認してみると外部からLog4Shellの脆弱性の有無を調べるスキャンのようなアクセスログが確認できました。THRモジュールではないですが、Tanium Revealモジュールの機能を使えばYARAスキャンを実施することなくJNDIの文字列が含まれるファイルを特定することも可能です。YARAスキャンの場合Search Scopeでログのパスを指定する必要があります。アプリケーションのログの出力先パスが不明な場合はIndexモジュールによる.logファイルを検索することで/var/log/のような一般的なログ出力先でないパスも特定できる可能性があります。またRecorderの記録からJavaのプロセスによって作成されるファイルのパスの検索も可能です。

Apache Webサーバのaccess.log の中身

Revealを使ったjndi文字列の検索結果例

 

Log4Shellの脆弱性を狙った文字列が記載されているログが見つかったとしても、それが必ずしも侵害の痕跡とは限りません。実際の上記のApache WebサーバはLog4Shellに対して脆弱ではありませんが、攻撃やスキャンの痕跡がログとして記録されていました。ですので、ログが見つかった端末やアプリケーションがLog4Shellに対して脆弱なのか、その場合攻撃は成功したのかどうかを調査、確認する必要があります。PoCの検証結果からは攻撃が成功した場合、攻撃者が用意した外部の悪意のあるLDAPサーバへのアクセスやJavaのプロセスから不審な子プロセスが起動している痕跡が確認できます。次はこれらの点にフォーカスして侵害の痕跡の有無をハンティングする例を紹介します。

まずはネットワーク通信の観点から痕跡を探す例を紹介します。ネットワークのログはProxyやDNSのログを確認することが有効ですが、THRのRecorder機能は発生した通信がどのプロセスによるものなのかを特定することができますので不審な通信があった場合、Log4Shellに関係するものなのかを特定するのに有用な情報となります。THRのセンサーを使うことで過去のネットワーク通信の記録をプロセス名や通信先のアドレスを組み合わせて検索することができます。例えばJavaのプロセスで悪意のあるサーバのアドレス(IP: 192.168.0.152)に対する通信を検索する場合、Trace Network Connectionsセンサーを利用します。


Trace Network Connectionsセンサーの設定例

 

[過去1週間の通信から検索するQuestion例]


Trace Network ConnectionsセンサーによるLog4Shellエクスプロイト通信検索結果の例

 

またWindows端末の場合はPort 80に対するHTTPヘッダも記録可能です。今回の場合、Log4Shellの攻撃が成功すると、悪意のあるJavaクラスがJavaのプロセスによって取得されていますので、そのHTTP Headerイベントを検索することも可能です。Threat Response – HTTP Headers センサーを利用してJavaプロセスによるHTTPヘッダ通信を検索します。HTTPリクエストから取得を試みたオブジェクトや、レスポンスコードから通信の成功の有無が確認できる可能性があります。

[過去1週間の通信から検索するQuestion例]

Threat Response – HTTP HeadersセンサーによるLog4Shellエクスプロイト通信検索結果の例

 

次にプロセスの親子関係の観点から痕跡を探す例を紹介します。検証結果ではLog4Shellの攻撃が成功した場合、RCEで実行されるコマンドがJavaの子プロセス経由で実行されていました。こちらを検索するにはTHRのセンサーであるTrace Executed Process Treesセンサーを利用します。このセンサーはRecorderに記録されている過去のプロセスイベント情報を元に、指定したプロセスを起点として親のプロセスツリーもしくは子のプロセスツリーを検索することができます。今回の例ではJavaのプロセスを親プロセスとして起動した子プロセスツリーを検索します。

[Question例]

こちらの検索結果から利用しているJavaのアプリケーションでは普段見られないような子プロセスの有無をハンティングできます。またLog4Shellのエクスプロイトで実行されたRCEのコマンドはTHRのSignalsによる振る舞い検知の対象でもあります。以下はRCEで実行された不審なPowerShellの実行を検知した例です。プロセスツリー(Ancestry)よりjava.exeが親プロセスの一部となっていることが確認できます。

 


Trace Executed Process TreesセンサーによるJavaを親としたプロセスツリーを検索

 


Log4Shellエクスプロイトで実行された不審な振る舞いをアラート検知

 

最後にJavaのプロセスによって書き込まれた拡張子が.logのファイルを検索する例を紹介します。こちらはLog4Shellの攻撃の痕跡を探すというより、Javaのアプリケーションのログの出力先を検索するのが目的です。Trace File Operationsセンサーを利用してJavaのプロセスから書き込まれたファイルを検索することが可能です。

[過去1週間のファイルイベント検索するQuestion例]


Trace File OperationsセンサーによるJavaのログ出力先を検索

 

まとめ

本ブログではTanium Threat Response(THR)を利用してApache Log4j(Log4Shell)の脆弱性に該当する可能性のあるJavaのインスタンスを特定する方法、またPoCとして公開されているLog4Shellエクスプロイトの検証を通して理解した挙動からLog4jのインスタンス特定、Log4Shellによる攻撃の痕跡を検索する例を紹介しました。Log4jはJavaのライブラリですが、実際の環境ではLog4jを利用しているアプリケーションのプロセス名がJavaではなく別名である場合もあります(プロセス名がTomcat Serviceなど)。今回の検証ではプロセス名をJavaとしましたが、ハンティングの際にはこの点にも留意する必要があります。本ブログがLog4Shellの脆弱性に対する対処やハンティングのヒントになれば幸いです。

 

参考リンク

[1]  Apache Software Foundation: Log4j – Download Apache Log4j 2 :こちら
[2] CVE-2021-44228-Log4Shell-Hashes:こちら
[3]  log4shell-vulnerable-app:こちら
[4] signature-base/yara/expl_log4j_cve_2021_44228.yar:こちら

 


ブログ記事に関してご質問やご要望がございましたらこちらからお問い合わせください。