セキュリティブログ

S2-062(CVE-2021-31805) に関する任意のコード実行について

S2-062(CVE-2021-31805) に関する任意のコード実行について

更新日:2023.11.21

2022年4月19日 00:22 PM (JST)

こんにちは、くまさかです。

本脆弱性に関しては既に様々な情報が出ておりますが、それらの情報に関し少し注意すべき点があるため、その共有と検証結果等を紹介します。
既に、OGNL式%{.*}等にてシグネチャを書かれた防御側の皆様は、本ページの項目「攻撃クエリの特徴は%{.*}ではない」 をご覧ください。

概要

既にJPCRERTより、S2-062について注意喚起が出ている ので、ご存じの方も多いかと思いますが、

Apache Struts 2.0.0 から、2.5.29 までで、
任意のコード実行 が可能な脆弱性があります。

なお、既に修正版の、Apache Struts 2.5.30 がリリース されているので、こちらへのアップデートを推奨します。

発動条件

本脆弱性は、OGNL式が存在するnameエレメントがあり、且つ、同一タグ上でvalueエレメントがが存在しない場合に攻撃が可能です。
(そのため、作成されているコンテンツの形によっては、影響を受けない可能性もあります。)

labelタグで例を表すと、以下のような表記になります。

<s:label id="rabbit" name="%{tank}" />

この例では、tankに、細工した文字列を挿入することで、任意のコード実行が可能となります。

攻撃クエリの特徴は、%{.*}ではない

よく紹介されるApache Struts 2 の、OGNL式な攻撃コードの特徴としては、%{.*}や、EL式も動作する際には、${.*} といった文字列があります。
しかしながら、今回の脆弱性では、それらの特徴が無い形にて攻撃を成功させます。
もし、「OGNL式による攻撃なので、%{.*}をひっかけよう。」と検討された方がおりましたら、それでは不十分であり、対策の軌道修正が必要です。

以下は、弊社検証環境構成での、攻撃が成功するクエリの画像です。

攻撃クエリのpcapファイルからhttp streamを表示したもの
攻撃クエリのpcapファイルからhttp streamを表示したもの

赤枠で囲んでいるところからわかるように、%28%23から始まっています。(デコードすると、(#
このように、%{}というような文字列を含めない形で攻撃が可能なため、%{.*}という単純なルールでは検出できません。

また、今回は、S2-061とは異なり、攻撃コードの実行結果(stdout)がHTTPレスポンスのbodyに、含まれないという特徴もあります。レスポンスで攻撃成功の有無などを判断しようとしている場合は、この点も注意が必要です。

本脆弱性の原因

本脆弱性は、S2-061の修正が不十分であったためといった表現を目にします。
具体的にどのような修正であったのかを確認しつつ、原因箇所を少し解説します。

S2-061では、OGNL式の多重評価により任意のコード実行が可能だった為、修正が行われました。
https://github.com/apache/struts/commit/0a75d8e8fa3e75d538fb0fcbc75473bdbff9209e

しかし、この修正にて、OGNL式へ変換したexprインスタンスを用意する※1 も、
exprではなく、変換前のnameインスタンスを評価に利用する※2 といった修正が加えられてしまいました。
この実装により、評価されていないOGNL式なexprインスタンス が実行されてしまうといった挙動をしています。
該当箇所は、parameters.containsKey("value")のelse上に存在する ※3なので、同一タグ上のエレメントに、valueのエントリが無いと、任意のOGNL式が実行できます。

※1 https://github.com/apache/struts/commit/0a75d8e8fa3e75d538fb0fcbc75473bdbff9209e#diff-cfe644a2b24b492d6835fa1f38e7a770dad354b286cbe6b056a5fe7e80e669caR797
※2 https://github.com/apache/struts/commit/0a75d8e8fa3e75d538fb0fcbc75473bdbff9209e#diff-cfe644a2b24b492d6835fa1f38e7a770dad354b286cbe6b056a5fe7e80e669caR798
※3 https://github.com/apache/struts/commit/0a75d8e8fa3e75d538fb0fcbc75473bdbff9209e#diff-cfe644a2b24b492d6835fa1f38e7a770dad354b286cbe6b056a5fe7e80e669caR787

なお、Apache Struts 2.5.30 に含まれる最終的な修正では、exprインスタンスの用意をする直前に処理が移されています。
https://github.com/apache/struts/commit/e1209fde05a34b28e747f1fa858c82d2a32cb018#diff-cfe644a2b24b492d6835fa1f38e7a770dad354b286cbe6b056a5fe7e80e669caR804
(同じような修正漏れを誘発させないためか、オブジェクト名をnameのみから、translatedName等と差分も持たせているので、差分が多くなっていますね。)

ワークアラウンド

前述の通り、value のエントリが無い場合に限り、任意のOGNL式が実行できるという条件のため、ワークアラウンドとして、valueのエントリを付加する事も挙げられます。
用途が無いのであれば、以下の例のようにvalueに空の値を入れるといった対応でも防ぐことが可能です。

<s:label id="rabbit" name="%{tank}" value="" />

弊社検証環境構成では、実際にvalue有無それぞれのコンテンツを作成し、空のvalueがある場合には攻撃を防げることを確認しています。

攻撃が実行可能なコンテンツの例
攻撃が実行可能なコンテンツ例
ワークアラウンドにて、実行不可なコンテンツ例
ワークアラウンドにて、実行不可なコンテンツ例

なお、攻撃コードの実行結果は、HTTPレスポンスに含まれず攻撃が失敗するワークアラウンドの例であっても、200OKが返されます。
そのため、防御可否はサーバ側の実行ログ等で確認するしかありません。

シグネチャで守るのであれば。

前述したように、%{.*} だけでは、すり抜けます。

よく見かけるRCEのPoCでは、OGNL Sandbox回避の為の特徴的な文字列((#request.map=#@org.apache.commons.collections.B...)が見られるので、世に出ているRCEなPoCを防ぐには、こちらを特徴とすることも検討に挙げられます。
しかし、RCEではなく、#application['org.apache.*************'].getResource('/mycontent.html').*********()のように、リソースを取得し、書き換える事が可能なOGNL構文は異なる特徴をしているので、注意が必要です。
(公開されているPoCの調査中に、リソースへの変更を加えるPoCのソースコードも確認しています。)

攻撃者の調査を阻むことはできませんが、実害を防ぐためのシグネチャとしては、
「Apacheのリソースにアクセスでき、OGNL構文の中身に特徴的に表れる文字列が含まれること」を念頭に、条件としては少し広めですが、以下のようなパターンが考えられます。

# が含まれ、
#@org\.apacheか、'org\.apache のいずれかまたはその両方が含まれること

やはり、根本的な対策を推奨

以上のように、単純なワークアラウンドでは対応が漏れる可能性が考えられますし、それをどうにかしようと思うと、シグネチャで少し広めの検知するしかありません。

そのため(本件に限ったことではないですが)、可能な限り、バージョンアップを推奨いたします。
(本ブログの最初に記載した通り、既に修正版のApache Struts 2.5.30 がリリース されています。)


実は今回、S2-062 についてはだいぶ乗り遅れ感があったので、ブログの見送りを考えておりました。
しかし、S2-062を簡単に調べて出てくる情報では、残念ながらOGNL式というキーワードや、%{} での対応策が目立っておりました。
そのため、防御側の誤認が発生している可能性もあるかと考え、ここに掲載するに至りました。

参考


2022年04月19日 00:22 PM (JST): 公開

2022年04月21日 10:00 AM (JST): スタイルを一部修正

2023年11月21日 09:00 PM (JST): 記事更新日時のシステムアップデート

セキュリティ診断のことなら
お気軽にご相談ください
セキュリティ診断で発見された脆弱性と、具体的な内容・再現方法・リスク・対策方法を報告したレポートのサンプルをご覧いただけます。

関連記事

経験豊富なエンジニアが
セキュリティの不安を解消します

Webサービスやアプリにおけるセキュリティ上の問題点を解消し、
収益の最大化を実現する相談役としてぜひお気軽にご連絡ください。

疑問点やお見積もり依頼はこちらから

お見積もり・お問い合わせ

セキュリティ診断サービスについてのご紹介

資料ダウンロード