NỘI DUNG
Tiếp theo nội dung Penetration Testing Step 3 – Lại tìm và diệt mục tiêu nhưng với Stored Cross-Site Scripting, kỳ này tôi sẽ tiếp tục mò sang đối tượng cuối cùng của dòng họ XSS là DOM based Cross-Site Scripting. Thực tế câu chuyện với DOM XSS khá lê thê nên tôi sẽ phải chia ra nhiều kỳ. Ngoài ra, cũng tương tự như các kỳ trước, tôi cũng sẽ nhờ cậy vào mấy bài lab của ông PortSwigger để đỡ phải hì hục dàn cảnh.
#1. DOM XSS liệu có dễ ăn?
Trả lời nhanh cho câu hỏi “DOM XSS liệu có dễ ăn?” là “Không”. Bạn cần lưu ý những phần demo bên dưới được cố tình thiết kế cho bạn “dễ ăn” để minh họa chứ thực tế ít khi có chuyện mục tiêu hớ hênh như thế đâu nhé.
Với phương án trả lời dông dài, như tôi đã giới thiệu trong nội dung Penetration Testing Step 3 – Cross-Site Scripting – XSS là cái vẹo gì?, DOM-based XSS hay DOM XSS là dạng lỗ hổng phát sinh khi ứng dụng chứa một số client-side JavaScript xử lý ẩu dữ liệu từ các nguồn tào lao và đám dữ liệu này sau đó lại được ghi vào DOM.
Cũng giống như Reflected/Stored XSS, bạn cũng có thể chấm mút nhanh DOM XSS với Vulnerability Scanner của Burp Suite. Sau đó, nếu cần thiết, bạn chơi tiếp kiểu thủ công mỹ nghệ nhờ sự trợ giúp của developer tool trên các trình duyệt để kiểm tra xác nhận.
Về nguyên tắc, muốn “ăn” được DOM XSS thì ứng dụng phải có 1 con đường để dữ liệu chạy từ đầu vào đến đầu ra. Thực tế, các đầu vào và đầu ra khác nhau có thể tương tác với nhau nên công việc sẽ phức tạp hơn. Ngoài ra, các script có thể thực hiện phần validation cũng như các thao tác xử lý khác cũng làm quá trình “dò đường” mệt mỏi hơn.
Tôi sẽ tóm lược nguyên tắc xơ múi DOM XSS với 2 dạng đầu ra phổ biến là HTML và Javascript execution (tức là chạy code Javascript). Vì đây là phần nguyên tắc nên thông tin có thể hơi mơ hồ. Nếu bạn thấy chưa rõ thì cứ kệ mịa nó. Tí sang phần demo rồi bạn quay lại chiêm nghiệm tiếp cũng được.
#1.1 Nguyên tắc xơ múi DOM XSS với các đầu ra HTML
Với dạng này, bạn có thể đút các alphanumeric string ngẫu nhiên vô các vị trí đầu vào ví dụ như location.search sau đó sử dụng developer tool đào bới cái HTML để coi cái string đút vô sẽ xuất hiện ở đâu. Với từng vị trí tìm được, bạn cũng sẽ cần xác định context – ngữ cảnh để mông má lại thông tin đầu vào để thăm dò cách hệ thống xử lý thông tin.
Lưu ý: Với browser (ví dụ như Chrome, Firefox) có triển URL-encode các đầu vào trước khi xử lý, khả năng âm mưu XSS attack của bạn sẽ tan thành mây khói.
#1.2 Nguyên tắc xơ múi DOM XSS với các đầu ra JavaScript execution
Dạng này tương đối khó hơn và khi bạn đút thông tin vào không nhất thiết phải có dữ liệu ra DOM. Với loại này, bạn sẽ cần đến trợ giúp của JavaScript debugger để xác định xem với cái thông tin đầu vào thì bạn có được húp được gì không. Và với từng đầu vào tiềm năng ví dụ như location, bạn sẽ cần xác định các trường hợp mà Javascript có tham chiếu đến tương ứng.
Tiếp đến, bạn có thể dùng JavaScript debugger tạo break point (đại khái là điểm cho code dừng chạy để bạn đánh giá cách xử lý dữ liệu) và nghiên cứu cách các giá trị đầu vào được xử lý. Trường hợp đầu vào được gán vào variable – biến khác, bạn sẽ cần tiếp tục sử dụng search function để theo dõi quá trình xử lý đám này xem nó có dẫn đến đầu ra nào không. Nếu có, bạn sẽ lại tiếp tục dùng debugger để nghiên cứu giá trị của đám variable trước khi được đẩy ra. Dựa vào đây, bạn sẽ điều chỉnh thông tin đầu vào để tìm phương án triển khai thành công mưu đồ XSS attack.
Lưu ý: Burp Suite embedded browser có built-in DOM invader extension hỗ trợ quá trình cày cuốc đầy mệt nhọc này
#2. Demo các đường chấm mút với DOM XSS
Trong quá trình “ăn” DOM-based vulnerabilities, bạn có thể triển với nhiều dạng đầu ra khác nhau. Một số đám đầu ra phổ biến cần đặc biệt lưu ý bao gồm:
- write()
- writeln()
- domain
- innerHTML
- outerHTML
- insertAdjacentHTML
- onevent
Tùy thuộc vào dạng đầu ra, bCạn sẽ cần nghiên cứu các phương án xử lý phù hợp. Ví dụ document.write() có thể múc với các thành phần script nên bạn có thể dùng các payload kiểu như:
document.write('... <script>alert(document.domain)</script> ...');
#2.1 DOM XSS với đầu vào location.search và đầu ra document.write
Nháy DOM XSS đầu tiên tôi quất ứng với trường hợp đầu vào là location.search và đầu ra là document.write. Cụ thể, với document.write function của JavaScript, tôi sẽ thử gọi nó thông qua việc nhập liệu alphanumeric string vớ vẩn vào location.search như sau.
Sau khi nhập liệu và search, tôi thử Inspect con hàng này để coi ruột gan nó ra sao.
Nếu bạn rảnh rỗi thì có thể ngồi soi bằng mắt. Còn nếu bận thì có thể dùng chức năng tìm kiếm cho nhanh. Ví dụ tôi tìm cái string vớ vẩn đã nhập liệu vào ở trên và quan sát được như sau.
Như bạn thấy ở trên, cái input tôi đút vào ở trên đã chui tọt vào img src atttribute. Do vậy, bạn có thể mông má lại search string để thử đâm thọc vô phần img attribute như sau.
Và sau khi bấm search nếu bạn thấy kết quả như sau thì mưu đồ của bạn đã thành công như mong đợi.
Lưu ý:
- SVG là viết tắt của Scalable Vector Graphics, dùng để xác định Web Graphics (các nội dung đồ họa cho Web). <svg> là HTML element đóng vai trò làm container cho SVG graphics;
- onload event sẽ xuất hiện khi object (ví dụ cái svg) được load.
#2.2 DOM XSS với đầu vào location.search nằm trong select element và đầu ra document.write
Rồi, giờ tôi tiếp tục với ví dụ cho trường hợp đầu vào location.search nằm trong select element và đầu ra là document.write. Tương tự như phần trước, document.write function cũng sẽ được gọi khi tôi đút dữ liệu vào location.search. Tuy nhiên ở đây có một điểm khác là dữ liệu sẽ được bao bọc bởi select element. Cụ thể, từ giao diện product page, tôi chọn đại một item.
Sau đó tôi cũng chuột phải để Inspect mục tiêu và tìm kiếm một nhân vật đặc biệt là storeId. Như bạn thấy ở cái JavaScript thơm ngon bên dưới, con hàng storeId sẽ được bốc từ location.search rồi đẩy qua document.write để tạo ra một tùy chọn mới trong select element (tương ứng cái Check stock function đề cập trong phần tiếp theo).
Ở đây, bạn có thể thử đút cái storeId query parameter vô URL với một cái alphanumeric string và chạy request để thăm dò dư luận. Và như quan sát bên dưới, cái string này nó sẽ chui tọt vô cái drop-down list tương ứng với các selected element rồi ngồi chung mâm với đám dữ liệu có sẵn của mục tiêu (đám London, Paris, Milan).
Đến đây thì bạn không thể không chọc ngoáy thử với các XSS payload tương ứng cho cái storedID parameter cho đến khi mục tiêu phọt ra cái pop up báo hiệu tin chiến thắng cho bạn. Một ví dụ chọc ngoáy thành công như sau:
Lưu ý:
- %20 là dạng encoding tương ứng với space character (khoảng trắng);
- src=1 là phép gán vớ vẩn để làm phát sinh lỗi từ đó khởi chạy onerror event.
#2.3 DOM XSS với đầu vào location.search và đầu ra innerHTML
Tiếp tục chuyển sang phần thử nghiệm với đầu vào location.search và đầu ra là innerHTML. Với phần này, dữ liệu từ location.search sẽ được đẩy vào để thay đổi nội dung của một div element cụ thể thông qua innerHTML assignment. Bạn có thể thử đập phát ăn ngay bằng cách đút dữ liệu vô search box như sau rồi bấm Search.
Như bạn thấy ở trên việc gán src=1 là một hành động sai trái cần bị lên án trong bối cảnh thông thường. Tuy nhiên, với ngữ cảnh đang chiến với DOM XSS, hành động thô bỉ này lại sinh ra lỗi làm ngòi nổ để bạn kích hoạt onerror event từ đó triển khai các mưu đồ thâm độc tiếp theo (ở đây là ví dụ alert(1) cho nhanh gọn). Và nếu mọi chuyện êm đẹp thì bạn có thể thu lượm kết quả ngay như sau.
Rồi thôi, đến đây tôi xin tạm dừng nội dung demo với DOM XSS. Như giới thiệu ở đầu bài, phần này còn khá nhiều nội dung hay ho khác. Tôi sẽ tiếp tục chém gió tiếp trong các kỳ tiếp theo.
1 thought on “Penetration Testing Step 3 – Các đường chấm mút với DOM based Cross-Site Scripting (Part 1)”