Năm trước, Zero Day Initiative đã công bố hai lỗ hổng bảo mật nghiêm trọng vượt qua xác thực, là ZDI-20-1176 (ZDI-CAN-10754) và ZDI-20-1451 (ZDI-CAN-11355) ảnh hưởng đến nhiều sản phẩn NETGEAR. Cả hai lỗ hổng này đều nằm trong máy chủ web mini_httpd và được phát hiện bởi chuyên gia bảo mật NHH đến từ Công ty An ninh mạng Viettel và một chuyên gia ẩn danh khác. Cả hai lỗ hổng này đều có nguyên nhân gốc rễ tương tự và được định vị rất gần nhau. Tuy nhiên, hai nhà nghiên cứu đã xác định các lỗ hổng tương tự này trong hai nhóm bộ định tuyến khác nhau và có cách tiếp cận không trùng lặp trong quá trình nghiên cứu.

Do đó, bài viết sẽ so sánh, đối chiếu cách hai chuyên gia bảo mật nghiên cứu , tiếp cận cùng một vấn đề nhưng với phương thức hoàn toàn khác biệt: White box và Blackbox. Phương thức nghiên cứu cũng có thể coi là chiến thuật được các chuyên gia lựa chọn trong quá trình nghiên cứu lỗ hổng bảo mật nhắm tối ứu hóa thời gian cũng như hiệu quả đạt được.

Thông tin về các lỗ hổng bảo mật (Vulnerabilities)

Nhờ các yêu cầu của giấy phép public GNU (GPL), NETGEAR đã công khai các mã nguồn firmware của họ. Hai lỗ hổng này có thể được hiểu theo cách đơn giản nhất bằng cách phân tích mã nguồn firmware do NETGEAR cung cấp. Trong bài này, chúng tôi sẽ phân tích GPL firmware phiên bản 1.0.0.72 của bộ định tuyến (router) NETGEAR R6120.

Dựa trên mã nguồn firmware, chúng ta có thể thấy máy chủ web hoạt động trên phiên bản 1.24 của mini_http open-source project. Các lỗ hổng bảo mật chỉ nằm trong code proprietary (code custom) của NETGEAR nên không ảnh hưởng đến phiên bản máy chủ web gốc.

Hàm main () nằm trong mini_http.c. Hàm này chịu trách nhiệm thiết lập các sockets, SSL handler và listen-loop. Để xử lí đồng thời các yêu cầu HTTP, máy chủ web tự fork khi nhận được kết nối TCP để xử lí từng kết nối riêng lẻ trong một tiến trình con. Đây là hàm main () đã chỉnh sửa của mini_http từ mã nguồn firmware GPL của NETGEAR:

Hàm handle_request () bắt đầu từ dòng 1502, sau đó sẽ tiếp quản và xử lí tất cả quá trình xử lí HTTP sau khi fork.

Đầu tiên, hàm khởi tạo một số biến và tiếp tục đọc trong dòng yêu cầu của một yêu cầu HTTP từ socket tại dòng 1608 bằng cách sử dụng hàm helper get_request_line(). Sau đó, hàm handle_request () tiến hành sử dụng strpbrk() để tách phương thức yêu cầu HTTP khỏi dòng yêu cầu. Phần còn lại của dòng yêu cầu được lưu trữ trong đường dẫn có tên biến ở dòng 1611 và hàm tiếp tục xử lí đường dẫn yêu cầu và yêu cầu.

Mọi thứ trở nên thú vị và đáng chú ý bắt đầu từ dòng 2106, trong đó, đầu tiên câu lệnh if đa điều kiện sẽ kiếm tra xem đường dẫn có khớp với một trong các chuỗi trong mảng no_check_passwd_paths hay không. Điều này được thể hiện tại dòng 409 với path_exists() (được thể hiện trong sc_util.c). Câu lệnh if cũng kiểm tra xem biến đường dẫn có chứa chuỗi con “PNPX_GetShareFolderList” hay không. Nếu một trong hai điều kiện này được đáp ứng, biến need_auth được đặt thành 0. Biến need_auth thực hiện đúng chức năng như tên gọi. Khi được đặt thành 0, nó sẽ bỏ qua việc xác thực. Đoạn mã sau sẽ cho biết cách mảng chuỗi no_check_passwd_paths được xác định:

Một người đọc tinh ý và có trình độ sẽ phát hiện ra lỗ hổng bảo mật từ thời điểm này. Từ main () đến handle_request (), chương trình không tính đến việc xử lí trường hợp khi HTTP parameter nằm trong HTTP method, target hoặc HTTP version. Nếu kẻ tấn công gửi một yêu cầu HTTP với tham số yêu cầu chứa bất kì chuỗi nào trong mảng no_check_passwd_paths, kẻ tấn công có thể đáp ứng điều kiện if được xác định tại dòng 2016 và bỏ qua xác thực.

POC và quá trình khai thác lỗi

Nhà nghiên cứu ẩn danh đã cung cấp một PoC đơn giản để mô tả lỗ hổng bảo mật (ZDI-20-1176):

PoC này cho phép kẻ tấn công xem trang sau xác thực passwordrecovered.htm mà không cần phải thực hiệu quá trình xác thực POC có thể được kiểm tra đơn giản chỉ bằng điều hướng đến đường dẫn trên trong trình duyệt.

Cuối cùng, nhà nghiên cứu ẩn danh đã cung cấp thêm một PoC cho phép kẻ tấn công xem mật khẩu admin của thiết bị định tuyến và giành toàn quyền kiểm soát, điều khiển thiết bị.

Đối với ZDI-20-1451, chuyên gia NHH nhận thấy rằng chương trình chưa thực sự phân tích cú pháp phiên bản HTTP trong biến đường dẫn và họ chỉ cần nối nó vào cuối phiên bản HTTP trong một yêu cầu và đáp ứng điều kiện if được xác định tại dòng 2110 để bỏ qua xác thực thì strstr () chất phát sẽ khớp với “PNPX_GetShareFolderList”.

Sau đó, chuyên gia NHH đã xâu chuỗi lỗ hổng này bằng một lệnh injection sau xác thực ZDI-20-1423 (ZDI-CAN-11653) để giành toàn quyền kiểm soát thiết bị.

Ưu điểm và giới hạn trong phương pháp săn tìm lỗ hổng bảo mật Whitebox và Blackbox của hai chuyên gia sẽ được phân tích ở bài viết phần tiếp theo.

"Kiểm thử hộp đen (Black box testing) là một phương pháp kiểm thử phần mềm mà việc kiểm tra các chức năng của một ứng dụng không cần quan tâm vào cấu trúc nội bộ hoặc hoạt động của nó. Mục đích chính của kiểm tra hộp đen chỉ là để xem phần mềm có hoạt động như dự kiến trong tài liệu yêu cầu và liệu nó có đáp ứng được sự mong đợi của người dùng hay không."
"Kiểm thử hộp trắng hay thử nghiệm kết cấu là loại thử nghiệm được thực hiện để kiểm tra cấu trúc code. Nó còn được gọi là thử nghiệm hộp trắng hoặc thử nghiệm hộp kính. Loại thử nghiệm này đòi hỏi người test phải có kiến thức về code. Do đó, phần lớn là do các lập trình viên, nhà phát triển phần mềm thực hiện."

Nguồn: Zerodayinitiative

Đón đọc phần tiếp theo TẠI ĐÂY.