鳩小屋

落書き帳

log4shell 年末防衛戦

log4shell(CVE-2021-44228)が先週金曜日頃から話題になり一週間経ちました。
CVSSが最大スコア10ということで、いろいろなところで被害調査や対策実施に追われていたのではないでしょうか。

logging.apache.org

概要

この脆弱性Javaのロギングに関するライブラリであるlog4j-coreというパッケージが対象となっています。
特にJavaアプリケーションが DNSLDAPを利用するためのJava Naming and Directory Interface(JNDI)に関するJNDI lookup という機能がよろしくないようです。

JNDI lookupは${}で囲まれたログ文字列を変数化し、DNSLDAP 等などの外部ドメインが含まれていればリクエストを飛ばしてしまいます。
そのため、まずは悪性LDAPサーバにアクセスさせ、悪性クラスファイルを配置したwebサーバに誘導することで任意のコード実行が可能になります。
また、任意のコード実行まで行われなかったとしても、攻撃フローの途中で行われるDNSクエリから環境変数が流出するケースやDos攻撃も想定されます。
普通の環境変数であれば許容範囲ですがAWSのアクセスキーなどが漏洩すると笑えないことになります。

milestone-of-se.nesuke.com

脆弱性有無の判定

この脆弱性(CVE-2021-44228)はlog4j-coreというパッケージに含まれていますが、紛らわしいものとしてlog4j-apilog4j-to-slf4jといったライブラリもあります。
log4j-apiはバックエンドとしてlog4j-coreを利用していれば問題ですが、そうでなければこのファイル自体にはJNDI lookupが含まれていないため問題なさそうです。
log4j-to-slf4jについてもslf4j APIとの互換ライブラリであるため、問題はありません。
そのため、該当バージョンのlog4j-coreが存在しているかが重要になります。

www.slf4j.org

log4j-core(2.0-beta9から2.14.1まで)を検出する方法には以下のような方法があるようです。
MavenのようなjavaパッケージマネージャやrpmのようなOSパッケージマネージャの機能で依存パッケージを出力する方法
・findコマンドやwhereコマンドでファイルを全探索する方法
・実行中のjavaプロセスが参照するクラス一覧が格納されたクラスパスから検索

パッケージマネージャですべて検出できるのか、WAR ファイルは大丈夫かなど、いくつか懸念はあるものの、ある程度有効っぽいです。
ちなみに私有VMでファイル検索を試してみましたがノーコード開発ツールのMendixとリバースエンジニアリングツールのGhidraが引っ掛かりました。
f:id:FallenPigeon:20211218161920p:plain

脆弱性診断ツールでもこの機能が使われているケースがあり、セキュリティツールを使おうとしたら死んだみたいなこともありそうです。

PoCコードもたくさん出回っているので簡単な検証を実施するのもよいかもしれません。
各製品の対応状況をまとめたリストもあるようです。

log4shell/software at main · NCSC-NL/log4shell · GitHub

被害調査

パッチ適用前に攻撃が行われていないか確認するためには、ログから特徴的な挙動を探す形になります。
攻撃時には通常の運用では発生しないアウトバウンド通信が行われるはずです。特にLDAPDNSに関して不審なものが見つかれば、リクエストとレスポンスを確認すべきでしょう。
これらの挙動が確認された場合は、対象のJavaアプリを中心に本格的な調査が必要になります。Javaアプリが行った挙動ログを確認し、不審なものを抽出していきましょう。

恒久対策

恒久対策はJavalog4jの更新になります。が、いくつか注意点もありそうです。
当初はJavaがこのバージョンなら他の対策は不要、log4jは2.15であれば問題なしといった情報が出回っていましたが、2.15でのDos攻撃、情報漏洩(第2号:CVE-2021-45046)や該当Javaバージョンのパラメータ回避策が登場してきています。
2.16についても無限再帰によるDos攻撃(第3号:CVE-2021-45105)が発見され、修正された2.17が登場しています。
どちらも最新バージョンにするほかなさそうです。

www.bleepingcomputer.com
www.bleepingcomputer.com

緩和策

そんなにポンポン更新出来たら苦労はせんのじゃボケという方もいらっしゃるかと思います。

Javaやアプリに変更を加えずにできる有効な緩和策は、インバウンド通信による接続元の制限が挙げられます。
脆弱性Javaライブラリに悪性ペイロードを着弾させることで顕在化するため、ネットワークレイヤの遮断で大半の攻撃は防止できます。また、アウトバウンド通信についても必要最低限、特にLDAPDNSなどをブロックすることで二重防御が可能です。

もう一つの方法は、WAFルールによるブロックになります。ただし、WAFのブロックは基本文字列比較で行われます。
この脆弱性は多数の文字列エスケープ手法が発見されているため、過信は禁物です。

github.com

最後にサーバ側の対策になります。
trustURLcodebaseやformsgnolookupsのパラメータ設定が有効とされていましたが、回避策が登場しているようです。
いまのところjndilookup.classを削除する方法がまともそうです。

回避策がさらに登場する可能性があるため、恒久策が取れない場合は複数の緩和策の実施を検討しましょう。