+2

Web cache poisoning - Lỗ hổng đầu độc bộ nhớ cache (phần 4)

V. Case study và ví dụ

1. Case study: Redirect DoS

Case study đầu tiên tôi muốn giới thiệu tới các bạn là sự kết hợp lỗ hổng web cache poisoning nhằm tấn công DoS (denial of service) tới người dùng khác thông qua quy trình chuyển hướng request của Cloudflare.

Một đường dẫn đăng nhập của Cloudflare tại dash.cloudflare.com/login, sau khi người dùng đăng nhập, họ được chuyển hướng tới /login/, chú ý rằng đường dẫn đích có thêm một ký tự /. Tác giả James Kettle sau khi quan sát cơ chế caching của ứng dụng, đã phát hiện các tham số gửi kèm trong request được loại bỏ khỏi cache key:

GET /login?x=abc HTTP/1.1
Host: www.cloudflare.com
Origin: https://dontpoisoneveryone/

HTTP/1.1 301 Moved Permanently
Location: /login/?x=abc
GET /login HTTP/1.1
Host: www.cloudflare.com
Origin: https://dontpoisoneveryone/

HTTP/1.1 301 Moved Permanently
Location: /login/?x=abc

Tuy nhiên, ở giá trị header Location vẫn giữ nguyên các tham số này. Bởi vậy, tác giả đã nảy ra ý tưởng sử dụng một tham số có giá trị với kích thước lớn, đạt tới giới hạn cho phép của URL.

GET /login?x=very-long-string... HTTP/1.1
Host: www.cloudflare.com
Origin: https://dontpoisoneveryone/

Như vậy, khi ứng dụng xử lý chuyển hướng, nếu mọi thứ bình thường, header Location được thêm một ký tự / như sau:

HTTP/1.1 301 Moved Permanently
Location: /login/?x=very-long-string...

Bởi URL ban đầu đã đạt đến giới hạn ký tự, nên khi chuyển hướng tới /login/?x=very-long-string... có thêm ký tự / đã vượt qua giới hạn, dẫn đến hệ thống không chấp nhận, trả về response lỗi:

GET /login/?x=very-long-string... HTTP/1.1
Host: www.cloudflare.com
Origin: https://dontpoisoneveryone/

HTTP/1.1 414 Request-URI Too Large
CF-Cache-Status: MISS

Lúc này, khi response được lưu trữ trong hệ thống cache, dẫn đến một cuộc tấn công từ chối dịch vụ tới người dùng sau.

2. Lab Cache key injection

2.1. Thu thập thông tin

Sử dụng extension Param Miner, chúng ta có thể nhận thấy request khi truy cập trang đăng nhập của bài lab cho phép sử dụng param utm_content.

image.png

image.png

Quan sát mã nguồn tại /login, phát hiện tệp tin /js/localize.js:

image.png

image.png

2.2. Phân tích

Chú ý rằng tham số lang=en được đính kèm tại đường dẫn /login/

image.png

Chúng ta có thể thay đổi tùy ý giá trị tham số này, kết quả được hiển thị trong response, sử dụng bởi /js/localize.js:

image.png

Hơn nữa, giống với case study đã phân tích phía trên, khi chúng ta gửi request ở trang đăng nhập với tham số tại /login dạng /login?lang=, ứng dụng thực hiện chuyển hướng trình duyệt tới /login/:

image.png

Ở đây cũng bao gồm cơ chế caching, thử một vài hướng khai thác đã nêu ở các bài viết trước, các bạn sẽ nhận thấy rằng cơ chế caching ở đây có thể tấn công bởi phương pháp Cache parameter cloaking, kết hợp tham số utm_content, chúng ta có thể lưu trữ tài nguyên cache với payload: /login?lang=en?utm_content=viblo, thật vậy:

image.png

Lúc này, tất cả người dùng truy cập đường dẫn /login?lang=en sẽ được chuyển hướng và response trả về chứa dữ liệu caching bị kẻ tấn công control.

image.png

Chuyển hướng tới:

image.png

Tại /js/localize.js, chú ý tham số cors=0 và header Vary trong response cho biết response có thể thay đổi khi request chứa header Origin cho biết nguồn gốc của request, ở đây chúng ta cần thay đổi tham số cors=1 để cho phép điều đó:

image.png

image.png

Đồng thời, tại header Origin chúng ta có thể thực hiện tấn công CRLF:

image.png

Do đó chúng ta có thể sử dụng lỗ hổng CRLF tại đây nhằm thay đổi nội dung response với payload header Origin: x%0d%0aContent-Length:%208%0d%0a%0d%0aalert(1) (lưu ý giá trị tham số cors=1)

image.png

Lúc này, nếu chúng ta có thể khiến trang web sử dụng nội dung file localize.js chứa payload này sẽ có thể thực thi XSS.

Trong bài lab này, chúng ta có thể sử dụng header Pragma: x-get-cache-key để yêu cầu ứng dụng trả về bộ cache key cho tài nguyên đang truy cập nếu nó đang có sẵn trong bộ nhớ cache.

Với payload XSS đã caching ở phía trên, tìm kiếm bộ cache key của nó:

image.png

Quan sát phản hồi nhận thấy ứng dụng trả về bộ cache key /js/localize.js?lang=en?cors=1&x=1$$origin=x%0d%0aContent-Length:%208%0d%0a%0d%0aalert(1)

Tại đây chúng ta cũng có thể control giá trị bộ cache key này. Ý tưởng rõ ràng hơn: nếu ứng dụng trả về response tương ứng với bộ cache key này, payload XSS sẽ được thực thi.

Cấu tạo của bộ cache key sẽ thêm 22 ký tự $$ vào sau chuỗi URL truy vấn. Thật vậy, kiểm tra bộ cache key khi truy cập /js/localize.js?lang=en?cors=1&x=1$$origin=x%0d%0aContent-Length:%208%0d%0a%0d%0aalert(1):

image.png

Thực hiện lưu trữ cache response có bộ cache key là /js/localize.js?lang=en?cors=1&x=1$$origin=x%0d%0aContent-Length:%208%0d%0a%0d%0aalert(1)$$ bằng cách sử dụng header Origin

image.png

Lúc này khi truy cập /js/localize.js?lang=en?cors=1&x=1$$origin=x%0d%0aContent-Length:%208%0d%0a%0d%0aalert(1) sẽ trả về response tương ứng với bộ cache key /js/localize.js?lang=en?cors=1&x=1$$origin=x%0d%0aContent-Length:%208%0d%0a%0d%0aalert(1)$$, đồng thời chứa payload XSS:

image.png

Mục tiêu cuối cùng của chúng ta là khiến ứng dụng trả về response lấy nội dung tại /js/localize.js?lang=en?cors=1&x=1$$origin=x%0d%0aContent-Length:%208%0d%0a%0d%0aalert(1) chứa payload XSS.

2.3. Tấn công

Bước 11: Kết hợp CRLF, Cache parameter cloaking để lưu trữ payload thực thi XSS:

image.png

Bước 22: Sử dụng Cache parameter cloaking tại /login nhằm cache payload:

image.png

Người dùng truy cập /login?lang=en lúc này:

image.png

Tiếp theo được chuyển hướng đến response chứa dữ liệu caching:

image.png

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í