+5

Server side request forgery vulnerabilities (SSRF) - Các lỗ hổng giả mạo yêu cầu phía máy chủ (Phần 1)

I. Đặt vấn đề

1. Giới thiệu

Server-side request forgery (thường được gọi là SSRF) là một dạng tấn công trong đó kẻ tấn công lợi dụng một tính năng của server public nhằm truy xuất trái phép dữ liệu từ một trang web chỉ định khác, thường là các trang web back-end ở chính server đó. Để các bạn có thể hình dung rõ hơn về dạng lỗ hổng này, chúng ta cùng xét ví dụ sau:

image.png

Trong quá trình trao đổi dữ liệu với server public (server AA), kẻ tấn công lợi dụng server AA gửi request tới server back-end (server BB, mạng nội bộ). Sau khi phân tích request này, server BB nhận thấy đây là một request đáng tin cậy do nó được gửi từ server AA, từ đó trả về response tới server AA, và server AA tiếp tục trả về dữ liệu tới kẻ tấn công. Như vậy kịch bản khai thác hoàn thành, cách thức hoạt động giống hệt với chiêu thức "mượn đao giết người"! Đây cũng chính là lý do dạng tấn công này được gọi là "giả mạo yêu cầu phía máy chủ" - kẻ tấn công mạo danh thành máy chủ để truy xuất dữ liệu nhạy cảm một cách "hợp pháp"!

2. Tầm ảnh hưởng

Kẻ tấn công thường lợi dụng kiểu tấn công này giả mạo yêu cầu truy cập tới các trang web vốn cần quyền hạn cao hoặc không nằm trong phạm vi truy cập của người dùng thường, đó có thể là các trang dành cho quản trị viên, các end point chỉ có thể truy cập từ local hoặc chứa dữ liệu nhạy cảm. Từ đó thu thập trái phép dữ liệu hoặc thực hiện các hành vi phá hoại, trong một số trường hợp có thể leo thang từ tấn công SSRF lên tấn công Command Injection. Lỗ hổng Server-side request forgery được xếp ở vị trí số 1010 trong thông kê Top 1010 lỗ hổng bảo mật web của OWASP vào năm 20212021 (A10:2021-Server Side Request Forgery (SSRF))

image.png

II. Phân tích và khai thác các lỗ hổng Server-side request forgery

1. Lỗ hổng SSRF trong một số ngôn ngữ

1.1. Ngôn ngữ PHP

Lỗ hổng SSRF có thể xuất hiện trong ngôn ngữ lập trình PHP khi các nhà phát triển sử dụng chưa tốt một số hàm làm việc với URL. Ví dụ xét đoạn code sử dụng hàm file_get_contents() sau:

<?php
if (isset($_GET['url'])) {
    $url = $_GET['url'];
    $content = file_get_contents($url);
    echo $content;
} else {
    echo "Give me the URL to show your content!";
}

Đoạn code trên in ra nội dung trang web thông qua tham số url được truyền bởi người dùng bằng hàm file_get_contents(). Ví dụ với url=https://google.com:

image.png

Do trang web không có bất kỳ phương án ngăn chặn tấn công SSRF, nên kẻ tấn công có thể dễ dàng truy xuất nội dung tệp /etc/passwd:

image.png

Hoặc đọc nội dung tại một port đang mở khác của server - vốn dĩ chỉ có thể truy cập thông qua mạng local:

image.png

Ngoài ra các hàm khác như fscokopen(), curl_exec(), ... nếu cài đặt thiếu cẩn thận cũng có nguy cơ gây ra lỗ hổng SSRF, các bạn có thể tìm hiểu thêm qua các tài liệu trên Google.

1.2. Ngôn ngữ Python

Xét đoạn code Python sử dụng thư viện Slack sau:

from flask import *
import requests

app = Flask(__name__)

@app.route('/ssrf')
def follow_url():
    url = request.args.get('url', '')
    if url:
        return (requests.get(url).text)

    return "no url parameter provided"

if __name__ == '__main__':
    app.run(host = "0.0.0.0", port = 9999)

Do không thực hiện ngăn chặn lỗ hổng SSRF đối với tham số url được truyền bởi người dùng nên trang web có thể bị tấn công SSRF như sau:

image.png

2. Lỗ hổng SSRF truy cập local server

Kẻ tấn công thường tận dụng lỗ hổng SSRF để truy cập các trang web vốn dành cho tài khoản có quyền quản trị viên hoặc chỉ có thể truy cập từ phía local server. Từ đó có thể sử dụng các chức năng của các trang web này. Local server thường được xác định với địa chỉ URL dạng: http://127.0.0.1 hoặc http://localhost. Xét bài lab sau:

Phân tích lab Basic SSRF against the local server

image.png

Miêu tả: Chức năng stock check của trang web lấy 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 truy cập vào trang quản trị viên có địa chỉ http://localhost/admin và thực hiện xóa tài khoản người dùng carlos.

Trang web chứa chức năng kiểm tra số lượng hàng còn lại trong kho:

image.png

Quan sát request và response trong Burp Suite khi sử dụng chức năng này:

image.png

Tham số stockApi truyền bằng phương thức POST cho hệ thống giá trị là một địa chỉ URL http://stock.weliketoshop.net:8080/product/stock/check?productId=1&storeId=1. Địa chỉ này chỉ có thể truy cập từ mạng local.

image.png

Do hệ thống nhận giá trị stockApi là một địa chỉ URL nên chúng ta có thể dự đoạn tại đây có thể chứa lỗ hổng SSRF. Thực hiện kiểm tra: Sử dụng Burp Collaborator, thay giá trị stockApi bằng domain mới được sinh ra:

image.png

Gửi request, kết quả tại client collaborator nhận được request tương tác - DNS lookup thành công:

image.png

Chứng tỏ chức năng stock check có thể tương tác với bất kỳ URL nào, khả năng lớn chứa lỗ hổng SSRF. Bởi vậy, chúng ta có thể khai thác lỗ hổng truy cập trang quản trị bằng một số cách như sau:

  • Payload 11: stockApi=http://localhost/admin

image.png

  • Payload 22: stockApi=http://127.0.0.1/admin

image.png

Cuối cùng, thực hiện xóa tài khoản người dùng carlos bằng cách truy cập tới đường dẫn /admin/delete?username=carlos

image.png

Payload: stockApi=http://127.0.0.1/admin/delete?username=carlos

image.png

Bài lab hoàn thành:

image.png

Các tài liệu tham khảo


©️ Tác giả: Lê Ngọc Hoa từ Viblo


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.