Kiếm 35.000 USD từ bug bounty trên GitHub Private Pages
(robertchen.cc)Câu chuyện một học sinh lớp 12, vì có nhiều thời gian rảnh do Covid nên đi săn bug bounty và nhận được 35.000 USD từ bug bounty của trang private pages trên GitHub.
Người này đã báo cáo bug bounty trên trang private pages của GitHub và có hai khoản thưởng CTF bổ sung.
-
10.000 USD: đọc được flag từ
flag.private-org.github.iomà không cần tương tác của người dùng. Nếu có thể đọc flag này từ một tài khoản ở ngoài tổ chứcprivate-orgthì có thêm khoản thưởng bổ sung 5.000 USD. -
5.000 USD: đọc được flag từ
flag.private-org.github.iothông qua tương tác của người dùng.
Luồng xác thực
GitHub Pages được lưu trữ trên tên miền riêng github.io, nên cookie xác thực của github.com không được gửi tới máy chủ private pages. Vì vậy, việc xác thực cho private pages không thể biết danh tính người dùng nếu không có tích hợp bổ sung với github.com. Do đó GitHub đã tạo một luồng xác thực tùy chỉnh.
-
Khi truy cập một private page, máy chủ sẽ kiểm tra sự tồn tại của cookie
__Host-gh_pages_token. -
Nếu cookie không tồn tại hoặc không hợp lệ, máy chủ private page sẽ chuyển hướng tới
https://github.com/login. -
Việc chuyển hướng này cũng đặt nonce vào cookie
__Host-gh_pages_session.- Cookie này dùng tiền tố cookie
__Host-, nên ngăn JavaScript đặt nó từ nơi không phải tên miền host.
- Cookie này dùng tiền tố cookie
-
/loginchuyển hướng tới/pages/auth?nonce=&page_id=&path=. -
Tại đây, một cookie xác thực tạm thời được tạo từ tham số
tokenđể chuyển chohttps://pages-auth.github.com/redirect. -
/redirecttiếp tục chuyển tiếp tớihttps://repo.org.github.io/__/auth. -
Endpoint cuối cùng này đặt các cookie xác thực
__Host-gh_pages_tokenvà__Host-gh_pages_idtrên tên miềnrepo.org.github.io. -
Tại đây,
noncetrong__Host-gh_pages_sessionđã được đặt trước đó cũng được kiểm tra.
Đường dẫn yêu cầu ban đầu và page ID được lưu lần lượt trong các tham số truy vấn path, page_id, còn nonce được lưu trong tham số nonce.
Khai thác
Trả về CRLF
-
Lỗ hổng đầu tiên là chèn CRLF vào tham số
page_idcủahttps://repo.org.github.io/__/auth. -
Tác giả phát hiện việc phân tích
page_idbỏ qua ký tự khoảng trắng và giá trị này được đặt thẳng vào headerSet-Cookie. -
Có thể phá vỡ quá trình phân tích bằng kiểu chèn CRLF truyền thống, nhưng không tạo thêm ảnh hưởng nào khác.
-
Vì header
Location:được thêm sau headerSet-Cookie, nên dù là chuyển hướng 302 thì header Location vẫn bị bỏ qua và phần thân được render.
Tấn công
-
Sau khi xem mã GitHub Enterprise, tác giả biết rằng máy chủ private page được triển khai bằng openresty nginx.
-
Bằng cách thêm null byte, tác giả đã thực hiện XSS thành công. Null byte này phải nằm ở đầu phần body nên không thể thực hiện tấn công chèn header.
-
Từ đây, có thể thực thi mã JavaScript tùy ý trên tên miền private page.
-
Việc còn lại là tìm cách vượt qua nonce.
Vượt qua nonce
-
Qua quan sát, tác giả phát hiện các sibling private page trong cùng một tổ chức có thể đặt cookie cho nhau.
-
Cookie được đặt trên
private-org.github.iosẽ được gửi tớiprivate-page.private-org.github.io. -
Nếu có thể vượt qua lớp bảo vệ của tiền tố
__Host-thì có thể dễ dàng vượt nonce. -
Không phải mọi trình duyệt đều hỗ trợ điều này, và IE không hỗ trợ tiền tố
__Host-. -
Nhưng trong lúc tìm cách tốt hơn, tác giả nảy ra một ý tưởng thú vị.
-
Sau khi kiểm tra cách cookie xử lý chữ hoa chữ thường, tác giả phát hiện
__HOSTvà__Hostđược xử lý khác nhau, còn GitHub private pages thì bỏ qua chữ hoa khi phân tích cookie. -
Nhờ đó có thể chỉ định nonce bằng JavaScript.
-
Tác giả nhận thêm khoản thưởng 5.000 USD.
Đầu độc cache
-
Phản hồi của endpoint
/__/auth?được cache bằng giá trị số nguyên củapage_idbị giả mạo. -
Nhờ đó, nếu đầu độc cache thành công bằng payload XSS thì cả những người dùng không tương tác cũng sẽ bị ảnh hưởng.
-
Nếu kẻ tấn công nhắm vào
unprivileged.org.github.iođể đầu độc luồng xác thực, payload XSS sẽ được cache. -
Vì cookie được chia sẻ ở tên miền cha
org.github.io, kẻ tấn công cũng có thể nhắm vàoprivileged.org.github.io.
Private page công khai
-
Để nhận khoản thưởng bổ sung 15.000 USD, cần khiến một người dùng không thuộc tổ chức thực hiện cuộc tấn công này.
-
Điều đó có thể thực hiện được nhờ một cấu hình sai khi thiết lập private pages trên kho lưu trữ public.
- Tức là tạo pages trên một repo private rồi sau đó chuyển kho lưu trữ sang public.
-
Private page bị cấu hình sai này sẽ đưa mọi người dùng vào luồng xác thực và cho phép người dùng ngoài tổ chức có quyền đọc.
Chưa có bình luận nào.