Clickjacking, một tập hợp con của chỉnh sửa giao diện người dùng, là một kỹ thuật độc hại, theo đó người dùng web bị lừa để tương tác (trong hầu hết các trường hợp bằng cách nhấp vào) với thứ gì đó khác với thứ mà người dùng tin rằng họ đang tương tác. Loại tấn công này, đơn lẻ hoặc kết hợp với các cuộc tấn công khác, có khả năng gửi các lệnh trái phép hoặc tiết lộ thông tin bí mật trong khi nạn nhân đang tương tác với các trang web dường như vô hại. Thuật ngữ clickjacking được Jeremiah Grossman và Robert Hansen đặt ra vào năm 2008.
Một cuộc tấn công sử dụng clickjacking sử dụng các chức năng của HTML và JavaScript để thao túng máy client thực hiện hành động ngoài ý muốn, như tự ý xuất hiện popup hay click vào button ẩn. Đây là vấn đề bảo mật ảnh hưởng phụ thuộc nhiều web browser và nền tảng khác.
Để thực hiện cuộc tấn công này, kẻ tấn công tạo ra một trang web dường như vô hại để tải ứng dụng mục tiêu thông qua việc sử dụng một inline frame (được che giấu bằng mã CSS). Khi điều này được thực hiện, kẻ tấn công có thể khiến nạn nhân tương tác với trang web bằng các phương tiện khác (ví dụ: thông qua kỹ thuật xã hội). Giống như các cuộc tấn công khác, điều kiện tiên quyết chung là nạn nhân được xác thực dựa trên trang web mục tiêu của kẻ tấn công.
Hình minh họa inline frame của Clickjacking
Nạn nhân lướt trang web của kẻ tấn công với ý định tương tác với giao diện người dùng hiển thị, nhưng lại vô tình thực hiện các hành động trên trang ẩn. Sử dụng trang ẩn, kẻ tấn công có thể đánh lừa người dùng thực hiện các hành động mà họ không bao giờ có ý định thực hiện thông qua việc định vị các phần tử ẩn trong trang web.
Sức mạnh của phương pháp này là các hành động được thực hiện bởi nạn nhân được bắt nguồn từ trang web đích ẩn những xác thực. Do đó, một số biện pháp bảo vệ chống CSRF được các nhà phát triển triển khai để bảo vệ trang web khỏi các cuộc tấn công CSRF có thể bị bỏ qua.
Mục tiêu kiểm tra Clickjacking
Mục tiêu của quá trình kiểm tra Clickjacking không chỉ là hiểu rõ các biện pháp an ninh tại chỗ được triển khai mà còn đánh giá mức độ nghiêm ngặt của chúng và xác định xem chúng có thể vượt qua được hay không. Dưới đây là các khía cạnh quan trọng cần được xem xét trong quá trình kiểm tra Clickjacking:
- Hiểu Biện Pháp An Ninh Tại Chỗ:
- Xác định và hiểu rõ các biện pháp an ninh tại chỗ được triển khai để ngăn chặn Clickjacking. Các biện pháp này có thể bao gồm sử dụng HTTP header như X-Frame-Options để kiểm soát việc nhúng trang web vào một iframe.
- Kiểm Tra Mức Độ Nghiêm Ngặt:
- Đánh giá mức độ nghiêm ngặt của các biện pháp bảo mật hiện tại. Xác định cách mà chúng ảnh hưởng đến khả năng của attacker trong việc thực hiện Clickjacking và xâm phạm quyền riêng tư người dùng.
- Kiểm Tra Tương Thích Với Trình Duyệt:
- Đảm bảo rằng các biện pháp Clickjacking là tương thích với nhiều trình duyệt khác nhau. Kiểm tra xem chúng có được triển khai đồng đều trên các trình duyệt phổ biến như Chrome, Firefox, Safari, và Edge không.
- Phân Tích Tác Động Đến Trải Nghiệm Người Dùng:
- Đánh giá cách mà các biện pháp Clickjacking ảnh hưởng đến trải nghiệm người dùng. Chắc chắn rằng chúng không tạo ra những rắc rối không mong muốn, như làm giảm khả năng tương tác hoặc hiệu suất của trang web.
- Kiểm Tra Khả Năng Vượt Qua:
- Thực hiện kiểm tra cố gắng vượt qua các biện pháp Clickjacking hiện tại. Điều này bao gồm việc tìm kiếm các kỹ thuật tấn công mới và sáng tạo mà có thể bypass các biện pháp bảo mật truyền thống.
- Tối Ưu Hóa Cấu Hình An Ninh:
- Đề xuất và kiểm tra tối ưu hóa cấu hình an ninh để đảm bảo rằng Clickjacking không thể tận dụng được bất kỳ điểm yếu nào trong hệ thống. Điều này có thể bao gồm việc thiết lập chính sách CSP (Content Security Policy) và cập nhật các cơ sở dữ liệu điều khiển truy cập.
- Kiểm Tra Sự Tương Thích Với Các Kỹ Thuật Khác:
- Đảm bảo rằng biện pháp Clickjacking không gây xung đột với các biện pháp bảo mật khác đang được triển khai trong hệ thống, như cơ chế chống XSS (Cross-Site Scripting) và CSRF (Cross-Site Request Forgery).
- Giả Lập Tình Huống Tấn Công:
- Sử dụng kỹ thuật giả lập để tái tạo tình huống Clickjacking và kiểm tra cách hệ thống phản ứng. Điều này giúp xác định được các lỗ hổng và điều chỉnh biện pháp an ninh để nâng cao khả năng chống lại tấn công.
Bằng cách tiếp cận toàn diện, quá trình kiểm tra Clickjacking không chỉ tập trung vào việc hiểu các biện pháp hiện tại mà còn đánh giá tính hiệu quả và khả năng chống lại những mối đe dọa tiềm ẩn.
Làm thế nào để kiểm tra Clickjacking
Kiểu tấn công này nhắm đến sự thiết kế giao diện trên các máy client, ngay cả khi CSRF đã được phòng chống.
Người kiểm tra có thể điều tra xem một trang mục tiêu có thể được tải trong một inline frame hay không bằng cách tạo một trang web đơn giản bao gồm một khung chứa trang web mục tiêu. Ví dụ về mã HTML để tạo trang web thử nghiệm này được hiển thị trong đoạn mã sau:
<html> <head> <title>Clickjack test page</title> </head> <body> <iframe src="http://www.target.site" width="500" height="500"></iframe> </body> </html>
Nếu trang http://www.target.site được tải thành công vào khung, thì trang đó rất dễ bị tấn công và không có kiểu bảo vệ chống lại các cuộc tấn công bằng clickjacking.
Bỏ qua Bypass Clickjacking
Nếu trang http://www.target.site không xuất hiện trong inline frame, trang web có thể có một số hình thức bảo vệ chống lại việc kích chuột. Điều quan trọng cần lưu ý là đây không phải là sự đảm bảo rằng trang hoàn toàn không bị tấn công bằng cách ClickJacking.
Các phương pháp bảo vệ trang web khỏi bị kích chuột có thể được chia thành một số cơ chế chính. Có thể bỏ qua các phương pháp này trong một số trường hợp bằng cách sử dụng các cách giải quyết cụ thể.
Bảo vệ phía máy khách: Frame Busting
Phương pháp phía máy khách phổ biến nhất, đã được phát triển để bảo vệ trang web khỏi bị clickjacking, được gọi là Frame Busting và nó bao gồm một tập lệnh trong mỗi trang không được đóng khung. Mục đích của kỹ thuật này là ngăn một trang web hoạt động khi nó được tải bên trong khung.
Cấu trúc của mã chặn khung thường bao gồm “câu lệnh điều kiện” và câu lệnh “hành động phản tác dụng”. Đối với loại bảo vệ này, có một số cách giải quyết được đặt dưới tên là “Bust frame busting”. Một số kỹ thuật này dành riêng cho từng trình duyệt trong khi những kỹ thuật khác hoạt động trên các trình duyệt.
Phiên bản trang web di động
Phiên bản dành cho thiết bị di động của trang web thường nhỏ hơn và nhanh hơn phiên bản dành cho máy tính để bàn và chúng phải ít phức tạp hơn ứng dụng chính. Các biến thể di động thường ít bảo vệ hơn vì có giả định sai lầm rằng kẻ tấn công không thể tấn công một ứng dụng bằng điện thoại thông minh. Điều này về cơ bản là sai, vì kẻ tấn công có thể giả mạo nguồn gốc thực do trình duyệt web cung cấp, để nạn nhân không phải di động có thể truy cập ứng dụng dành cho người dùng di động. Từ giả định này, trong một số trường hợp, không cần thiết phải sử dụng các kỹ thuật để tránh evade frame busting khi có các lựa chọn thay thế không được bảo vệ, cho phép sử dụng các vectơ tấn công giống nhau.
Double Framing
Một số kỹ thuật frame busting cố gắng phá vỡ khung bằng cách gán giá trị chuyển đến thuộc tính parent.location trong câu lệnh “counter-action”.
Những hành động như vậy, ví dụ:
- self.parent.location = document.location
- parent.location.href = self.location
- parent.location = self.location
Phương pháp này hoạt động tốt cho đến khi trang đích được đóng Frame bởi một trang duy nhất. Tuy nhiên, nếu kẻ tấn công bao bọc trang web mục tiêu trong một frame được lồng trong một frame khác (khung kép), thì việc cố gắng truy cập vào parent.location sẽ trở thành vi phạm bảo mật trong tất cả các trình duyệt phổ biến do chính sách điều hướng frame con. Vi phạm bảo mật này vô hiệu hóa điều hướng hành động chống lại.
Mã chặn khung trang đích (example.org):
if(top.location!=self.locaton) { parent.location = self.location; }
Khung trên cùng của kẻ tấn công (fictitious2.html):
<iframe src="fictitious.html">
Khung phụ giả mạo của kẻ tấn công (fictitious.html):
<iframe src="http://example.org">
Tắt JavaScript
Vì loại bảo vệ phía máy khách này dựa vào mã chặn khung JavaScript, nếu nạn nhân đã tắt JavaScript hoặc kẻ tấn công có thể vô hiệu hóa mã JavaScript, trang web sẽ không có bất kỳ cơ chế bảo vệ nào chống lại clickjacking.
Có ba kỹ thuật hủy kích hoạt có thể được sử dụng với khung:
Khung bị hạn chế với Internet Explorer: Bắt đầu từ Internet Explorer 6, khung có thể có thuộc tính “security”, nếu nó được đặt thành giá trị “limited”, đảm bảo rằng mã JavaScript, điều khiển ActiveX và chuyển hướng lại các trang web khác. không hoạt động trong Frame.
Ví dụ:
<iframe src="http://example.org" security="restricted"></iframe>
Thuộc tính hộp cát: với HTML5, có một thuộc tính mới được gọi là “hộp cát”. Nó cho phép một loạt các hạn chế đối với nội dung được tải vào iframe. Tại thời điểm này, thuộc tính này chỉ tương thích với Chrome và Safari.
Ví dụ:
<iframe src="http://example.org" sandbox></iframe>
Chế độ thiết kế: Paul Stone đã chỉ ra một vấn đề bảo mật liên quan đến “designMode” có thể được bật trong trang đóng khung (thông qua document.designMode), vô hiệu hóa JavaScript trong khung trên và khung phụ. Chế độ thiết kế hiện được triển khai trên Firefox và IE8.
Sự kiện OnBeforeUnload
Sự kiện onBeforeUnload có thể được sử dụng để tránh mã chặn frame. Sự kiện này được gọi khi mã chặn Frame muốn phá hủy iframe bằng cách tải URL trong toàn bộ trang web chứ không chỉ trong iframe. Hàm xử lý trả về một chuỗi được nhắc người dùng yêu cầu xác nhận xem anh ta có muốn rời khỏi trang hay không. Khi chuỗi này được hiển thị cho người dùng có khả năng hủy điều hướng, đánh bại nỗ lực chặn khung của mục tiêu.
Kẻ tấn công có thể sử dụng cuộc tấn công này bằng cách đăng ký một sự kiện dỡ hàng trên trang đầu bằng cách sử dụng mã ví dụ sau:
<h1>www.fictitious.site</h1> <script> window.onbeforeunload = function() { return " Do you want to leave fictitious.site?"; } </script> <iframe src="http://example.org">
Kỹ thuật trước yêu cầu sự tương tác của người dùng nhưng, kết quả tương tự, có thể đạt được mà không cần người dùng nhắc nhở. Để làm điều này, kẻ tấn công phải tự động hủy yêu cầu điều hướng đến trong trình xử lý sự kiện onBeforeUnload bằng cách gửi liên tục (ví dụ: mỗi mili giây) một yêu cầu điều hướng đến một trang web phản hồi với tiêu đề “HTTP / 1.1 204 No Content”.
Vì với phản hồi này, trình duyệt sẽ không làm gì cả, kết quả của hoạt động này là việc xả luồng yêu cầu, làm cho nỗ lực chặn khung ban đầu trở nên vô ích.
Sau một mã ví dụ:
204:
<?php header("HTTP/1.1 204 No Content"); ?>
Trang của kẻ tấn công:
<script> var prevent_bust = 0; window.onbeforeunload = function() { prevent_bust++; }; setInterval( function() { if (prevent_bust > 0) { prevent_bust -= 2; window.top.location = "http://attacker.site/204.php"; } }, 1); </script> <iframe src="http://example.org">
Bộ lọc XSS
Bắt đầu từ Google Chrome 4.0 và từ IE8, đã có các bộ lọc XSS được giới thiệu để bảo vệ người dùng khỏi các cuộc tấn công XSS được phản ánh. Nava và Lindsay đã quan sát thấy rằng những loại bộ lọc này có thể được sử dụng để hủy kích hoạt mã chặn khung bằng cách giả mạo nó là mã độc hại.
Bộ lọc XSS của IE8: bộ lọc này có khả năng hiển thị tất cả các tham số của từng yêu cầu và phản hồi đi qua trình duyệt web và nó so sánh chúng với một tập hợp các biểu thức chính quy để tìm kiếm các lần thử XSS được phản ánh. Khi bộ lọc xác định các cuộc tấn công XSS có thể xảy ra; nó vô hiệu hóa tất cả các tập lệnh nội tuyến trong trang, bao gồm các tập lệnh chặn khung (điều tương tự cũng có thể được thực hiện với các tập lệnh bên ngoài). Vì lý do này, kẻ tấn công có thể tạo ra dương tính giả bằng cách chèn phần đầu của tập lệnh chặn khung vào các tham số của yêu cầu.
Ví dụ: Nhắm mục tiêu mã chặn khung trang web:
<script> if ( top != self ) { top.location=self.location; } </script>
Mã kẻ tấn công:
<iframe src="http://example.org/?param=<script>if">
Bộ lọc Chrome 4.0 XSSuditor: Nó có một chút hành vi khác nhau
của chúng tôi so với bộ lọc XSS của IE8, trên thực tế với bộ lọc này, kẻ tấn công có thể hủy kích hoạt một “tập lệnh” bằng cách chuyển mã của nó trong một tham số yêu cầu. Điều này cho phép trang tạo khung nhắm mục tiêu cụ thể một đoạn mã có chứa mã chặn khung, giữ nguyên tất cả các mã khác.
Ví dụ: Nhắm mục tiêu mã chặn khung trang web:
<script> if ( top != self ) { top.location=self.location; } </script>
Mã kẻ tấn công:
<iframe src="http://example.org/?param=if(top+!%3D+self)+%7B+top.location%3Dself.location%3B+%7D">
Xác định lại vị trí
Đối với một số trình duyệt, biến “document.location” là một thuộc tính bất biến. Tuy nhiên, đối với một số phiên bản của Internet Explorer và Safari, có thể xác định lại thuộc tính này. Thực tế này có thể được khai thác để trốn tránh mã chặn khung.
Xác định lại vị trí trong IE7 và IE8: có thể xác định lại “vị trí” như được minh họa trong ví dụ sau. Bằng cách xác định “vị trí” dưới dạng một biến, bất kỳ mã nào cố gắng đọc hoặc điều hướng bằng cách gán “top.location” sẽ không thành công do vi phạm bảo mật và do đó mã chặn khung bị tạm ngưng.
Ví dụ:
<script> var location = "xyz"; </script> <iframe src="http://example.org"></iframe>
Xác định lại vị trí trong Safari 4.0.4: Để phá mã chặn khung bằng “top.location”, bạn có thể liên kết “vị trí” với một hàm thông qua defineSetter (qua cửa sổ), để cố gắng đọc hoặc điều hướng đến “trên cùng. vị trí ”sẽ không thành công.
Ví dụ:
<script> window.defineSetter("location" , function(){}); </script> <iframe src="http://example.org"></iframe>
Bảo vệ phía máy chủ: X-Frame-Options
Một cách tiếp cận khác đối với mã chặn frame phía máy khách đã được Microsoft triển khai và nó bao gồm một biện pháp bảo vệ dựa trên tiêu đề. Tiêu đề “X-FRAME-OPTIONS” mới này được gửi từ máy chủ trên phản hồi HTTP và được sử dụng để đánh dấu các trang web không nên đóng khung. Tiêu đề này có thể nhận các giá trị DENY, SAMEORIGIN, ALLOW-FROM gốc hoặc ALLOWALL không chuẩn. Giá trị đề xuất là DENY.
“X-FRAME-OPTIONS” là một giải pháp rất tốt và đã được các trình duyệt lớn áp dụng, nhưng đối với kỹ thuật này cũng có một số hạn chế có thể dẫn đến việc khai thác lỗ hổng clickjacking trong mọi trường hợp.
Kể từ khi “X-FRAME-OPTIONS” được giới thiệu vào năm 2009, tiêu đề này không tương thích với trình duyệt cũ. Vì vậy, mọi người dùng không có trình duyệt cập nhật đều có thể là nạn nhân của cuộc tấn công clickjacking.
Proxy
Web proxy được biết đến với chức năng thêm và loại bỏ các tiêu đề. Trong trường hợp proxy web loại bỏ tiêu đề “X-FRAME-OPTIONS” thì trang web sẽ mất khả năng bảo vệ khung của nó.
Phiên bản trang web di động
Cũng trong trường hợp này, vì X-FRAME-OPTIONS phải được triển khai trong mọi trang của trang web, các nhà phát triển có thể đã không bảo vệ phiên bản di động của trang web.
Tạo Proof of Concept
Khi chúng tôi phát hiện ra rằng trang web mà chúng tôi đang kiểm tra dễ bị tấn công bằng clickjacking, chúng tôi có thể tiến hành phát triển bằng chứng khái niệm (PoC) để chứng minh lỗ hổng bảo mật. Điều quan trọng cần lưu ý là, như đã đề cập trước đây, các cuộc tấn công này có thể được sử dụng kết hợp với các hình thức tấn công khác (ví dụ: cuộc tấn công CSRF) và có thể dẫn đến việc vượt qua các mã thông báo chống CSRF. Về vấn đề này, chúng ta có thể tưởng tượng rằng, ví dụ: trang web example.org cho phép người dùng đã xác thực và được ủy quyền thực hiện chuyển tiền sang một tài khoản khác.
Giả sử rằng để thực hiện chuyển giao, các nhà phát triển đã lập kế hoạch ba bước. Trong bước đầu tiên, người dùng điền vào biểu mẫu với tài khoản đích và số tiền. Trong bước thứ hai, bất cứ khi nào người dùng gửi biểu mẫu, sẽ có một trang tóm tắt yêu cầu xác nhận của người dùng (như trang được trình bày trong hình sau).
Ví dụ về clickjacking Bước 2
Sau một đoạn mã cho bước 2:
//generate random anti CSRF token $csrfToken = md5(uniqid(rand(), TRUE)); //set the token as in the session data $_SESSION['antiCsrf'] = $csrfToken; //Transfer form with the hidden field $form = ' <form name="transferForm" action="confirm.php" method="POST"> <div class="box"> <h1>BANK XYZ - Confirm Transfer</h1> <p> Do You want to confirm a transfer of <b>'. $_REQUEST['amount'] .' €</b> to account: <b>'. $_REQUEST['account'] .'</b> ? </p> <label> <input type="hidden" name="amount" value="' . $_REQUEST['amount'] . '" /> <input type="hidden" name="account" value="' . $_REQUEST['account'] . '" /> <input type="hidden" name="antiCsrf" value="' . $csrfToken . '" /> <input type="submit" class="button" value="Transfer Money" /> </label> </div> </form>';
Trong bước cuối cùng là các biện pháp kiểm soát an ninh theo kế hoạch và sau đó, nếu tất cả đều ổn, quá trình chuyển giao được thực hiện. Trong danh sách sau đây, một đoạn mã của bước cuối cùng được trình bày:
Lưu ý: trong ví dụ này,
vì đơn giản, không có quy trình làm sạch đầu vào, nhưng nó không có liên quan để chặn kiểu tấn công này
if( (!empty($_SESSION['antiCsrf'])) && (!empty($_POST['antiCsrf'])) ) { // input logic and sanization checks // check the anti-CSRF token if(($_SESSION['antiCsrf'] == $_POST['antiCsrf']) { echo '<p> '. $_POST['amount'] .' € successfully transferred to account: '. $_POST['account'] .' </p>'; } } else { echo '<p>Transfer KO</p>'; }
Như bạn có thể thấy, mã được bảo vệ khỏi cuộc tấn công CSRF bằng cả mã thông báo ngẫu nhiên được tạo ở bước thứ hai và chỉ chấp nhận biến được chuyển qua phương thức POST. Trong tình huống này, kẻ tấn công có thể giả mạo cuộc tấn công CSRF + Clickjacking để trốn tránh sự bảo vệ chống CSRF và buộc nạn nhân thực hiện chuyển tiền mà không có sự đồng ý của cô ấy.
Trang mục tiêu cho cuộc tấn công là bước thứ hai của quy trình chuyển tiền. Vì các nhà phát triển chỉ đặt các biện pháp kiểm soát bảo mật ở bước cuối cùng nên nghĩ rằng điều này đã đủ an toàn, kẻ tấn công có thể chuyển các thông số tài khoản và số tiền thông qua phương thức GET.
Lưu ý: có một cuộc tấn công clickjacking nâng cao cho phép buộc người dùng điền vào biểu mẫu, vì vậy cũng trong trường hợp được yêu cầu điền vào biểu mẫu, cuộc tấn công có thể thực hiện được
Trang của kẻ tấn công có thể trông giống như một trang đơn giản và vô hại như trang được trình bày bên dưới:
Ví dụ về clickjacking Trang độc hại 1
Hình 4.11.9-4: Ví dụ về clickjacking Trang độc hại 1
Nhưng khi chơi với giá trị độ mờ CSS, chúng ta có thể thấy những gì ẩn dưới trang web tưởng như vô hại.
Ví dụ về clickjacking Trang độc hại 2
Hình 4.11.9-5: Ví dụ về clickjacking độc hại Trang 2
Mã clickjacking để tạo trang này được trình bày bên dưới:
<html> <head> <title>Trusted web page</title> <style type="text/css"><!-- *{ margin:0; padding:0; } body { background:#ffffff; } .button { padding:5px; background:#6699CC; left:275px; width:120px; border: 1px solid #336699; } #content { width: 500px; height: 500px; margin-top: 150px ; margin-left: 500px; } #clickjacking { position: absolute; left: 172px; top: 60px; filter: alpha(opacity=0); opacity:0.0 } //--></style> </head> <body> <div id="content"> <h1>www.owasp.com</h1> <form action="http://www.owasp.com"> <input type="submit" class="button" value="Click and go!"> </form> </div> <iframe id="clickjacking" src="http://localhost/csrf/transfer.php?account=ATTACKER&amount=10000" width="500" height="500" scrolling="no" frameborder="none"> </iframe> </body> </html>
Với sự trợ giúp của CSS (lưu ý khối #clickjacking), chúng tôi có thể che dấu và định vị iframe một cách thích hợp sao cho khớp với các nút. Nếu nạn nhân nhấp vào nút “Nhấp và truy cập!” biểu mẫu được gửi và quá trình chuyển giao hoàn tất.
Ví dụ được trình bày chỉ sử dụng kỹ thuật clickjacking cơ bản, nhưng với kỹ thuật nâng cao có thể buộc người dùng điền vào biểu mẫu với các giá trị do kẻ tấn công xác định.