Dot of Moon
VIP Members
-
17/10/2022
-
0
-
8 bài viết
Khai thác lỗ hổng Pre-Auth RCE bằng CodeQL chỉ trong 20 phút
Bài viết này sẽ nói về một công cụ hỗ trợ khai thác lỗ hổng Pre-Auth RCE là CodeQL. Đây là 1 phần mềm kiểm tra lỗ hổng liên quan đến database cho anh em làm code.
Mục tiêu của chúng ta hôm nay là pgAdmin. Hầu như tất cả những người từng học công nghệ thông tin code sơ qua về web cũng đều đã sử dụng framework này. Nói sơ qua một chút, pgAdmin là nền tảng quản trị và phát triển nguồn mở phong phú và phổ biến nhất dành cho PostgreSQL.
CodeQL cần một cơ sở dữ liệu chứa mã ở định dạng có cấu trúc tùy thuộc vào ngôn ngữ mục tiêu. Ví dụ đối với Java, nhìn vào dự án pgAdmin GitHub thì ngôn ngữ chính là Python. May mắn thay, CodeQL cũng hỗ trợ ngôn ngữ này.
Vì https://lgtm.com/ sẽ ngừng hoạt động nên việc tìm nạp cơ sở dữ liệu CodeQL sẵn sàng hoạt động từ nền tảng này sẽ không còn là một tùy chọn nữa.
Hãy cài CodeQL trên tiện ích của Visual Studio Code:
Một nút mới ở thanh bên trái sẽ xuất hiện có tên là QL. Tiếp theo tìm nạp phiên bản 6.16 mới nhất của pgAdmin (tại thời điểm phát hiện lỗ hổng) từ GitHub. Lập tức thư mục web có nhiều tệp Python, một phần của ứng dụng web.
Nếu quá trình cài đặt tiện ích mở rộng CodeQL hoàn tất đúng cách, bạn sẽ thấy tệp CodeQL CLI tại một số vị trí như:
Đặt alias, điều chỉnh .bashrc,... phù hợp với nhu cầu của bạn.
Tạo một thư mục mới “pgadmincodeql” và đưa cơ sở dữ liệu này vào VS Code bằng menu QL.
Chọn thư mục mới tạo và cơ sở dữ liệu sẽ xuất hiện trong VS Code. Sau đó đặt mặc định bằng cách nhấp vào đến khi hiển thị dấu màu xám.
Trong VS Code Explorer hiển thị dự án CodeQL GitHub và tiếp tục “codeql/python/ql/src/Security” sẽ tìm thấy tất cả những cung cấp các truy vấn thông minh đối với cơ sở dữ liệu. Đặc biệt hãy để ý đến các truy vấn:
Hãy mở tệp này và sau đó chỉ cần nhấn CodeQL. Chạy truy vấn cần mất một chút thời gian nên hãy đi lấy 1 cốc cà phê rồi quay lại xem kết quả nhé!
CodeQL giúp ta nhận ra rằng request từ flask thư viện Python được sử dụng trên tất cả các mã, ví dụ đọc từ request.data. Hãy xem xét kỹ hơn về hàm sink.
Tại [1], trình xử lý tuyến HTTP được xác định với /validate_binary_path là phần URI tương ứng để kích hoạt mã.
Hi vọng sẽ xuất hiện dưới dạng yêu cầu POST. request.data được đọc và tại [2] tham số nội dung POST của tiện ích_path được xử lý trong khối if.
Hãy bỏ qua chức năng tại [3]. Nhưng tại [4], một constant có tên UTILITIES_ARRAY dường như hạn chế rất nhiều đầu vào cuối cùng, sau đó được đưa vào lệnh gọi quy trình con. constants.py cho biết UTILITIES_ARRAY = ['pg_dump', 'pg_dumpall', 'pg_restore', 'psql'].
Tại [5] chúng ta vẫn kiểm soát biến binary_path nhưng là đường dẫn chứ không phải tên tệp đang được thực thi trong phần nguy hiểm cuối cùng ở [6].
Ngoài ra, có thể thấy mô-đun jar_login cung cấp chú thích @login_required (kiểm tra các tuyến khác của ứng dụng web) để kiểm tra ngữ cảnh được xác thực.
Nhưng ở đây là Python và hướng dẫn thiết lập chế độ Máy chủ đã được đề cập ở phần đầu cùng mô tả cài đặt trên Windows, nên mình sẽ không đi vào hướng dẫn chi tiết từng bước để cài đặt pgAdmin vì nó sẽ mất thêm 3 tiếng nữa.
Nếu đủ kiên nhẫn, bạn có thể thử sử dụng Python CLI trên Windows để kiểm tra sau khi sử dụng đường dẫn UNC đến chia sẻ từ xa trong os.path.abspath(os.path.join(...)) và tệp sẽ được truy xuất, có thể đọc hay gọi.
Hãy thử thiết lập máy chủ SMB trên máy tấn công Linux bằng cách sử dụng bộ Impacket phổ biến.
Trong thư mục tmp tạo một tệp được đặt tên ngẫu nhiên từ danh sách UTILITIES_ARRAY, ví dụ pg_dump[.exe]
Chà, không phải nội dung hoàn toàn ngẫu nhiên, chúng ta muốn làm điều đó ngay lần đầu tiên. Vì vậy, hãy tạo một tệp .exe bằng trình biên dịch chéo (cross compiler) mingw và pg_dump.c như thế này.
Bây giờ POST /misc/validate_binary_path HTTP/1.1 sẽ kích hoạt đường dẫn mã dễ bị tấn công. Tùy thuộc vào cài đặt Windows pgAdmin, trước tiên tìm nạp Cookie và mã thông báo CSRF từ thư mục / đến /login hoặc /browser. Nó có thể áp dụng cho bất kỳ loại cài đặt nào, giả sử bạn có thể truy xuất nội dung cho X-pgA-CSRFToken. Payload cuối cùng sẽ như hình minh họa bên dưới.
Sau khi kích hoạt payload sẽ thấy một kết nối SMB đến thiết bị của kẻ tấn công đang truy xuất (các) tệp pg_dump.exe: RCE Pre-Auth.
Bối cảnh chưa được xác thực đã được vá. Nhưng với cách khai thác tương tự thì vẫn nên hoạt động trong bối cảnh được xác thực.
Mục tiêu của chúng ta hôm nay là pgAdmin. Hầu như tất cả những người từng học công nghệ thông tin code sơ qua về web cũng đều đã sử dụng framework này. Nói sơ qua một chút, pgAdmin là nền tảng quản trị và phát triển nguồn mở phong phú và phổ biến nhất dành cho PostgreSQL.
CodeQL cần một cơ sở dữ liệu chứa mã ở định dạng có cấu trúc tùy thuộc vào ngôn ngữ mục tiêu. Ví dụ đối với Java, nhìn vào dự án pgAdmin GitHub thì ngôn ngữ chính là Python. May mắn thay, CodeQL cũng hỗ trợ ngôn ngữ này.
Vì https://lgtm.com/ sẽ ngừng hoạt động nên việc tìm nạp cơ sở dữ liệu CodeQL sẵn sàng hoạt động từ nền tảng này sẽ không còn là một tùy chọn nữa.
Hãy cài CodeQL trên tiện ích của Visual Studio Code:
Một nút mới ở thanh bên trái sẽ xuất hiện có tên là QL. Tiếp theo tìm nạp phiên bản 6.16 mới nhất của pgAdmin (tại thời điểm phát hiện lỗ hổng) từ GitHub. Lập tức thư mục web có nhiều tệp Python, một phần của ứng dụng web.
Nếu quá trình cài đặt tiện ích mở rộng CodeQL hoàn tất đúng cách, bạn sẽ thấy tệp CodeQL CLI tại một số vị trí như:
$HOME/.config/Code/User/globalStorage/github.vscode-codeql/distribution2/codeql/codeql
Đặt alias, điều chỉnh .bashrc,... phù hợp với nhu cầu của bạn.
Tạo một thư mục mới “pgadmincodeql” và đưa cơ sở dữ liệu này vào VS Code bằng menu QL.
Chọn thư mục mới tạo và cơ sở dữ liệu sẽ xuất hiện trong VS Code. Sau đó đặt mặc định bằng cách nhấp vào đến khi hiển thị dấu màu xám.
Tìm lỗ hổng với CodeQL
Tìm lỗ hổng trong vòng 20 phút? Bao gồm cả việc tải xuống nguồn pgAdmin, cài đặt tiện ích mở rộng VS Code, tạo cơ sở dữ liệu CodeQL, sao chép kho lưu trữ CodeQL GitHub và bắt đầu truy vấn CodeQL dựng sẵn.Trong VS Code Explorer hiển thị dự án CodeQL GitHub và tiếp tục “codeql/python/ql/src/Security” sẽ tìm thấy tất cả những cung cấp các truy vấn thông minh đối với cơ sở dữ liệu. Đặc biệt hãy để ý đến các truy vấn:
- Cho phép duyệt một lúc nhiều lệnh nguy hiểm.
- Thay vì “chỉ” hiển thị kết nối nguy hiểm tiềm ẩn, thì phải hiển thị đồng thời cả thông tin hành vi hoặc câu lệnh truy vấn từ kết nối đó.
codeql/python/ql/src/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.ql
Hãy mở tệp này và sau đó chỉ cần nhấn CodeQL. Chạy truy vấn cần mất một chút thời gian nên hãy đi lấy 1 cốc cà phê rồi quay lại xem kết quả nhé!
CodeQL giúp ta nhận ra rằng request từ flask thư viện Python được sử dụng trên tất cả các mã, ví dụ đọc từ request.data. Hãy xem xét kỹ hơn về hàm sink.
Tại [1], trình xử lý tuyến HTTP được xác định với /validate_binary_path là phần URI tương ứng để kích hoạt mã.
Hi vọng sẽ xuất hiện dưới dạng yêu cầu POST. request.data được đọc và tại [2] tham số nội dung POST của tiện ích_path được xử lý trong khối if.
Hãy bỏ qua chức năng tại [3]. Nhưng tại [4], một constant có tên UTILITIES_ARRAY dường như hạn chế rất nhiều đầu vào cuối cùng, sau đó được đưa vào lệnh gọi quy trình con. constants.py cho biết UTILITIES_ARRAY = ['pg_dump', 'pg_dumpall', 'pg_restore', 'psql'].
Tại [5] chúng ta vẫn kiểm soát biến binary_path nhưng là đường dẫn chứ không phải tên tệp đang được thực thi trong phần nguy hiểm cuối cùng ở [6].
Ngoài ra, có thể thấy mô-đun jar_login cung cấp chú thích @login_required (kiểm tra các tuyến khác của ứng dụng web) để kiểm tra ngữ cảnh được xác thực.
Nhưng ở đây là Python và hướng dẫn thiết lập chế độ Máy chủ đã được đề cập ở phần đầu cùng mô tả cài đặt trên Windows, nên mình sẽ không đi vào hướng dẫn chi tiết từng bước để cài đặt pgAdmin vì nó sẽ mất thêm 3 tiếng nữa.
Nếu đủ kiên nhẫn, bạn có thể thử sử dụng Python CLI trên Windows để kiểm tra sau khi sử dụng đường dẫn UNC đến chia sẻ từ xa trong os.path.abspath(os.path.join(...)) và tệp sẽ được truy xuất, có thể đọc hay gọi.
Hãy thử thiết lập máy chủ SMB trên máy tấn công Linux bằng cách sử dụng bộ Impacket phổ biến.
./smbserver.py myshare $HOME/tmp
Trong thư mục tmp tạo một tệp được đặt tên ngẫu nhiên từ danh sách UTILITIES_ARRAY, ví dụ pg_dump[.exe]
Chà, không phải nội dung hoàn toàn ngẫu nhiên, chúng ta muốn làm điều đó ngay lần đầu tiên. Vì vậy, hãy tạo một tệp .exe bằng trình biên dịch chéo (cross compiler) mingw và pg_dump.c như thế này.
Bây giờ POST /misc/validate_binary_path HTTP/1.1 sẽ kích hoạt đường dẫn mã dễ bị tấn công. Tùy thuộc vào cài đặt Windows pgAdmin, trước tiên tìm nạp Cookie và mã thông báo CSRF từ thư mục / đến /login hoặc /browser. Nó có thể áp dụng cho bất kỳ loại cài đặt nào, giả sử bạn có thể truy xuất nội dung cho X-pgA-CSRFToken. Payload cuối cùng sẽ như hình minh họa bên dưới.
Sau khi kích hoạt payload sẽ thấy một kết nối SMB đến thiết bị của kẻ tấn công đang truy xuất (các) tệp pg_dump.exe: RCE Pre-Auth.
Vá lỗi
Nhóm pgAdmin đã xác nhận lỗ hổng CVE-2022-4223 và nhanh chóng phát hành phiên bản 6.17. Họ cũng đã bổ sung thêm thông tin về dự án GitHub và thảo luận về việc tạo một tệp SECURITY.md.Bối cảnh chưa được xác thực đã được vá. Nhưng với cách khai thác tương tự thì vẫn nên hoạt động trong bối cảnh được xác thực.
Kết luận
Bạn có thể nghĩ: Việc này dễ như ăn kẹo nên ai cũng có thể làm được. Nhưng hãy áp dụng các công cụ và kiến thức trong infosec để giúp bạn tìm kiếm các lỗ hổng nghiêm trọng. Ngoài ra, bạn nên tìm hiểu kỹ hơn về CodeQL đã nhé!Theo Frycos Security Diary
Chỉnh sửa lần cuối bởi người điều hành: