Một số ứng dụng có thể block các input có chứa các hostname chẳng hạn như 127.0.0.1 và localhost hoặc các endpoint nhạy cảm chẳng hạn như /admin. Trong trường hợp này, ta có thể vượt qua bằng cách sử dụng các kỹ thuật sau:
Sử dụng một dạng biểu diển IP khác của 127.0.0.1 chẳng hạn như 2130706433, 017700000001 hoặc 127.1.
Đăng ký một tên miền mà phân giải thành 127.0.0.1.
Làm rối các chuỗi bị chặn bằng cách sử dụng URL encode hoặc sử dụng các chữ in hoa và in thường lẫn lộn.
Cung cấp một URL mà ta kiểm soát và có thể chuyển hướng về URL mục tiêu. Sử dụng những redirect code cũng như là các protocol khác nhau. Ví dụ, việc chuyển từ https: thành http: trong quá trình redirect có thể giúp bypass một số anti-SSRF filter.
Lab: SSRF with Blacklist-based Input Filter
Mô tả lab:
Lab này có chức năng kiểm tra tồn kho thực hiện lấy dữ liệu từ hệ thống nội bộ.
Mục tiêu là truy cập giao diện admin tại http://localhost/admin để xóa người dùng carlos.
Lập trình viên có sử dụng hai cách phòng chống SSRF yếu mà ta cần bypass.
Request kiểm tra tồn kho có dạng như sau:
Thử thay thành giá trị của stockApi thành http://127.1 thì nhận được response là trang chủ (endpoint /). Sau đó, dùng endpoint là /Admin thay vì /admin thì thu được trang giao diện của admin và có đoạn code như sau;
Thay URL thành http://127.1/Admin/delete?username=carlos để xóa người dùng carlos.
SSRF with Whitelist-based Input Filters
Một số ứng dụng sử dụng whitelist bao gồm các giá trị được phép tồn tại trong input (có thể ở đầu hoặc ở giữa) và filter tất cả các giá trị khác. Chúng ta có thể bypass filter này bằng cách khai thác tính không nhất quán trong việc phân tách URL giữa các thành phần trong ứng dụng.
Các ví dụ:
Khi sử dụng HTTP basic authentication, credentials có thể được nhúng vào URL trước host name1 bằng cách sử dụng ký tự @ . Cú pháp: [ userinfo "@" ] host [ ":" port ]. Ví dụ:
https://expected-host:fakepassword@evil-host
Sử dụng ký tự # để chỉ định URL fragment:
https://evil-host#expected-host
Sử dụng expected hostname như là subdomain của một domain mà ta kiểm soát:
https://expected-host.evil-host
Thực hiện URL-encode các ký tự để gây bối rối cho các đoạn code parse URL. Cách làm này là hữu ích nếu đoạn code triển khai filter xử lý các ký tự được URL encode khác với đoạn code thực hiện gửi back-end request. Thậm chí, ta cũng có thể URL-encode hai lần vì một số WAF chỉ URL-decode một lần2. Ví dụ, xét URL sau:
Lab này có chức năng kiểm tra tồn kho thực hiện lấy dữ liệu từ hệ thống nội bộ.
Mục tiêu là truy cập giao diện admin tại http://localhost/admin để xóa người dùng carlos.
Lập trình viên có sử dụng một cách phòng chống SSRF mà ta cần bypass.
Request kiểm tra tồn kho có dạng như sau:
Thử với 127.1 thì nhận được response sau:
Thử thêm localhost@ vào trước hostname stock.weliketoshop.net, URL trở thành:
Lúc này, localhost đóng vai trò là username gửi đến stock.weliketoshop.net.
Response có status code là 200.
Ta giả sử phần code filter URL xem localhost là username nhưng phần code gửi request cho back-end lại xem localhost là hostname. Thử thêm endpoint /:
Dạng URL encode:
Response nhận được là:
Thử double encode ký tự / (thay % thành %25):
Response nhận được có status code là 200 và là trang sản phẩm (endpoint /). Ngoài ra, trang này có một đoạn code như sau:
Có thể thấy, đã xuất hiện trang admin.
Thử dùng endpoint là /admin (vẫn double encode ký tự /):
Response không có sự thay đổi so với endpoint /.
Hint
Đáp án không sử dụng path ở phần username mà sử dụng path ở sau phần hostname.
Chuyển endpoint /admin về sau phần hostname và xóa các query param không cần thiết:
Response thu được có đoạn code sau:
Payload dùng để xóa người dùng carlos:
Bypassing SSRF Filters via Open Redirection
Nếu có một API nào đó hỗ trợ cơ chế chuyển hướng mở (open redirect), attacker có thể chuyển hướng đến một địa chỉ tùy ý thông qua API được dùng để gửi request đến backend.
Ví dụ, URL sau sẽ chuyển hướng tới http://evil-user.net:
Cụ thể, attacker có thể tận dụng điều này để bypass URL filter và khai thác SSRF:
Lab: SSRF with Filter Bypass via Open Redirection Vulnerability
Mô tả lab:
Lab này có chức năng kiểm tra tồn kho thực hiện lấy dữ liệu từ hệ thống nội bộ.
Mục tiêu là truy cập giao diện admin tại http://192.168.0.12:8080/admin để xóa người dùng carlos.
Request kiểm tra tồn kho không có query param chứa URL:
Request chuyển sang sản phẩm kế tiếp có query param path có thể chứa URL:
Tuy nhiên, nếu sử dụng giá trị của path là http://192.168.0.12:8080/admin:
Thì response có dạng như sau:
Response này sẽ redirect đến địa chỉ IP nội bộ của chúng ta thay vì địa chỉ nội bộ của ứng dụng:
Như vậy, endpoint /product/nextProduct không được dùng để tấn công.
Hint
Đáp án khai thác param stockApi ở request kiểm tra tồn kho (đề bài cũng đã đề cập là lỗ hổng tồn tại ở chức năng kiểm tra tồn kho 🤦♀️).
Ta sẽ lợi dụng tính năng redirect của endpoint /product/nextProduct để redirect đến địa chỉ mong muốn thông qua param stockApi. Cụ thể, thay giá trị của stockApi thành /product/nextProduct?productId=1&path=http://192.168.0.12:8080/admin:
Response có đoạn code như sau:
Chỉnh sủa giá trị của stockApi để xóa người dùng carlos: