- DownloadManager của qBittorrent đã bỏ qua lỗi xác minh chứng chỉ SSL trong khoảng 14 năm 6 tháng, từ ngày 6/4/2010 đến 12/10/2024, khiến nhiều luồng tải xuống trở thành bề mặt tấn công trong các tình huống chặn bắt mạng
- Vấn đề này được gán mã CVE-2024-51774, và để khai thác cần có quyền truy cập MITM hoặc DNS spoofing
- Các đường dẫn dùng DownloadManager như tìm kiếm, tải xuống
.torrent, RSS feed, tải favicon đều bị ảnh hưởng, và có thể chấp nhận cả chứng chỉ hết hạn hoặc tự ký - Lời nhắc cài đặt Python trên Windows và luồng RSS kiểm tra cập nhật có thể dẫn đến tải xuống tệp thực thi hoặc thao túng liên kết cập nhật nếu phản hồi từ URL hard-coded bị thay đổi
- Người dùng nên nâng cấp bằng cách tự tải trực tiếp v5.0.1 qua trình duyệt thay vì dùng lời nhắc cập nhật trong ứng dụng
Vượt qua xác minh chứng chỉ kéo dài hơn 14 năm
- Lớp DownloadManager của qBittorrent đã bỏ qua mọi lỗi xác minh chứng chỉ SSL kể từ commit
9824d86ngày 6/4/2010 - Hành vi mặc định đã được đổi sang xác minh chứng chỉ trong commit
3d9e971ngày 12/10/2024 - Bản phát hành vá lỗi đầu tiên là qBittorrent v5.0.1, được phát hành 2 ngày trước thời điểm bài viết
- Vấn đề này được gán mã CVE-2024-51774
- Điều kiện khai thác là quyền truy cập MITM hoặc DNS spoofing
Bề mặt tấn công rộng do DownloadManager tạo ra
- Phạm vi sử dụng DownloadManager rất rộng, nên các tính năng như tìm kiếm, tải xuống
.torrent, RSS feed, tải favicon đều bị ảnh hưởng - Các đường dẫn này có thể chấp nhận chứng chỉ hết hạn, chứng chỉ tự ký, hoặc chứng chỉ thuộc cả hai trường hợp
- Các đường dẫn ảnh hưởng chính được chia thành cài đặt Python trên Windows, cập nhật phần mềm, RSS feed và bề mặt tấn công của thư viện giải nén
Tải xuống tệp thực thi trong luồng cài đặt Python trên Windows
- Trên Windows, nếu chưa cài Python đủ mới, qBittorrent sẽ hiển thị cửa sổ hỏi người dùng cài đặt hoặc cập nhật Python để dùng plugin tìm kiếm
- Nếu người dùng nhấp vào Yes được chọn mặc định hoặc nhấn Enter, ứng dụng sẽ tải tệp cài đặt Python từ URL
python.orgđược hard-code - Sau khi tải xuống, qBittorrent đổi tên tệp đó thành
.exe, chạy nó, rồi xóa tệp tạm sau khi hoàn tất - Hành vi này tồn tại từ tháng 6/2015 đến nay, ảnh hưởng từ
v3.2.1đếnv5.0.0 - Trên các biến thể hệ điều hành khác, nếu không có Python hoặc Python chưa đủ mới, widget tìm kiếm sẽ bị vô hiệu hóa, và dường như hành vi tương tự không tái hiện
- Ví dụ, tệp thực thi có thể được lưu ở đường dẫn như
C:\Users\_user_\AppData\Local\Temp\is-G61QK.tmp - Có thể do hành vi của
QProcess, hai luồng tệp thực thi có thể được tạo ra, chỉ một luồng kết thúc còn luồng kia vẫn ở trạng thái sleeping
Thao túng URL thông qua RSS kiểm tra cập nhật
- Phiên bản qBittorrent đã cài trên Windows hoặc Linux, nếu không phải tệp
appImage, mặc định sẽ kiểm tra cập nhật khi chạy - Kiểm tra cập nhật được thực hiện bằng cách tải xuống tài liệu XML từ URL RSS Fosshub được hard-code rồi phân tích thông tin phát hành của chương trình
- Nếu tìm thấy trong XML một phiên bản cao hơn phiên bản đang chạy, ứng dụng sẽ trích xuất update URL và có luồng hỏi người dùng có muốn truy cập URL đó hay không, không có bước lọc hay xác minh riêng
- Nếu người dùng chấp nhận lời nhắc, URL đó sẽ được mở bằng trình duyệt mặc định
- Người dùng sẽ kỳ vọng một tệp
.exetrong bối cảnh tin cậy rằng đây là liên kết do phần mềm cung cấp - Nếu kẻ tấn công điều hướng đến một trang chia sẻ tệp như mediafire, người dùng có thể nhận tệp thực thi do kẻ tấn công kiểm soát như thể đó là bản nâng cấp
- Vì qBittorrent là mã nguồn mở, việc thêm chức năng backdoor vào phiên bản mới nhất rồi biên dịch lại là khá dễ
- Các nhà phát triển cung cấp khóa để xác minh chữ ký nhị phân, nhưng chỉ có hiệu quả bảo vệ nếu người dùng thực sự xác minh và tôn trọng kết quả xác minh thất bại
RSS feed và chèn liên kết
- Mọi RSS feed mà ứng dụng phân tích đều đi qua DownloadManager, nên có thể bị hijack
- Các URL mà nạn nhân truy cập có thể bị quan sát và lập danh sách; về bản chất, URL RSS thường tĩnh và tồn tại lâu dài
- Phần tử
linkcủa từng mục được phân tích trực tiếp, và có thể được tải xuống khi người dùng nhấp đúp - Ngay cả khi không có sửa đổi MITM, một URL tùy ý do tác giả hoặc kẻ tấn công đầu độc feed đưa vào RSS feed mà người dùng đăng ký cũng có thể được mở chỉ bằng một cú nhấp đúp
- CVE-2019-13640 là lỗ hổng từng cho phép thực thi lệnh từ xa thông qua ký tự meta shell trong tên torrent hoặc tham số tracker hiện tại; kẻ tấn công MITM có thể đưa dữ liệu độc hại vào RSS, làm tăng rủi ro khi kết hợp
Tải xuống cơ sở dữ liệu GeoIP và bề mặt tấn công giải nén
- Khi chạy, qBittorrent mặc định tự động tải xuống và giải nén cơ sở dữ liệu MaxMind GeoIP nhị phân có phần mở rộng
.gztừ một URL được hard-code - Nếu có lỗ hổng trong giải nén zlib, kẻ tấn công có thể nhắm vào bề mặt tấn công này bằng tệp tùy ý có kích thước tối đa 64MB
- CVE-2022-37434 được nêu làm ví dụ là lỗi tràn bộ đệm CVSS 9.8 Critical năm 2022, nhưng không áp dụng ở đây vì hàm
inflateGetHeader()không được gọi - Mã phân tích cơ sở dữ liệu MaxMind nhị phân sau khi giải nén được bảo vệ tốt tính đến năm 2024, nhưng trong quá khứ thì khác và có thể từng tồn tại bề mặt tấn công bổ sung
- Trong một commit của hàm
gzip::decompress(), buffer đích đã được đổi từ cấp phát tĩnh trên stack sang cấp phát động trên heap; có kiểm tra trước khi ghi nên không thể khai thác
Kịch bản tấn công có thể tự động hóa
- Vì cả URL tệp cài đặt Python lẫn URL RSS cập nhật đều được hard-code, một script độc hại trong môi trường MITM có thể liệt kê các phiên bản dễ bị tấn công để khai thác
- URL RSS feed không có lý do để được truy cập trừ khi qBittorrent đang chạy, nên có thể dùng làm dấu vân tay phần mềm
- Do không có xác minh chứng chỉ, kẻ tấn công có thể spoof máy chủ mục tiêu mà không cần triển khai Man-On-The-Side phức tạp như QUANTUM
- Do đặc tính URL hard-coded, nạn nhân sẽ không được cảnh báo bởi lỗi kết nối bảo mật từ trình duyệt hoặc ứng dụng khác; kẻ tấn công có thể chỉ chặn có chọn lọc các yêu cầu không được qBittorrent xác minh
- Khi dùng tùy chọn
-scủa mitmproxy cùng script Python, có thể tự động hóa các hành vi sau- Thay tệp
.exePython bằng tệp thực thi tùy ý: RCE chỉ với một cú nhấp - Tự động thay URL trong RSS cập nhật qBittorrent: hijack trình duyệt/RCE, cần mức tương tác người dùng trung bình
- Thay toàn bộ hoặc một số liên kết cụ thể trong trình xem RSS của qBittorrent: RCE cho đến năm 2019, hijack tải xuống
- Thay tệp
Nâng cấp và cách giảm thiểu
- Cần nâng cấp lên qBittorrent v5.0.1
- Khuyến nghị nâng cấp bằng cách tự tải trực tiếp qua trình duyệt, không dùng lời nhắc cập nhật trong ứng dụng
- Một phương án thay thế là dùng các client không có lỗ hổng này như Deluge, Transmission
- Khó có thể xem các cuộc tấn công cần MITM chỉ là rủi ro lý thuyết; cần cân nhắc lịch sử gần đây và các trường hợp thực tế ở một số quốc gia
- Đã có liên hệ với maintainer của kho lưu trữ, nhưng chưa nhận được phản hồi về việc họ có ý định phát hành khuyến cáo bảo mật trên GitHub hay không
1 bình luận
Ý kiến trên Hacker News
Lớp DownloadManager của qBittorrent đã bỏ qua mọi lỗi xác minh chứng chỉ SSL xảy ra trên mọi nền tảng trong suốt 14 năm 6 tháng kể từ commit 9824d86 ngày 6/4/2010
Trông khá nghiêm trọng
Điểm đáng chú ý là đây không phải bug mà là “tính năng”
void downloadThread::ignoreSslErrors(QNetworkReply* reply,QList errors) {
// Ignore all SSL errors
reply->ignoreSslErrors(errors);
}
https://github.com/qbittorrent/qBittorrent/commit/9824d86a3c...
Không có ý xem nhẹ lỗ hổng này, nhưng tôi cho rằng việc chỉ dựa vào cặp chứng chỉ TLS hợp lệ và tên miền làm tuyến phòng thủ duy nhất trên một đường dẫn có thể dẫn tới thực thi mã từ xa gần như là thảm họa
Tối thiểu, nếu ứng dụng tải một artifact nào đó từ Internet rồi chạy nó, thì nên ghim vào một phiên bản cụ thể và xác minh hash của tệp đã tải trước khi thực thi
Vậy có nghĩa là không thể cập nhật tự động sao?
Tôi nghĩ tiêu chuẩn tối thiểu là xác minh chữ ký
Nếu phần mềm được cập nhật đủ thường xuyên thì cũng sẽ có đủ cơ hội để thay khóa
Trên Windows, có thể dùng chứng chỉ ký mã trong công cụ build và để hệ điều hành xác minh binary đã tải xuống
Tuy nhiên, khi ký mã nhất thiết phải dùng máy chủ timestamp thì mới không bị hỏng sau khi chứng chỉ hết hạn
Trong trường hợp này, tôi nghĩ kiểm tra hash là khó vì bản chất tiềm ẩn của tấn công trung gian
Nếu kẻ tấn công có thể xem và sửa nội dung yêu cầu thì kiểm tra hash cũng không còn hữu ích ngoài việc kiểm tra tính toàn vẹn
Nhìn chung, cách các ứng dụng desktop gửi yêu cầu cập nhật tự động hoặc kiểm tra tới một domain cụ thể dường như chưa được chú ý đủ từ góc độ bảo mật
Cũng có các kịch bản như tác giả ban đầu ngừng gia hạn domain và nó bị chiếm đoạt theo hướng thù địch, nhưng tôi vẫn chưa tìm được giải pháp tốt
Sẽ rất đáng ngạc nhiên nếu có thể biết trong khoảng 15 năm qua thực sự có bao nhiêu người bị ảnh hưởng bởi vấn đề này
Tôi tự hỏi xác minh SSL quan trọng đến mức nào với một kẻ tấn công có thể hòa lẫn vào đám đông ngay cả ở những góc hơi đáng ngờ của Internet
Quá nhiều thứ “cứ thế chạy được” là vì chẳng ai để tâm, và giờ vấn đề này đã được soi chiếu thì tình hình chắc chắn sẽ tệ hơn với những người không cập nhật tự động
Đoạn mã này dùng để tải Python từ python.org; có thể bị khai thác, nhưng phải khá nhắm mục tiêu và có lẽ đã cần một mức quyền truy cập nào đó tới mục tiêu
Muốn khai thác theo cách khác thì cần những chuyện như chiếm domain python.org, thứ mà khả năng cao mọi người sẽ nhận ra
Nếu có bị ảnh hưởng thì phần lớn khả năng là tấn công có chủ đích
Phần lớn bài viết có cảm giác bị thổi phồng; đúng là có vấn đề gì đó, nhưng cách gọi “thực thi mã từ xa trong qBittorrent” dù về mặt kỹ thuật là đúng, lại cảnh báo quá mức
Có vẻ gần như không thể có được dữ liệu thực tế, nhưng nếu xem được thì chắc sẽ thú vị
Nếu từng xem mã nguồn qBittorrent thì bạn sẽ biết đó thực sự là mã kinh khủng
Những hàm không có chú thích kéo dài vài trang, dòng chữ dày đặc, trông như ghi chép trong tù của một bệnh nhân tâm thần bị giam oan
Ngay cả trong phần nhỏ tôi xem, chỉ vài trang nén lại, cũng hoàn toàn không có kiểm tra giá trị trả về
Tôi nhớ rằng nếu một trường nào đó nhận một giá trị 3 ký tự hợp lệ thay vì giá trị 2 ký tự đúng thường lệ, khoảng một phút sau chương trình sẽ crash hoặc gì đó tương tự
Khoảng 20 năm trước tôi từng hai lần được trả tiền để lập trình bằng C++, và sau khi nhận được tin nhắn của maintainer kiểu “vậy anh tự xem thử đi”, tôi đã chạy nó bằng debugger
Tôi đã lần tới được điểm trong GUI nơi giá trị sai và giá trị đúng được đọc vào, rồi lần theo giá trị đó thì không biết từ lúc nào -1 đã được truyền đi khắp nơi, còn chương trình thì cứ tiếp tục chạy một thời gian
Cuối cùng nhánh chạy với giá trị sai crash ở một hàm khá xa, kèm thông báo lỗi giống như của một bệnh nhân tâm thần bị giam oan
Sau đó một trong các developer thực sự của qBittorrent đã sửa trong bản phát hành kế tiếp, nhưng dù sao mã khi đó là như vậy
Chỉ ghi “BUGFIX: Don't ignore SSL errors (sledgehammer999)”
https://www.qbittorrent.org/news
Cá nhân tôi nghĩ nên có thông báo bảo mật
Ngay cả khi kiểm tra chứng chỉ đúng cách, việc tải xuống và chạy tệp thực thi từ xa theo định nghĩa vẫn là lỗ hổng thực thi mã từ xa
Syncthing cũng dùng cách này; có lẽ họ có kiểm tra chứng chỉ, nhưng cập nhật tự động không giám sát về mặt logic rất khó phân biệt với RAT/Trojan
Phần “lỗ hổng” xuất hiện khi bên thứ ba có thể khai thác
Dù sao bạn cũng phải tin nhà cung cấp phần mềm, nên bản thân cập nhật tự động không đồng nghĩa với lỗ hổng thực thi mã từ xa
Dù không phải nguyên nhân trực tiếp của lỗ hổng này, các ứng dụng kiểu này giao tiếp với nhiều node có khả năng độc hại có lẽ sẽ hưởng lợi rất lớn từ an toàn bộ nhớ
Tuy nhiên, các triển khai hiện tại trông đều như được viết bằng C++
Bài viết cũng đề cập đến loại khả năng dễ bị tổn thương này ở mục 4
Ngay cả Deluge viết bằng Python cũng phụ thuộc vào libtorrent viết bằng C++
Không rõ hiện có fork hiện đại nào của client Azureus cũ dựa trên Java hay không
Dạo này nhiều client BitTorrent tách riêng GUI và tiến trình daemon đảm nhiệm việc xử lý torrent thực tế, nên nếu làm daemon bằng Java rồi kết nối với GUI native thì có thể đạt được sự cân bằng khá ổn giữa bảo mật, hiệu năng và trải nghiệm người dùng
Tìm sơ qua cũng thấy có vài thư viện BitTorrent thuần Go
Có rqbit viết bằng Rust và không phụ thuộc vào libtorrent: https://github.com/ikatson/rqbit
Thay vì tự tìm để thảo luận, xin hỏi lười một chút: nếu muốn tạo giải pháp thay thế cho libtorrent thì nên bắt đầu từ đâu?
Cũng tò mò liệu đã có nỗ lực hay trường hợp thành công nào chưa, và có client đang hoạt động thực tế nào dùng triển khai khác không
Đặc biệt càng về các mục phía sau thì trông hơi phóng đại
Mục 1, “trình nạp file thực thi độc hại có chức năng ẩn mình”, thực chất là chuyện client tải Python từ python.org qua HTTPS
Điều này không hay, nhất là việc hard-code thành 3.12.4 cũng là vấn đề, nhưng không thấy đường khai thác rõ ràng nào mà không cần cả tấn công trung gian lẫn tương tác của người dùng
Mục 2, “chiếm quyền trình duyệt + tải file thực thi”, là chuyện client tải file RSS qua HTTPS và, tùy điều kiện, hỏi người dùng có muốn mở URL trong file đó không
Rủi ro còn thấp hơn mục 1; ngay cả khi tấn công trung gian người dùng và khiến họ bấm “update” thì cuối cùng thứ có thể hiển thị cũng chỉ là trang web
Mục 3, “chèn URL tùy ý vào RSS feed”, có vẻ nhà nghiên cứu đã nhầm lẫn về hành vi kỳ vọng của RSS client
Mục 4, “bề mặt tấn công của thư viện giải nén”, nếu có thể tìm ra lỗ hổng zlib thì bạn có thể làm những việc tệ hơn nhiều so với tấn công client torrent
Giải nén đầu vào về cơ bản là thao tác được giả định là an toàn
Thứ hiện ra ngay trong đầu là các HTTP server hỗ trợ nén stream
Đúng vậy
Không muốn nói quá tiêu cực, nhưng có vẻ các “nhà nghiên cứu” bảo mật đang bám cả vào những khả năng cực kỳ mong manh để kiếm chút tiếng tăm
Nếu họ ghi tài liệu một cách trung thực thì tôi đã tôn trọng hơn, còn cách làm ở đây chỉ khiến người ta cau mày
Nếu không bỏ qua lỗi chứng chỉ thì các mục đó đã chỉ là chuyện nhỏ
Vấn đề gốc nằm ở việc bỏ qua lỗi SSL, nên trên thực tế mọi lượt tải xuống qua HTTPS đều bị hạ cấp thành tải xuống qua HTTP, và có thể bị tấn công ngay cả khi không có tấn công trung gian
Nói cách khác, vì thiếu xác minh SSL nên các URL HTTPS đã tạo cho người rà soát cảm giác yên tâm sai lầm rằng chúng có bảo mật
Đồng ý
Gọi đây là “lỗ hổng thực thi mã từ xa” thì phóng đại đến mức vô lý
Tiếp theo họ sẽ nói trình duyệt web có “lỗ hổng thực thi mã từ xa” vì nó cho phép tải và chạy chương trình từ các trang tùy ý, có thể an toàn hoặc không chắc?
Hay họ sẽ lại công bố một điều hiển nhiên rằng nếu sống trong một quốc gia độc tài thì chính phủ có thể làm điều xấu?
qBittorrent là client có hiệu năng tốt hơn 1000 lần so với các lựa chọn khác được nêu trong bài, nên thật sốc khi chất lượng của những vấn đề này lại thấp đến vậy
Thứ tạo ra hiệu năng là libtorrent-rasterbar(libtorrent.org)
Nếu muốn biên dịch và chạy phiên bản mới nhất, https://github.com/userdocs/qbittorrent-nox-static là một script hỗ trợ khá ổn, dùng Docker để build binary tĩnh
Tôi muốn chạy 5.0.0 với libtorrent 1.2, và script này là cách dễ nhất vượt trội