NỘI DUNG
Tiếp theo nội dung Penetration Testing Step 3 – CSRF attack – Hồi thứ nhất, kỳ này tôi sẽ triển tiếp hồi thứ hai với Cross-site Request Forgery – CSRF attack. Cụ thể, tôi sẽ tập trung vào các kịch bản bao gồm:
- CSRF token không liên kết với user session;
- CSRF token có liên kết – nhưng liên kết nhầm sang non-session cookie;
- CSRF token được kiểm tra “nhân bản” với session cookie.
Lưu ý:
- Như mọi khi, tôi cũng sẽ tận dụng các bài Lab dựng sẵn của ông PortSwigger để tiết kiệm thời gian dàn cảnh;
- Thông tin liên quan đến Burp Suite bạn có thể xem trong nội dung Penetration Testing Step 3 – 6 điều bạn nên biết trước khi xài tool khủng Burp Suite;
- Chi tiết việc sử dụng Burp Suite Repeater bạn có thể xem trong nội dung Penetration Testing Step 3 – Thủ thuật chọc ngoáy HTTP/WebSockets message với Burp Suite Repeater;
#1. CSRF attack trong tình huống CSRF token không tích hợp vào hệ thống quản lý user session
Đây là tình huống khi ứng dụng không buồn nghĩ tới chuyện xác minh xem CSRF token trong request có thuộc về cùng một session của user liên quan hay không. Việc này có thể gặp khi ứng dụng khởi tạo ra một token pool (có thể tạm dịch là “kho token“, nhưng nghe bựa quá nên thôi tôi dùng từ tiếng Anh luôn cho lành) và khi đó nó chỉ kiểm tra coi cái CSRF token đang được sử dụng có nằm trong cái token pool hay không rồi chấm hết.
Với cơ chế này, attacker có thể đăng nhập vào ứng dụng bằng account của y rồi hốt cái token đã được ứng dụng cấp phát này để xả CSRF attack lên đầu nạn nhân.
Tôi bay vào phần demo để minh họa cái ý tưởng này ngay đây.
Tương tự như kỳ trước, với Burp Suite Interception đã chạy, tôi cũng đăng nhập vào ứng dụng với account thứ nhất (wiener:peter) rồi chạy chức năng Update email. Sau đó tôi hốt cái CSRF token trong request tương ứng (h02hFN4f6dXMUfNKd4NYJqtpROdC6sET trong trường hợp này).
Tiếp đến, tôi mở một private/incognito browser để đăng nhập vào ứng dụng với account thứ 2 (carlos:montaya). Tương tự, tôi cũng chạy chức năng Update email rồi bắt cái request tương ứng gửi sang Burp Suite Repeater.
Điểm thú vị ở đây là nếu tôi thử thay thế cái CSRF token của carlos bằng cái token đã tạo trước đó với account thứ nhất (h02hFN4f6dXMUfNKd4NYJqtpROdC6sET) thì ứng dụng vẫn chạy cái chức năng Update email ầm ầm. Việc này cho thấy ứng dụng đang chơi kiểu xuất bản ra một CSRF token pool rồi chỉ kiểm tra coi token được sử dụng trong các request có nằm trong token pool hay không. Còn việc cái CSRF token có tương ứng cho user session liên quan hay không thì nó méo quan tâm.
Giờ tôi sẽ giở trò cũ với CSRF PoC Generator như kỳ trước.
Lưu ý:
- Vụ triển CSRF PoC Generator tôi nói kỹ trong kỳ trước rồi nên không nhắc lại. Nếu cần thiết thì bạn vui lòng de lại để xem cho rõ;
- CSRF token chỉ dùng được một lần nên tôi sẽ cần tạo lại cái mới trước khi triển CSRF attack (3Xf90d7iEz4UToioz3Sh8RpJ2tvuMcQP như trường hợp bên dưới).
Và tất nhiên, bạn cũng có thể làm kiểu thủ công mỹ nghệ với cái template sau nếu không sử dụng CSRF PoC Generator.
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://ac491f191ed880a6c04a102100f40067.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="test-csrf-carlos@carlos-montoya.net" />
<input type="hidden" name="csrf" value="3Xf90d7iEz4UToioz3Sh8RpJ2tvuMcQP" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
Công việc tiếp theo không có gì mới. Tôi cũng đẩy hàng vô Body section của Exploit server.
Rồi sau đó Store và View exploit để xác nhận “hàng” đã chạy như ý đồ thiết kế.
#2. CSRF attack trong tình huống CSRF token liên kết với non-session cookie
Tình huống này có “cải thiện” hơn trước đó một tí khi CSRF token đã được gắn với một cookie nào đấy. Tuy nhiên, có thể do định mệnh nên ông developer gắn nhầm vô non-session cookie (tức là cookie không phục vụ cho việc track – theo dõi – user session).
Việc này có thể xảy ra khi ứng dụng sử dụng 2 framework khác nhau (một cái để quản lý session và một cái để xử lý CSRF) và 2 cái này chưa được tích hợp lại để xử lý user sesion với CSRF token.
Điểm cần lưu ý ở đây là attacker sẽ cần có một phương án để cài cắm cái non-session cookie vào browser của nạn nhân từ đó có một sự vụ tấn công thành công.
Giống như trên, với Burp Suite Interception đã chạy, tôi cũng đăng nhập vào ứng dụng với account thứ nhất (wiener:peter) rồi chạy chức năng Update email và chặn cái request tương ứng.
Ở đây, tôi ghi nhận thấy có xuất hiện một đối tượng mới là csrfKey cookie (VGKrZugc9clyoyeyNV1tmhuRsdAO4My4 trong trường hợp này) bên cạnh cái CSRF token (IAng1n6gH04Wb4ZApoR0X4xkQhrcXhd0) như trước đó. Nếu đẩy cái request này sang Burp Suite Repeater và thử thực hiện một số hiệu chỉnh thì tôi nhận thấy:
- Đổi sesion cookie thì tôi sẽ bị log out, sút văng ra ngoài;
- Đổi csrfKey cookie thì cái CSRF token của tôi sẽ bị từ chối chứ không liên đới đến cái session;
- Và tất nhiên, đổi CSRF token thì tôi sẽ bị ăn chửi vì xài hàng đểu như bên dưới.
Hành vi nói trên của ứng dụng hàm ý cho thấy cái CSRF token đã bị “buộc nhầm” vô cái cookie không liên quan đến việc quản lý session (csrfKey cookie).
Tôi lại thử mở một private/incognito browser để đăng nhập vào ứng dụng với account thứ hai (carlos:montaya) và chạy chức năng Update email. Tất nhiên tôi cũng intercept cái request và gửi sang Burp Suite Repeater.
Tại đây, nếu tôi thử hốt bộ đôi csrfKey cookie và CSRF token từ account wiener đẩy vô cho request tương ứng của account carlos thì ứng dụng vẫn chạy tốt một cách đáng ngạc nhiên.
Sau khi đã xác nhận được lỗ hổng liên quan, giờ tôi quay lại account wiener để tìm cách dí cái csrfKey cookie của mình sang browser của nạn nhân.
Với chức năng Search của ứng dụng, tôi nhận thấy cái Search term (“test“) được “hồi quang phản chiếu” vô Set-Cookie header của response như bên dưới.
Chức năng Search này được chạy thả cửa mà không có CSRF protection nên tôi có thể tận dụng để đẩy csrfKey cookie vô browser của nạn nhân. Cụ thể, tôi sẽ dựng một cái Search term cú pháp kiểu bên dưới (tôi dùng csrfKey cookie minh họa là Z0xukRp3aYGPaFR0Evh6nRw1ShYhxCiA) với URL encode:
/?search=test%0d%0aSet-Cookie:%20csrfKey=Z0xukRp3aYGPaFR0Evh6nRw1ShYhxCiA
Ngon, cái response trả về cho thấy tôi đã có thể dí cái csrfKey cookie vào thành công.
Công việc tiếp theo với CSRF PoC Generator cũng tương tự như trước đó. Tuy nhiên lần này, chỗ Script Block tôi sẽ cần cập nhật lại để thực hiện ý đồ đẩy csrfKey cookie vào browser của nạn nhân theo cú pháp kiểu như sau:
<img src="$cookie-injection-url" onerror="document.forms[0].submit()">
Ở đây, cái $cookie-injection-url tương ứng của tôi sẽ là https://ac451faa1f7be655c067152f0025004a.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrfKey=VGKrZugc9clyoyeyNV1tmhuRsdAO4My4
Và như vậy cái Script Block cụ thể tương tương ứng sẽ là:
<img src="https://ac451faa1f7be655c067152f0025004a.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrfKey=VGKrZugc9clyoyeyNV1tmhuRsdAO4My4" onerror="document.forms[0].submit()">
Câu chuyện sau đó không có gì mới nên tôi không bàn kỹ thêm nữa.
#3. CSRF attack trong tình huống CSRF token được kiểm tra “nhân bản” với session cookie
Tôi tiếp tục sang kịch bản kế tiếp khi ứng dụng giải pháp “double submit” CSRF prevention một cách sai trái. Đại khái ở đây ứng dụng sẽ kiểm tra 2 cái csrf cookie và CSRF token, nếu 2 thằng này giống nhau thì ok cho qua.
Tôi lại đăng nhập vào hệ thống với crendtial wiener:peter rồi chạy chức năng Update Email.
Sau đó tôi cũng hốt cái request tương ứng đẩy qua Burp Suite Repeater. Ở đây, tôi ghi nhận ứng dụng kiểm soát thông qua việc so sánh cái CSRF token (csrf body parameter) với csrf cookie.
Cũng lại giống như kịch bản trước đó, khi chạy thử Search function tôi nhận thấy Search term sẽ được “phản chiếu” vô Set-Cooke header của response từ đó cho phép tôi đẩy csrf cookie vô browser của nạn nhân.
Công việc tay chân này cũng sẽ được triển khai với Search term theo kiểu: /?search=test%0d%0aSet-Cookie:%20csrf=faketoken
Và vẫn nhai lại bài cũ với CSRF PoC Generator, tôi cập nhật chỗ Script Block (với $cookie-injection-url tương ứng là https://ac361ff61e5fe629c06d0bcb00ad000e.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrf=faketoken để tuồn cái “pha-ke” csrf cookie vào.
<img src="https://ac361ff61e5fe629c06d0bcb00ad000e.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrf=faketoken" onerror="document.forms[0].submit();"/>
Rồi, đến đây tôi cũng xin tạm dừng hồi thứ hai của CSRF attack. Trong kỳ tới tôi sẽ triển khai dứt điểm các kịch bản còn lại với thằng CSRF.
2 thoughts on “Penetration Testing Step 3 – CSRF attack – Hồi thứ hai”