XML external entity (XXE) injection
0. Mở đầu
XXE (XML external entity) injection là một lỗ hổng đã có từ lâu và hiện tại độ phủ sóng của XML trên các Web Application cũng đã giảm đi đôi chút. Dù vậy, đây là một lỗ hổng một khi đã xuất hiện thì đều được đánh giá ở mức độ nghiêm trọng. Và có một sự thiếu sót nhẹ khi mình search trên Viblo về XXE thì không thấy bài viết nào về nó cả, không phải ngẫu nhiên mà năm 2017, XXE đứng top 4/10 trong top Top 10 Web Application Security Risks của OWASP !
1. Về XML
Mình định trích dẫn định nghĩa về XML trên wikipedia về, nhưng có vẻ hơi phức tạp. Nên mình trích dẫn về XML từ W3School tại đường dẫn này.
XML stands for eXtensible Markup Language.
XML was designed to store and transport data.
XML was designed to be both human- and machine-readable.
Vậy XML được dịch nôm ra là ngôn ngữ đánh dấu mở rộng, được thiết kế với mục đích lưu trữ, truyền dữ liệu và cả người và "máy" đều có thể đọc được.
Cụ thể hơn, chúng là những file có đuôi (extension) .xml , nó giúp đơn giản hóa việc chia sẻ dữ liệu giữa các hệ thống khác nhau, vì thế nên có rất nhiều ngôn ngữ đánh dấu hay các ứng dụng khác dựa trên XML với những mục đích khác nhau (Ví dụ: RDF, RSS, MathML, XHTML, SVG,...); và đương nhiên phần extension của file cũng sẽ khác đi. Nhưng về bản chất đều thông qua việc sử dụng các thẻ xác định cấu trúc tài liệu cũng như cách tài liệu được lưu trữ, đọc và vận chuyển.
Ví dụ:
Dòng đầu tiên là Khai báo XML (XML declaration), nó nên có chứ không bắt buộc phải có. Ở phần thân, cứ một cặp thẻ mở-đóng trong XML tạo thành một phần tử, và các phần tử này lồng nhau tạo nên cấu trúc dạng cây. Đương nhiên sẽ có những quy định về cú pháp, cách khai báo, cách lồng các phần tử, thêm thuộc tính cho các thẻ..., nhưng đó không phải là chủ đề chính của bài viết này.
2. Về External Entity trong XML
Khai báo external entity chính là điểm mấu chốt trong kỹ thuật tấn công XXE. Vậy nó là gì ?
2.1 DTD
Trước tiên hãy tìm hiểu về DTD (document type definitions) - dịch nôm ra DTD dùng để "định nghĩa loại tài liệu" thông qua việc xác định cấu trúc cũng như chỉ ra format hợp lệ của các elements và attributes trong file xml.
Nếu DTD được định nghĩa luôn bên trong file xml, nó được gọi là Internal DTD. Còn ví dụ dưới đây là ví dụ về một External DTD. Tức là bản thân DTD là một file, nằm ngoài file xml. Ví dụ từ w3schools:
Vậy là trong file XML này, ngoài phần XML declaration như ví dụ ở phần 1, còn có thêm phần DOCTYPE declaration. Phần này chứa một reference tới một DTD file có tên Note.dtd. Nội dung của nó:
Nội dung file Note.dtd chỉ ra một số ràng buộc nhất định với file .xml. Ví dụ như mỗi note element phải bao gồm những elements khác bên trong nó: to,from,heading,body hay xác định các elements nào phải thuộc loại nào (ở đây là #PCDATA - parsed character data - hiểu đơn giản là data ở dạng text).
Vậy DTD giúp các file xml thống nhất một standard/format xác định, từ đó dễ dàng hơn trong việc xác định cấu trúc của dữ liệu, đặc biệt khi chuyển file từ nơi này sang nơi khác, người sử dụng có thể sử dụng DTD để verify lại file xml có giống như standard/format mong muốn hay không.
Ngoài DTD ra, thì file xml còn có thể được "definition" bởi một kiểu khác là XML Schema Definition (XSD) - định nghĩa theo lược đồ. Nhưng chỉ có DTD gây ra lỗi XXE Injection.
2.2 DTD Entity
Chúng ta có thể hiểu đơn giản DTD Entity giống như những biến trong lập trình vậy.
DTD Entity cũng có internal và external !
Hãy xem ví dụ về Internal DTD Entity:
Ví dụ về External DTD Entity:
2.3 External Entity
Để xử lý được file xml, mọi ứng dụng đều cần phải có một XML parser (còn được gọi là XML processor) để xử lý file xml và đưa ra output. Khi chúng ta khai báo một entity, parser sẽ tự động thay thế giá trị của entity vào nơi entity được khi báo.
Request:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY bar SYSTEM "file:///c:/boot.ini" >]>
<foo>&bar;</foo>
Response:
[boot loader]
timeout=5
default=multi(0)disk(0)rdisk(1)partition(1)\WINDOWS
[operating systems]
Chúng ta có thể thấy trong phần DOCTYPE declaration, ngoài khai báo những elements , nó khai báo thêm một URI (trong XML thì URI được hiểu là một system identifier) trỏ đến file c:/boot.ini. External entity được đặt tên bar và được chỉ định trả về thông qua <foo>&bar;</foo>
Đến đây thì khái niệm về External Entity đã tương đối rõ ràng. Câu hỏi là nó có thể làm được gì ?
2.3.1 Denial of service
Đây là một kiểu tấn công mang tên Billion laughs attack. Thực tế đây mới chỉ là Internal entity. Ví dụ từ wikipedia:
Gọi entity lol9 với cú pháp &lol9, trông có vẻ vô hại, nhưng từ lol9 đến lol đã là 10^10 lần từ "lol" được gọi đến lần lượt thông qua các entity, tương đương 1.000.000.000 chữ "lol" cần được parser xml xử lý. Điều này khiến over load parser và dẫn đến DoS.
2.3.2 File Disclosure
Bạn có còn nhớ syntax của External DTD Entity ở phía trên?
Syntax:
<!ENTITY name SYSTEM "URI/URL">
Tại đây, nếu hacker khai báo một URI (hay với XML thì được gọi là system identifier) và parser được cấu hình để xử lý các external entities thì có thể dẫn tới những vấn đề rất lớn.
Request:
Response:
2.3.3 SSRF
Thay payload phía trên bằng:
Request:
Response:
2.3.4 Access Control Bypass (Loading Restricted Resources — ví dụ với PHP)
...
Tham khảo thêm tại đây.
3. Ví dụ và kết luận
Mình lấy ví dụ từ một số bài lab của portswigger.net - một công ty nổi tiếng với rất nhiều research, article, software và đặc biệt là các bài labs được tạo ra rất chuyên nghiệp.
Ví dụ về File Disclosure:
Request dùng để kiểm tra số lượng sản phẩm hiện có:
Response:
Chỉnh sửa request:
Và response nhận về là nội dung file ở URI chúng ta định nghĩa ở trên:
Đời không như mơ và cuộc sống cũng không dễ thở. Thực tế để khai thác thành công XXE cần nhiều kỹ thuật hơn là copy - paste những payload như trên. Những kỹ thuật có thể kể đến như Out-of-band XML External Entity (OOB-XXE), Blind XXE... và đặc biệt nếu ứng dụng được config như thế này thì chịu:
Lỗi nằm ở Server-side và ảnh hưởng là rất rõ ràng. Vì vậy nếu ứng dụng của bạn có sử dụng XML hay những Markup Language, ứng dụng khác dựa trên XML để process, gửi nhận dữ liệu... thì hãy chắc chắn rằng chúng không mắc phải lỗ hổng nghiêm trọng này !
4. Tài liệu tham khảo
https://www.w3schools.com/xml/
https://vi.wikipedia.org/wiki/XML
https://www.w3schools.com/xml/xml_dtd.asp
https://portswigger.net/web-security/xxe
https://www.tutorialspoint.com/dtd/dtd_entities.htm
https://www.youtube.com/watch?v=DREgLWZqMWg
https://www.acunetix.com/blog/articles/xml-external-entity-xxe-vulnerabilities/
https://en.wikipedia.org/wiki/Billion_laughs_attack
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE Injection
All rights reserved