- vừa được xem lúc

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 3)

0 0 33

Người đăng: Viblo Security

Theo Viblo Asia

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

5. Kiểm tra lỗ hổng SSRF

SSRF thường xuất hiện ở các chức năng có quá trình trao đổi dữ liệu với một trang web khác. Và chúng ta cũng cần có một phương pháp để kiểm tra khả năng xảy ra của lỗ hổng SSRF. Một trong những phương pháp kiểm tra phổ biến và đơn giản nhất chính là kỹ thuật out-of-band (OAST). Trong bài viết này tôi sẽ trình bày kỹ thuật với công cụ Burp Collaborator.

Nếu các bạn để ý thì trong các bài lab trước tôi cũng có sử dụng tới kỹ thuật này nhằm xác định chính xác hơn khả năng xảy ra lỗ hổng SSRF.

Một ví dụ khác cho kỹ thuật out-of-band (OAST) qua bài lab sau.

Phân tích lab Blind SSRF with out-of-band detection

Miêu tả: Trang web sử dụng một phần mềm tìm nạp và phân tích URL được xác định trong header Referer khi người dùng truy cập vào trang hiển thị chi tiết sản phẩm. Để giải quyết bài lab, chúng ta cần sử dụng chức năng này thực hiện một kịch bản DNS lookup với server Burp Collaborator.

Khi truy cập vào trang hiển thị chi tiết sản phẩm, quan sát request trong Burp Suite:

Chúng ta thấy header Referer mang giá trị địa chỉ URL của trang được truy cập ngay trước khi chúng ta truy cập tới giao diện hiển thị chi tiết sản phầm /product?productId=1

Thay đổi giá trị header Referer thành địa chỉ tới domain Burp Collaborator.

Gửi request, quan sát tại Burp Collaborator Client thu được request đến từ server trang web chứa lỗ hổng SSRF.

Như vậy chúng ta đã thực hiện DNS lookup thành công, tại header Referer có khả năng bị tấn công SSRF, bài lab được giải quyết!

Việc xác nhận lỗ hổng SSRF thông qua kỹ thuật out-of-band (OAST) không chỉ giúp chúng ta tiết kiệm thời gian, tài nguyên trong quá trình kiểm thử sản phẩm, mà còn là một bước bắt buộc trong việc khai thác lỗ hổng Server-side request forgery ở dạng blind - Một dạng lỗ hổng SSRF không trả về kết quả trong giao diện, sẽ được chúng ta bàn bạc và phân tích kỹ hơn ở phần sau.

6. SSRF và bypass white-based input filters

Bên cạnh sử dụng black list, một số trang web sử dụng white list gồm các phần tử bắt buộc phải xuất hiện trong các tham số. Việc sử dụng white list thường mang lại hiệu quả tốt hơn black list, tuy nhiên các nhà phát triển cần cập nhật white list liên tục mỗi khi có chức năng hoặc các phần tử mới cần bổ sung. Việc cài đặt cơ chế ngăn chặn dựa theo white list vẫn có khả năng bị kẻ tấn công vượt qua bởi các ký tự có chức năng đặc biệt trong URL.

6.1. Cài đặt cơ chế ngăn chặn white list dựa theo port

Một trang web có một cơ chế ngăn chặn lỗ hổng SSRF bằng cách giới hạn chỉ cho phép người dùng truy cập tới port 8080 tại local. Đoạn code vận hành với ngôn ngữ PHP như sau:

<?php
$url = 'http://' . $_GET['url'];
$parsed_url = parse_url($url);
if ($parsed_url['port'] == '80') { readfile($url);
} else { echo "SSRF attack detected!";
}

Tham số url truyền giá trị qua phương thức GET, sau đó trang web thực hiện hàm parse_url() phân tích cú pháp URL giá trị này và kiểm tra biến $parsed_url['port'] có bằng 8080 hay không, nếu có thực hiện hàm readfile() đọc giá trị từ $url. Điều này chỉ cho phép người dùng có thể truy cập tới nội dung public tại port 8080:

Đoạn code không hề có vấn đề gì? Thực tế không phải như vậy, lỗ hổng xảy ra ở cách hoạt động xung đột của hai hàm parse_url()readfile() trong PHP. Xét giá trị url=localhost:8888:80, thực tế ở đây, hai hàm readfile()parse_url() đang quan tâm hai port khác nhau!

Theo cách định nghĩa trong ngôn ngữ PHP thì: readfile() sẽ mặc định chọn port xuất hiện đầu tiên (sau dấu hai chấm), còn parse_url() sẽ chọn port xuất hiện cuối cùng!

Và hình ảnh phía trên cũng chính là cách vượt qua cơ chế ngăn chặn tấn công trong đoạn code chúng ta đang xét:

6.2. Cài đặt cơ chế ngăn chặn white list dựa theo host

Chúng ta sẽ tiếp cận với cơ chế ngăn chặn đơn giản bằng cách kiểm tra các phần tử trong danh sách white list có xuất hiện trong chuỗi URL hay không. Từ đó thực hiện ngăn chặn các hành vi tấn công SSRF.

Xem xét đoạn code viết bằng ngôn ngữ Python sau:

from flask import *
import requests app = Flask(__name__) @app.route('/ssrf')
def follow_url(): url = request.args.get('url', '') whitelist = ['google.com', 'youtube.com'] check = 0 for i in whitelist: if i in url: check = 1 if check: return (requests.get(url).text) else: return ("SSRF Attack detected!") if __name__ == '__main__': app.run(host = "0.0.0.0", port = 1234)

Đoạn code trên chứa một white list kiểm tra biến url cần chứa một trong các phần tử google.com hoặc youtube.com, với mong muốn sẽ ngăn chặn kẻ tấn công thực hiện khai thác lỗ hổng SSRF vào các trang web khác, chỉ cho phép hai trang web trên trong white list.

Điều này có nghĩa rằng, để khai thác được lỗ hổng SSRF thì trong tham số url luôn cần chứa giá trị google.com hoặc youtube.com. Ý tưởng để vượt qua cơ chế ngăn chặn này là chúng ta có thể "nhúng" địa chỉ vào URL này. Thực hiện bằng các ký tự đặc biệt như @, #, &, .. Kết quả sau đúng với phần lớn các ứng dụng web:

  • https://expected-host@evil-host
  • https://evil-host#expected-host
  • https://expected-host.evil-host

Ngoài ra có thể sử dụng kỹ thuật URL encode và kết hợp khéo léo các kỹ thuật trên với nhau.

Quay lại ví dụ phía trên, chúng ta có thể "nhúng" địa chỉ localhost:8888 vào tham số url vượt qua cơ chế white list bằng một vài cách như sau:

  • Cách 11: Sử dụng ký tự @, payload: url=http://google.com@localhost:8888

  • Cách 22: Sử dụng ký tự #. Nếu trực tiếp truyền giá trị url=http://localhost:8888#google.com thì khi thực thi request.args.get('url', '') trang web chỉ nhận được giá trị url=http://localhost:8888 do ký tự # lúc này được hiểu với vai trò anchor link. Bởi vậy cần thực hiện URL encode ký tự # thành %23 để khi URL decode tự động ký tự # được hiểu là một fragment, payload: url=http://localhost:8888%23google.com

Xem xét một trường hợp khác, sử dụng white list thực hiện ngăn chặn tấn công SSRF với đoạn mã nguồn viết bằng PHP như sau:

<?php
$url = 'http://' . $_GET['url'];
$parsed_url = parse_url($url);
if ($parsed_url['host'] == 'google.com') { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_exec($ch);
} else { echo "SSRF attack detected!";
}

Đoạn code sử dụng hàm parse_url() trong PHP phân tích cú pháp URL đầu vào, kiểm tra giá trị host $parsed_url['host'] bắt buộc phải là google.com, tiếp theo sử dụng hàm curl_exec() của thư viện cURL hiển thị nội dung trang web.

Mục đích của kẻ tấn công là đọc nội dung tại http://11.0.0.1:1234 là một địa chỉ chỉ có thể truy cập từ mạng nội bộ. Chắc hẳn qua ví dụ cài đặt white list với port ở phía trên các bạn cũng đã đoán ra vấn đề ở đây rồi phải không? Đúng vậy, lỗ hổng SSRF xảy ra do định nghĩa về giá trị host của hàm parse_url() và thư viện cURL không đồng nhất. Chẳng hạn với URL http://viblo@evil.com@google.com (chuỗi viblo ở đầu có thể thay bằng bất kỳ giá trị khác):

Như trong hình vẽ, thư viện cURL sẽ ưu tiên host là evil.com, đối với hàm parse_url() lại lựa chọn google.com. Bởi vậy, chúng ta có thể xây dựng payload tấn công như sau: url=viblo@11.0.0.1:1234@google.com

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

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cây tìm kiếm nhị phân

Như mình đã trình bày trong bài viết trước, tìm kiếm nhị phân trên một mảng thể hiện sự hiệu quả. Tuy nhiên, hiệu suất của việc tìm kiếm trên mảng bị giảm đi rất nhiều khi dữ liệu trong tập dữ liệu th

0 0 26

- vừa được xem lúc

Giới thiệu thuật toán tìm kiếm nhị phân

Tìm kiếm nhị phân là một thuật toán cơ bản trong khoa học máy tính. Thay vì tìm kiếm một phần tử trong mảng một cách tuyến tính duyệt từng phần tử, tìm kiếm nhị phân cho ta cách tìm kiếm tối ưu hơn bằ

0 0 26

- vừa được xem lúc

Quy hoạch động trên cây

I. Giới thiệu.

0 0 38

- vừa được xem lúc

Toán học tổ hợp

II. Các dãy số và công thức quan trọng. 1. Dãy Fibonaci.

0 0 140

- vừa được xem lúc

Một số ứng dụng nâng cao của cây DFS (phần 1)

I. Cây DFS và bài toán định chiều đồ thị. 1. Phân loại các cung trên cây DFSext{DFS}DFS.

0 0 42

- vừa được xem lúc

Một số ứng dụng nâng cao của cây DFS (phần 2)

III. Bài toán tìm thành phần liên thông mạnh - giải thuật Tarjan. 1. Định nghĩa thành phần liên thông mạnh.

0 0 32