XML external entity (XXE) injection
Last updated
Last updated
Chúng ta sẽ xem doc trước khi bước vào thực hành lab.
XML là ngôn ngữ đánh dấu mở rộng, nó được sử dụng rộng rãi, được phát triển để lưu truwxx và truyền dữ liệu. Hiện nay có rất nhiều loại tài liệu sử dụng định dạng XML như rtf, pdf, tệp hình ảnh (svg) hay các file cấu hình.
Cấu trúc XML là các thành phần cơ bản của ngôn ngữ đánh dấu tài liệu XML (Extensible Markup Language). XML được sử dụng để mô tả và trao đổi dữ liệu giữa các ứng dụng khác nhau. XML sử dụng các thẻ để xác định cấu trúc của tài liệu và nội dung của nó.
Các thành phần cơ bản của cấu trúc XML bao gồm:
Khai báo XML: Khai báo XML là một chuỗi định dạng để chỉ ra rằng tài liệu là một tài liệu XML. Khai báo XML phải được đặt ở đầu của tài liệu và có định dạng như sau:
Thẻ: Thẻ là các khối xây dựng chính của tài liệu XML. Chúng được sử dụng để xác định nội dung của tài liệu. Một thẻ bao gồm thẻ mở, thẻ đóng và nội dung nằm giữa chúng. Ví dụ:
Thuộc tính: Thuộc tính được sử dụng để cung cấp thông tin bổ sung về một phần tử. Chúng có thể được sử dụng để xác định các thuộc tính của phần tử hoặc để truyền tải thông tin bổ sung. Thuộc tính có thể được xác định trong thẻ mở của phần tử. Ví dụ:
Chú thích: Chú thích được sử dụng để thêm thông tin giải thích cho tài liệu XML. Chú thích bắt đầu bằng cặp ký tự "<!--". Chú thích không ảnh hưởng đến nội dung của tài liệu. Ví dụ:
Không gian tên: Không gian tên được sử dụng để phân biệt các phần tử có cùng tên nhưng thuộc các không gian tên khác nhau. Không gian tên có thể được xác định trong khai báo XML hoặc trong thẻ mở của phần tử. Ví dụ:
Đây là cấu trúc cơ bản của tài liệu XML, cho phép xác định nội dung và cấu trúc của tài liệu, cũng như thêm thông tin bổ sung về dữ liệu mà nó chứa.
Tham chiếu (References) thường cho phép bạn thêm hoặc bao phần text hoặc phần đánh dấu bổ sung trong một tài liệu XML. Các tham chiếu luôn luôn bắt đầu với biểu tượng “&” , đây là ký tự dành riêng và kết thúc với ký tự “;”. XML có hai kiểu tham chiếu:
Tham chiếu thực thể (Entity Reference): Một tham chiếu thực thể chứa một tên giữa dấu tách mở và dấu tách đóng. Ví dụ: & có amp là tên. Tên tham chiếu tới một chuỗi văn bản hoặc đánh dấu đã được định nghĩa trước.
Tham chiếu ký tự (Character Reference): Chứa các tham chiếu, ví dụ A, chứa một dấu băm (#) được theo sau bởi một số. Số này luôn luôn tham chiếu tới mã hóa Unicode của ký tự. Trong ví dụ này, 65 tham chiếu tới chữ cái “A”.
XML Document Type Definition (DTD) là một tập tin văn bản định nghĩa cấu trúc, các phần tử và thuộc tính của một tài liệu XML. DTD được sử dụng để xác định cách mà các phần tử và thuộc tính phải được sử dụng trong tài liệu XML, cũng như các quy tắc mà phải tuân thủ khi tạo tài liệu XML.
Ví dụ, đoạn mã XML sau đây sử dụng một DTD để định nghĩa cấu trúc của một tài liệu XML đơn giản:
Trong ví dụ này, DTD được định nghĩa bên trong khai báo DOCTYPE. Nó định nghĩa rằng tài liệu XML phải chứa ba phần tử: "title", "author" và "content", theo thứ tự như vậy. Mỗi phần tử này chỉ có thể chứa dữ liệu văn bản, được định nghĩa bằng cách sử dụng ký tự đại diện #PCDATA.
Để 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:
Response:
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>
Với XXE attack, tôi sẽ có thể gặp các dạng phổ biến sau:
Khai thác XXE để trích xuất file: Định nghĩa external entity chứa nội dung của 1 file và trả về trong response;
Khai thác XXE để thực thi SSRF attacks: Định nghĩa external entity dựa vào URL đến back-end system;
Khai thác blind XXE để hốt dữ liệu theo kiểu out-of-band: Truyền tải dữ liệu nhạy cảm từ server đến hệ thống mà attacker có thể kiểm soát;
Khai thác blind XXE để trích xuất dữ liệu thông qua thông báo lỗi: Làm phát sinh parsing error message chứa thông tin nhạy cảm.
Hầu như tất cả các lỗ hổng XXE phát sinh do thư viện phân tích cú pháp XML của ứng dụng hỗ trợ các tính năng XML nguy hiểm tiềm ẩn mà ứng dụng không cần hoặc không có ý định sử dụng. Cách dễ nhất và hiệu quả nhất để ngăn chặn các cuộc tấn công của XXE là tắt các tính năng đó. Nói chung, chỉ cần vô hiệu hóa độ phân giải của các thực thể bên ngoài và vô hiệu hóa hỗ trợ cho XInclude là đủ. Điều này thường có thể được thực hiện thông qua các tùy chọn cấu hình hoặc bằng cách ghi đè hành vi mặc định theo chương trình. Tham khảo tài liệu về thư viện phân tích cú pháp XML hoặc API của bạn để biết chi tiết về cách tắt các chức năng không cần thiết.
Chúng ta để khi ý khi truy cập trang web có một nút check xem số lượng sản phẩm còn lại là bao nhiêu.
Dùng burp suite để check thì chúng ta sẽ có req và res như trên. Và chúng ta tự đặt ra giải thuyết rằng nếu thêm một external entity vào giữa XML declaration và stock element.
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
Sau đó thay 1 thành &xxe, kiểu như này:
Solve:
Như tiêu đề ở đây chúng ta cần phải khai thác lỗ hổng XXE thông qua SSRF, nếu chưa biết tới ssrf thì có thể xem ở bài gần nhất trong mục server-side.
Chúng ta sẽ vẫn dùng burp suite để bắt các request:
Mỗi lần req thì mỗi nó sẽ báo lỗi kèm theo endpoint mà chúng ta cần. Cho tới khi lấy được full dữ liệu tại endpoint cuối.
XInclude là một tiêu chuẩn của W3C được sử dụng trong tài liệu XML để tham chiếu đến các phần khác của tài liệu hoặc các tài liệu khác và chèn chúng vào tài liệu hiện tại. XInclude cho phép tách tài liệu thành các phần nhỏ hơn để quản lý và tái sử dụng nó trong các tài liệu khác.
XInclude được định nghĩa bằng các phần tử và thuộc tính mới, bao gồm:
<xi:include> phần tử: được sử dụng để tham chiếu đến tài liệu hoặc phần của tài liệu khác và chèn chúng vào tài liệu hiện tại. Nó có thể có một số thuộc tính, bao gồm "href" để chỉ định đường dẫn đến tài liệu được chèn, "parse" để chỉ định cách tài liệu được phân tích, và "xpointer" để chỉ định phần của tài liệu được chèn.
<xi:fallback> phần tử: được sử dụng để định nghĩa một phần tử dự phòng nếu tài liệu không hỗ trợ XInclude.
Ví dụ, đoạn mã sau đây minh họa cách sử dụng XInclude để chèn một tài liệu XML vào tài liệu hiện tại:
Trong đó, phần tử <xi:include> được sử dụng để chèn tài liệu XML được chỉ định trong thuộc tính "href" vào tài liệu hiện tại. Thuộc tính "parse" được sử dụng để chỉ định rằng tài liệu được chèn cũng là một tài liệu XML.
Với lab tiếp theo chúng ta thấy được lúc này ở req truyền đi dữ liệu với tham số chứ không phải xml. Tự hỏi rằng có thể chèn được đoạn này vào productId không?
Đoạn mã XML trên chứa một phần tử XInclude tham chiếu đến một tài nguyên bên ngoài bằng cách sử dụng một địa chỉ file URI. Cụ thể, phần tử "xi:include" xác định rằng nó muốn bao gồm nội dung của một tệp tin nằm tại "/etc/passwd" trên hệ thống tệp tin cục bộ. Thuộc tính "parse" được đặt thành "text", cho biết rằng tệp được bao gồm sẽ được xử lý như văn bản thuần túy chứ không phải là một tài liệu XML.
Mỗi mục của bài này đều có để lại cmt kèm theo tải một file avatar, chúng ta sẽ khai thác lỗ hổng XXE qua upload
Trước hết chúng ta cần tải một file ảnh định dạng svg về để up lên.
Sau khi upload sẽ như này, sau đó vào burp suite và chuyển sang chế độ repeater và chỉ sửa đoạn svg thành như này:
Bài này cũng giống các bài khác nhưng như tiêu đề thì chúng ta không nhận được kết quả. Và vấn đề ở đây thử xem nó có tương tác với một domain bên ngoài không?
Tiếp theo chúng ta sẽ khai thác XXE thông qua XML parameter entities. Nếu chưa hiểu nó là gì thì đại khái:
XML parameter entities là một loại thực thể trong XML được sử dụng để định nghĩa các tham số có thể được sử dụng trong nội dung của tài liệu XML.
Một parameter entity được khai báo bằng cách sử dụng cặp ký tự %
và ;
. Để sử dụng một parameter entity, bạn cần đặt tên của nó giữa cặp dấu &
và ;
.
Ví dụ, ta có thể định nghĩa một parameter entity companyname
như sau:
Sau đó, ta có thể sử dụng parameter entity này trong nội dung của tài liệu XML như sau:
Với lab này thì cách khai thác XXE với entity thông thường thì không thể vậy sử dụng parameter entity.
Ở hai lab trên Blind XXE thì nó hơi nửa nạc nửa mỡ chưa khai thác lấy dữ liệu được gì, thì trong lab này chúng ta sẽ leak data máy chủ ra và gửi về server của chúng ta bằng cách tạo một file DTD.
Tận dụng lỗ hổng XXE mù để lấy dữ liệu ra khỏi hệ thống thông qua kỹ thuật out-of-band Phát hiện một lỗ hổng XXE mù thông qua kỹ thuật out-of-band là điều quan trọng, nhưng nó chưa thực sự cho thấy cách lỗ hổng có thể bị khai thác. Điều mà kẻ tấn công thực sự muốn đạt được là lấy ra dữ liệu nhạy cảm. Điều này có thể được thực hiện thông qua một lỗ hổng XXE mù, nhưng nó đòi hỏi kẻ tấn công phải lưu trữ DTD độc hại trên một hệ thống mà họ kiểm soát, sau đó triệu gọi DTD ngoại vi từ XXE payload in-band.
Một ví dụ về DTD độc hại để lấy nội dung của file /etc/passwd như sau:
DTD này thực hiện các bước sau:
Định nghĩa một thực thể tham số XML có tên là file, chứa nội dung của file /etc/passwd.
Định nghĩa một thực thể tham số XML có tên là eval, chứa một khai báo động của thực thể tham số XML khác có tên exfiltrate. Thực thể exfiltrate sẽ được đánh giá bằng cách thực hiện một yêu cầu HTTP đến máy chủ web của kẻ tấn công chứa giá trị của thực thể file trong chuỗi truy vấn URL.
Sử dụng thực thể eval, điều này khiến cho khai báo động của thực thể exfiltrate được thực hiện.
Sử dụng thực thể exfiltrate, để giá trị của nó được đánh giá bằng cách yêu cầu URL được chỉ định.
Kẻ tấn công phải lưu trữ DTD độc hại trên một hệ thống mà họ kiểm soát, thường là tải nó lên máy chủ web của mình. Ví dụ, kẻ tấn công có thể phục vụ DTD độc hại tại URL sau:
http://web-attacker.com/malicious.dtd
Cuối cùng, kẻ tấn công phải gửi XXE payload sau đến ứng dụng dễ bị tấn công:
Payload XXE này khai báo một thực thể tham số XML có tên xxe và sau đó sử dụng thực thể trong DTD. Điều này sẽ khiến trình phân tích XML tìm nạp DTD ngoại vi từ máy chủ của kẻ tấn công và diễn giải nó ngay lập tức. Các bước được định nghĩa trong DTD độc hại sau đó được thực hiện, và file /etc/passwd được truyền đến máy chủ của kẻ tấn công.
Lưu ý
Kỹ thuật này có thể không hoạt động với một số nội dung file, bao gồm các ký tự xuống dòng trong file /etc/passwd. Điều này là do một số trình phân tích XML tìm nạp URL trong định nghĩa thực thể ngoại vi bằng API kiểm tra các kýtự được phép xuất hiện trong URL. Trong tình huống này, có thể sử dụng giao thức FTP thay vì HTTP. Đôi khi, sẽ không thể lấy dữ liệu chứa các ký tự xuống dòng, và do đó một file như /etc/hostname có thể được mục tiêu hướng tới thay thế.
Bây giờ như mình giải thích ở trên sẽ tạo một DTD với nội dung file như trên.
Sau đó gửi lại payload như cũ kèm endpoint exploit.dtd để exploit server.
Một cách tiếp cận khác để khai thác XXE mù là kích hoạt một lỗi phân tích XML trong đó thông báo lỗi chứa dữ liệu nhạy cảm mà bạn muốn lấy. Điều này sẽ hiệu quả nếu ứng dụng trả về thông báo lỗi kết quả trong phản hồi của nó.
Bạn có thể kích hoạt thông báo lỗi phân tích XML chứa nội dung của tệp /etc/passwd bằng cách sử dụng một DTD bên ngoài độc hại như sau:
DTD này thực hiện các bước sau:
Xác định XML parameter entity được gọi là file, chứa nội dung của tệp /etc/passwd.
Xác định XML parameter entity được gọi là eval, chứa một khai báo động của một XML parameter entity khác được gọi là error. Entity lỗi sẽ được xem xét bằng cách tải một tệp không tồn tại có tên chứa giá trị của file
entity.
Sử dụngeval
entity, điều này làm cho khai báo động của entity lỗi được thực hiện.
Sử dụng entity lỗi, để giá trị của nó được đánh giá bằng cách cố gắng tải tệp không tồn tại, dẫn đến thông báo lỗi chứa tên của tệp không tồn tại, đó là nội dung của tệp /etc/passwd.
Gọi DTD bên ngoài độc hại sẽ dẫn đến thông báo lỗi như sau:
Khi server của nạn nhân khóa chặt out-of-band interaction nhằm chống lại phương án trích xuất dữ liệu thì chúng ta có thể sử dụng external DTD ở local.
Chúng ta sẽ đi vào lab để hiểu rõ hơn. Vẫn như cũ lab vẫn cho chúng ta check số liệu.
Đúng ta sẽ có đoạn paylaod sau:
Entity %local_dtd được định nghĩa để tham chiếu đến DTD mặc định của DocBook XML, được lưu trữ tại đường dẫn file:///usr/share/yelp/dtd/docbookx.dtd.
Entity %ISOamso chứa mã HTML ISOamso, được sử dụng để định nghĩa các ký tự toán học. Tuy nhiên, nó cũng chứa hai entity khác, % file và % eval, được sử dụng để thực hiện một cuộc tấn công XML External Entity (XXE).
Entity % file được định nghĩa để tham chiếu đến tập tin /etc/passwd trên máy chủ.
Entity % eval được định nghĩa để định nghĩa một entity mới có tên là % error, được sử dụng để thực hiện cuộc tấn công XXE. Thực thể này sẽ định nghĩa một hàm lỗi mới và thực hiện nó.
Ở đây đường dẫn làm sao biết được thì ví dụ Yelp Help Browser cho GNOME trên Linux thì đưòng dẫn sẽ “usr/share/yelp/dtd/docbookx.dtd
Có thể check bằng payload này: [Nếu sinh lỗi thì đường dẫn sai]
Cảm ơn mn đã đọc bài!! Hẹn mn các bài research khác....
java.io.FileNotFoundException: /nonexistent/root0:0:root:/root:/bin/bash daemon1:1:daemon:/usr/sbin:/usr/sbin/nologin bin2:2:bin:/bin:/usr/sbin/nologin