II. Phân tích và khai thác các lỗ hổng Server-side request forgery (tiếp)
9. Lỗ hổng SSRF trong open redirection (chuyển hướng)
Trong một số trường hợp các chức năng chuyển hướng cũng có thể gây ra lỗ hổng SSRF. Chẳng hạn ứng dụng web gọi tới API thực hiện chuyển hướng người dùng tới một trang web khác, có URL như sau:
/product/nextProduct?currentProductId=6&path=http://evil-user.net
Trang web sẽ chuyển hướng người dùng tới http://evil-user.net
được xác định qua tham số path
. Bởi vậy kẻ tấn công có thể xây dựng một request nhằm bỏ qua cơ chế ngăn chặn tấn công SSRF từ trang web như sau:
POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118 stockApi=http://weliketoshop.net/product/nextProduct?currentProductId=6&path=http://192.168.0.68/admin
Khi đó tham số stockApi
phù hợp với điều kiện trong cơ chế ngăn chặn, sau đó khi trang web gọi tới URL http://weliketoshop.net/product/nextProduct?currentProductId=6&path=http://192.168.0.68/admin
sẽ thực hiện API thực hiện thao tác chuyển hướng người dùng tới path
là http://192.168.0.68/admin
. Quá trình diễn ra kịch bản trên hoàn toàn phù hợp với tất cả điều kiện của trang web. Kẻ tấn công khai thác lỗ hổng SSRF thông qua chức năng open redirection thành công! Cùng phân tích sâu hơn kỹ thuật này thông qua lab sau:
Phân tích lab SSRF with filter bypass via open redirection vulnerability
Miêu tả: Chức năng stock check của trang web truy xuất dữ liệu từ trang mạng nội bộ trả về cho người dùng. Tại đây chứa lỗ hổng SSRF. Để giải quyết bài lab, chúng ta cần khai thác lỗ hổng SSRF kết hợp chức năng open redirection nhằm truy cập vào trang quản trị viên nội bộ tại http://192.168.0.12:8080/admin
và thực hiện xóa tài khoản người dùng carlos.
Với bài lab này chúng ta chú ý vào hai chức năng:
Chức năng Check stock: Truy xuất dữ liệu tại /product/stock/check?productId=1&storeId=1
qua tham số stockApi
và trả về kết quả trong giao diện - phương thức POST.
Chức năng Next product: Gọi tới /product/nextProduct?currentProductId=1&path=/product?productId=2
và chuyển hướng người dùng tới /product?productId=2
thông qua tham số path
- phương thức GET.
Thực tế bài lab này tồn tại hai cách khai thác lỗ hổng SSRF, tác giả mong muốn chúng ta lợi dụng chức năng open redirection để thực hiện tấn công SSRF (nhưng có vẻ cơ chế filter hoạt động chưa đủ chặt). Tôi sẽ trình bày cả hai hướng làm.
- Hướng đi : Lợi dụng chức năng open redirection tại Next product tấn công lỗ hổng SSRF.
Giống với phần ý tưởng đã trình bày ở trên, trang web chứa chức năng open redirection thông qua URL /product/nextProduct?currentProductId=1&path=/product?productId=2
(trang web đích xác định qua tham số path
) nên chúng ta có thể xây dựng một request bypass cơ chế ngăn chặn của trang web. Ở đây chúng ta sử dụng luôn request khi gọi chức năng check stock, khai thác qua tham số stockApi
.
Payload: stockApi=/product/nextProduct?currentProductId=1%26path=/product?productId=2
Chú ý rằng cần thực hiện URL encode ký tự &
để trang web không hiểu lầm chúng ta đang truyền tới cả hai tham số stockApi
và path
. (path
là một tham số trong chuỗi URL là giá trị của stockApi
). Hoặc các bạn có thể bỏ luôn giá trị currentProductId
để không phải sử dụng ký tự &
như sau: stockApi=/product/nextProduct?path=/product?productId=2
.
Request hoạt động thành công, response trả về là giao diện tại /product?productId=2
.
Bước tiếp theo đơn giản là truy cập tới trang quản trị viên, payload: stockApi=/product/nextProduct?currentProductId=1%26path=http://192.168.0.12:8080/admin
Thực hiện xóa tài khoản người dùng carlos, bài lab hoàn thành:
- Hướng đi : Bypass cơ chế ngăn chặn lỗ hổng SSRF
Hướng đi này chúng ta chỉ cần chú ý tới tham số stockApi trong chức năng check stock. Mặc định khi sử dụng chức năng này thì tham số stockApi
chỉ nhận phần path của URL /product/stock/check?productId=1&storeId=1
nên chúng ta có thể dự đoán trang web thực hiện ghép phần host, chẳng hạn http://localhost
với giá trị stockApi
. Thực tế điều này có thể nhận thấy bằng cách truyền giá trị gây lỗi cho quá trình phân tích URL của trang web, chẳng hạn stockApi=abc
(kết thúc bằng dấu khoảng trắng).
Bởi vậy, chúng ta có thể bypass bằng cách sử dụng các ký tự đặc biệt, chẳng hạn: stockApi=@abc.com
Response trả về status code , điều này cho thấy khả năng lớn chúng ta đã bypass filter thành công và trang web truy xuất đến host abc.com
dẫn đến Internal Server Error. Thực hiện kiểm tra DNS lookup để xác định chính xác suy đoán:
Tuyệt, DNS lookup thành công, chúng ta hoàn toàn có thể bypass bằng ký tự @
, có thể hình dung URL trang web truy xuất lúc này là http://localhost:80@bl049843b38nll24zow9p4iq3h99xy.oastify.com
.
Tiếp theo, truy cập tới trang quản trị viên nội bộ, payload: stockApi=@192.168.0.12:8080/admin
Cuối cùng, thực hiện xóa tài khoản người dùng carlos và hoàn thành bài lab:
III. Một số phương pháp ngăn chặn lỗ hổng SSRF
Một số ý tưởng cho việc phòng chống tấn công lỗ hổng SSRF có thể kể đến như:
- Kiểm tra các thông tin phản hồi cho người dùng: Thay vì trực tiếp phản hồi các thông tin yêu cầu từ người dùng, chúng ta nên có thêm các bước kiểm tra tính hợp lệ của thông tin, nguồn thông tin và nội dung thông tin.
- Thống nhất các thông báo lỗi, hạn chế kẻ tấn công dựa vào sự khác nhau giữa các thông báo lỗi khai thác thông tin hữu ích.
- Áp dụng kết hợp các biện pháp ngăn chặn lỗ hổng SSRF như blacklist-based, whitelist-based, block IP có dấu hiệu lạ, ...
- Ngăn chặn các wrapper không cần thiết, chẳng hạn
file://
,gopher://
,ftp://
, ...
Các tải liệu tham khảo
- https://portswigger.net/web-security/ssrf
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery
- https://book.hacktricks.xyz/pentesting-web/ssrf-server-side-request-forgery
- https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
- https://brightsec.com/blog/ssrf-server-side-request-forgery/