+2

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

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

6. SSRF và bypass white-based input filters (tiếp)

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

Cuối cùng, chúng ta hãy cùng đào sâu hơn một cách bypass cơ chế filter bằng cách kết hợp các kỹ thuật trên qua bài lab sau:

Phân tích lab SSRF with whitelist-based input filter

image.png

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. Biết rằng trang web có một cơ chế ngăn chặn tấn công SSRF. Để giải quyết bài lab, chúng ta cần vượt qua cơ chế ngăn chặn này, truy cập vào trang quản trị viên tại http://localhost/admin và thực hiện xóa tài khoản người dùng carlos.

Vẫn là giao diện quen thuộc, tham số stockApi tại chức năng check stock truyền tới hệ thống một giá trị URL qua phương thức POST.

image.png

Thử thay giá trị stockApi=http://localhost/admin

image.png

Chúng ta nhận được thông báo: External stock check host must be stock.weliketoshop.net. Có thể hiểu hệ thống chỉ cho phép trang web truy xuất dữ liệu tại host stock.weliketoshop.net, hay nói cách khác stock.weliketoshop.net là một phần tử trong white list, bắt buộc xuất hiện trong giá trị stockApi.

Như vậy chúng ta cần cố gắng tìm kiếm cách cài đặt cơ chế white list của trang web, thử cho phần tử white list stock.weliketoshop.net xuất hiện tại tham số: stockApi=http://abc-stock.weliketoshop.net

image.png

Chúng ta vẫn bị block, như vậy hệ thống không kiểm tra bằng cách trực tiếp tìm kiếm chuỗi white list trong stockApi.

Bằng cách sử dụng ký tự @, chúng ta có thể bypass qua cơ chế này: stockApi=abc@stock.weliketoshop.net

image.png

Thay abc thành localhost, bypass cơ chế white list nhưng không thể truy cập tới localhost:

image.png

Một cách khác có thể bypass là kết hợp ký tự #@, trong đó thực hiện URL encode hai lần ký tự # trở thành %2523, có stockApi=http://abc%2523@stock.weliketoshop.net

image.png

Thay abc thành localhost, đã có thể truy cập vào localhost do response trả về status code 200200:

image.png

Cả hai payload stockApi=http://localhost@stock.weliketoshop.netstockApi=http://localhost%2523@stock.weliketoshop.net đều có thể bypass cơ chế ngăn chặn có thể do hệ thống sử dụng các hàm đặc biệt (chẳng hạn parse_url()) để phân tích cú pháp URL. Còn lý do stockApi=http://localhost%2523@stock.weliketoshop.net có thể truy cập thành công trang localhost có thể do đoạn code trả về nội dung trang web truy xuất sử dụng các hàm có định nghĩa phân tích host (chẳng hạn như thư viện cURL) không đồng nhất với các hàm sử dụng trong cơ chế ngăn chặn bằng white list. (Tham khảo thêm tại https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf)

image.png

Ngoài ra trong trường hợp bài lab này còn có một số cách bypass khác:

  • Sử dụng http://abc/@xyz, payload stockApi=http://localhost%252f@stock.weliketoshop.net

image.png

  • Sử dụng http://abc?@xyz, payload stockApi=http://localhost%253f@stock.weliketoshop.net

image.png

Về phần nguyên nhân các payload trên cũng hoạt động xin dành cho bạn đọc tìm hiểu nhé!

Truy cập tới trang /admin

image.png

Thực hiện xóa tài khoản người dùng carlos, bài lab hoàn thành:

image.png

image.png

7. Tấn công lỗ hổng SSRF scan ip, port server nội bộ

Lỗ hổng SSRF có thể được sử dụng để scan ip cũng như port đang mở của server nội bộ, từ đó xác định mục tiêu tấn công hoặc mở rộng cuộc tấn công tới các tài nguyên, server khác.

Chúng ta có thể sử dụng tính năng Intruder trong Burp Suite thực hiện scan, các bạn có thể xem lại bài lab Basic SSRF against another back-end system.

Ngoài ra, một cách tốt hơn là tự động hóa việc scan này bằng script. Ví dụ đoạn mã scan viết bằng ngôn ngữ Python 2 như sau:

import requests
import time

ports = ['80', '1337', '3306', '6379', '8080', '8000']
session = requests.Session()
for i in xrange(255):
    ip = '192.168.1.%d' % i
    for port in ports:
        url = 'http://example.com/?url=http://%s:%s' % (ip, port)
        try:
            res = session.get(url, timeout = 3)
            if len(res.content) > 0:
                print ip, port, 'is open'
        except:
            continue
print 'DONE'

Giả sử trang web http://example.com chứa lỗ hổng SSRF trong việc truyền tham số url qua phương thức GET. Và chúng ta biết địa chỉ ip của server nội bộ nằm trong dải 192.168.1.X. Đoạn code trên thực hiện tìm kiếm ip từ 192.168.1.0 đến 192.168.1.255, mỗi ip scan các port thông dụng trong mảng ports, từ đó tìm ra ip server nội bộ với các port đang mở.

Kết quả có dạng như sau:

image.png

Đối với các request được gửi ở phương thức POST, các bạn có thể lập trình script tương tự như trên.

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


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


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí