HTTP Host header attack - Tấn công tiêu đề Host trong giao thức HTTP (phần 2)
II. Phân tích các dạng HTTP Host header attack và ngăn chặn (tiếp)
4. Sử dụng tấn công Host header khai thác SSRF
Một trong những phương pháp tấn công phổ biến kết hợp lỗ hổng Host header attack và SSRF là Routing-based SSRF. Kỹ thuật tấn công này thường được sử dụng trong các hệ thống đám mây. Kẻ tấn công sẽ khai thác thành phần trung gian (như máy chủ reverse proxy) để tấn công vào các hệ thống nội bộ. Thông thường, tiêu đề "Host" được sử dụng nhằm đánh lừa máy chủ trung gian chuyển hướng yêu cầu đến một địa chỉ IP mà kẻ tấn công đưa ra.
Xét một ứng dụng web được triển khai trên nền tảng đám mây của AWS. Ứng dụng web sử dụng một dịch vụ load balancer để phân phối tải cho các server back-end. Dịch vụ load balancer này được cấu hình để chuyển tiếp yêu cầu HTTP đến các server back-end bằng cách sử dụng tiêu đề "Host" trong request. Ví dụ cấu hình nginx như sau:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
}
}
upstream backend {
server backend1.example.com;
server backend2.example.com;
}
Trong đó, load balancer được cấu hình để lắng nghe trên cổng 80 và chuyển tiếp các yêu cầu tới địa chỉ IP của các server back-end được định nghĩa trong upstream "backend". Điều này cho phép load balancer phân phối các yêu cầu tới các server back-end khác nhau.
Chú ý rằng trong cấu hình trên, thông qua thiết lập "proxy_set_header Host $host;", tiêu đề "Host" trong yêu cầu HTTP được chuyển tiếp đến server back-end mà không được kiểm tra và xác thực, điều này tạo ra một lỗ hổng SSRF tiềm ẩn.
Để khai thác lỗ hổng SSRF truy cập vào các máy chủ nội bộ, kẻ tấn công sẽ gửi một yêu cầu HTTP đến ứng dụng web nhưng thay đổi tiêu đề "Host" để trỏ đến một máy chủ mà họ muốn tấn công. Yêu cầu này sẽ được gửi đến dịch vụ load balancer, sau đó sẽ được chuyển tiếp đến máy chủ cụ thể mà kẻ tấn công nhắm tới.
Chúng ta sẽ cùng phân tích kỹ thuật tấn công này qua bài lab Routing-based SSRF.
Kiểm tra header Host với một giá trị domain không tồn tại:
Response trả về thông báo Timeout rằng không thể kết nối tới Host được chỉ định. Từ đây có thể dự đoán có sự tương tác từ máy chủ tới giá trị domain lấy từ header Host trong request. Thay thế header Host với giá trị domain từ Burp Collaborator:
Server Burp Collaborator nhận được request DNS Lookup từ máy chủ web, dự đoán bài lab chứa lỗ hổng HTTP Host header attack có thể khai thác bằng kỹ thuật tấn công Routing-based SSRF.
Từ miêu tả bài lab chúng ta biết rằng địa chỉ IP private đặt tại . Với subnetmask (nghĩa là bits đầu cố định) suy ra địa chỉ private của máy chủ nằm trong dải địa chỉ từ đến .
Do ứng dụng truy cập tới giá trị header Host của request nên chúng ta có thể "trỏ" header Host vào từng giá trị IP trong dải trên nhằm tìm kiếm địa chỉ IP private của máy chủ.
Sử dụng chức năng Intruder gửi requests tương ứng với tất cả dải địa chỉ IP trên (lưu ý cần bỏ chọn mục "Update Host header to match target"):
Kết quả hiển thị một request có response trả về status code , chuyển hướng tới đường dẫn /admin
:
Còn tất cả request còn lại đều trả về 504 Gateway Timeout với thông báo lỗi Server Error: Gateway Timeout (3) connecting to ...
Qua đó có thể xác định được địa chỉ IP private của máy chủ là . Thực hiện truy cập admin panel:
Xóa người dùng Carlos và hoàn thành bài lab:
Ngoài ra, bạn đọc có thể thử sức thêm bài lab có độ khó cao hơn SSRF via flawed request parsing.
Để ngăn chặn phương thức tấn công Routing-based SSRF thông qua cấu hình của load balancer, chúng ta cùng xem xét các phương pháp sau:
Cách : Sử dụng whitelist
Chúng ta có thể sử dụng một whitelist chứa các tên miền được phép truy cập để giới hạn các yêu cầu chỉ được chuyển tiếp đến những server back-end được cho phép. Phương pháp này giúp đảm bảo yêu cầu từ người dùng không được phép truy cập các server back-end nhạy cảm. Ví dụ tệp cấu hình nginx:
server {
listen 80;
server_name example.com;
location / {
# Giới hạn truy cập đến các tên miền được cho phép
if ($host !~* ^(backend1.example.com|backend2.example.com)$ ) {
return 403;
}
proxy_pass http://$host;
proxy_set_header Host $host;
}
}
Trong đó, điều kiện if
sẽ kiểm tra xem tên miền trong yêu cầu có nằm trong whitelist cho phép hay không. Nếu không, server sẽ trả về status code .
Cách : Kiểm tra và xác thực header Host
Nên kiểm tra header Host trong yêu cầu trước khi chuyển tiếp nó đến server back-end. Việc này đảm bảo rằng các yêu cầu chỉ được chuyển tiếp đến các server back-end với tên miền hợp lệ. Ví dụ cấu hình:
server {
listen 80;
server_name example.com;
location / {
# Kiểm tra và xác thực header Host
if ($host !~* ^(backend1.example.com|backend2.example.com)$ ) {
return 403;
}
proxy_pass http://$host;
proxy_set_header Host $host;
}
}
Cách : Sử dụng tường lửa
Tường lửa có thể được cấu hình để chặn các yêu cầu HTTP đến máy chủ back-end có IP hoặc tên miền nằm ngoài phạm vi cho phép của hệ thống. Ví dụ cấu hình tường lửa dưới đây khai báo danh sách các địa chỉ IP hoặc tên miền được phép truy cập hệ thống và chặn tất cả các yêu cầu HTTP đến các địa chỉ IP hoặc tên miền nằm ngoài danh sách cho phép:
allow_list = ["10.0.0.0/8", "example.com"]
firewall_rule = {
"protocol": "http",
"destination": "back-end-server",
"action": "deny",
"source": {
"not": {
"cidr": allow_list
}
}
}
Cách : Giảm tải tính năng chuyển tiếp yêu cầu không cần thiết
Có thể tắt tính năng chuyển tiếp Host header để ngăn chặn tấn công SSRF. Tuy nhiên, điều này có thể gây ra một số vấn đề khác như gián đoạn việc phân phối tải hoặc làm giảm hiệu suất. Đây có lẽ là phương thức ngăn chặn tấn công "bất đắc dĩ" nhất.
Các tài liệu tham khảo
- https://portswigger.net/web-security/host-header
- https://portswigger.net/research/cracking-the-lens-targeting-https-hidden-attack-surface
©️ Tác giả: Lê Ngọc Hoa từ Viblo
All rights reserved