Kỹ thuật mới để khai thác lỗ hổng thực thi mã từ xa CVE-2019-8942

09:31 | 01/04/2021
TS. Nguyễn Việt Hùng , Hoàng Quốc Trọng (Học viện Kỹ thuật quân sự)

Bài báo này trình bày một kỹ thuật khai thác mới trên lỗ hổng bảo mật CVE-2019-8942, khắc phục điểm yếu của các kỹ thuật khai thác đã có trước đó. Kỹ thuật mới này có thể tấn công trên tất cả trình xử lý ảnh mặc định của Wordpress và có thể khai thác thực thi mã từ xa (RCE), được viết hoàn toàn bằng ngôn ngữ Python cho phép chạy trên đa nền tảng Windows, Linux, MacOS.

GIỚI THIỆU

Các nền tảng hệ thống quản trị nội dung (CMS) như WordPress, Drupal và Joomla đang ngày càng phổ biến và khiến quá trình quản trị nội dung trở nên rất thuận tiện. Tuy nhiên, xu hướng này cũng đi kèm với một rủi ro lớn khi các hệ thống CMS thường là mã nguồn mở, trở thành mục tiêu chủ yếu của kẻ tấn công trong việc tìm ra lỗ hổng bảo mật mới. Kẻ tấn công có thể hiểu toàn bộ mã nguồn của hệ thống và có khả năng tìm ra những lỗ hổng zero-day, sau đó khai thác các trang websites chứa lỗ hổng trong một thời gian dài trước khi bị phát hiện.

Nghiên cứu này sẽ đi sâu phân tích cách khai thác lổ hỗng RCE trên Wordpress với sự kết hợp của các lỗ hổng bao gồm: lỗ hổng Path Traversal CVE-2019-8943, lỗ hổng RCE CVE2019-8942 và kỹ thuật tiêm mã độc vượt qua trình xử lý ảnh GD [3].

LỖ HỔNG BẢO MẬT CVE-2019-8942 TRÊN WORDPRESS

Lỗ hổng RCE trên Wordpress này được tìm ra và công bố trên Ripstech Blog [4] vào ngày 19/02/2019. Lỗ hổng cho phép kẻ tấn công được xác thực với quyền author, có thể thực thi mã tuỳ ý thông qua việc tải lên một ảnh nhiễm mã độc PHP. Lỗ hổng RCE này được khai thác với lộ trình tấn công gồm ba loại lỗ hổng bảo mật khác nhau: Path Traversal, Local File Inclusion trên Wordpress và một kỹ thuật khai thác điểm yếu trong thư viện xử lý ảnh GD của Wordpress. Hình 1 mô tả véc-tơ tấn công lỗ hổng này:

Hình 1. Véc-tơ khai thác lỗ hổng CVE-2019-8942

Kỹ thuật tiêm mã độc PHP vào ảnh jpeg vượt qua trình xử lý ảnh PHP-GD Theo mặc định, Wordpress quản lý các ảnh được tải lên bằng việc sử dụng hai thư viện xử lý ảnh là ImageMagick và GD. Thư viện ImageMagick được ưu tiên trước thư viện GD theo cấu hình mặc định của Wordpress tại hàm: _wp_image_editor_choose().

Hình 2. Cấu hình thư viện xử lý ảnh mặc định của Wordpres

Tính năng đặc biệt của GD là nó luôn xoá toàn bộ phần thông tin Exifdata khỏi tệp ảnh. Điều này khiến việc tiêm mã độc PHP vào ảnh trở nên khó khăn hơn. Để giải quyết vấn đề này, công cụ được viết bởi tác giả Dleg [6] cho phép tạo một ảnh độc hại chứa mã PHP không bị loại bỏ bởi trình xử lý ảnh GD. Công cụ này được phát triển dựa trên kỹ thuật vượt qua hàm xử lý ảnh image-createfromjpeg() của GD [6]. Kỹ thuật này tiêm mã độc vào mục nullbyte phía sau phần Scan Header trong ảnh jpeg. Sau khi được tiêm mã độc, phần dữ liệu tiêm vào của ảnh có dạng như Hình 3.

Hình 3. Mã độc PHP trong ảnh vượt qua trình xử lý ảnh GD

Lợi dụng lỗ hổng này, một ảnh độc hại có thể được tải lên và nó có thể giữ được phần mã độc PHP sau khi bị xử lý bởi thư viện GD. Theo thử nghiệm của chúng tôi, độ dài của đoạn mã độc tiêm vào ảnh jpeg là có giới hạn, chỉ khoảng 26 kí tự được giữ lại toàn vẹn sau khi chạy qua hàm tái tạo ảnh của thư viện GD. Tuy nhiên, 26 kí tự là đủ cho một đoạn mã PHP hỗ trợ thực thi mã từ xa trên hệ thống nạn nhân. Ngoài ra, người ta có thể dễ dàng vượt qua ImageMagick chỉ bằng việc viết mã PHP trực tiếp vào mục Exifdata của bức ảnh như Hình 4.

Hình 4. Mã độc PHP trong phần Exifdata của ảnh

Lỗ hổng Path Traversal CVE-2019-8943 Lỗ hổng CVE-2019-8943 cho phép kẻ tấn công thay đổi Post Meta entry. Phiên bản Wordpress có lỗ hổng sẽ cho phép tuỳ biến entry này khi gửi dữ liệu POST lên Wordpress mà không có kiểm tra chuỗi trong post meta entry. Điểm yếu bảo mật này bắt đầu tại hàm wp- crop-image(), là hàm kiểm soát yêu cầu cắt hình ảnh. Hàm này lấy giá trị ID của ảnh (attachment_id) và truy xuất _wp_attached_file Post Meta entry tương ứng từ cơ sở dữ liệu MySQL, entry này chứa đường dẫn tới ảnh được yêu cầu chỉnh sửa đã lưu trên hệ thống. Tuy nhiên, trường _wp_attached_file có thể bị thay đổi tuỳ ý bởi kẻ tấn công. Khi tên ảnh được thay đổi thành chuỗi tuỳ ý, và nếu tên tệp ảnh đó không tồn tại, Wordpress vẫn cung cấp cách thức để truy xuất ảnh trên máy chủ của nó. Tại hàm wp-crop-image(), Wordpress sẽ xác định sự tồn tại của ảnh được yêu cầu, nó có hai cách để tải ảnh đó như sau:

Cách 1: Dùng _wp_attached_file Post Meta entry được cung cấp để tải ảnh từ thư mục wp-content/uploads trên máy chủ.

Cách 2: Nếu tệp ảnh không tồn tại trên máy chủ, Wordpress cố gắng tải xuống ảnh đó từ chính máy chủ của nó. Lý do tải xuống ảnh thay vì tìm kiếm tệp trong hệ thống máy chủ là vì một số plugins đôi khi lưu ảnh đó khi URL của ảnh được yêu cầu hoặc truy cập tới.

Sau khi được tải, hình ảnh sẽ chạy qua hàm cắt ảnh (của thư viện ImageMagick hoặc GD) và sẽ được lưu trở lại theo đường dẫn cung cấp bởi tham số _wp_attached_file Post Meta entry (entry có thể bị thay đổi bởi kẻ tấn công).

Hình 5. Phần _wp_attached_file Post Meta entry tuỳ biến lưu trong cơ sở dữ liệu MySQL

Vì vậy, nếu tham số _wp_attached_file bị chỉnh sửa thành “h.jpg?/../../h.jpg”, rõ ràng lỗ hổng Path Traversal được khai thác để lưu một ảnh độc hại tới bất kì thư mục nào trên hệ thống Wordpress.

Lỗ hổng Local File Inclusion CVE-2019-8942 Khai thác lỗ hổng CVE-2019-8942 cho phép kẻ tấn công thay đổi tham số _wp-page-template Post Meta entry, đây là một tính năng của Wordpress để người dùng có thể xem một bài đăng (post) với một khuôn mẫu (template) tuỳ chọn.

Mỗi Wordpress template được lưu trữ dưới dạng một thư mục trong thư mục wp-content/themes/. Người dùng với quyền author có thể tuỳ biến template thuộc một chủ đề khi xem một post trên Wordpress bằng cách thay đổi giá trị của tham số _wp_page_template Post Meta entry, chỉ cần nó có tồn tại trong chủ đề đang sử dụng theo mặc định bởi Wordpress.

Để kích hoạt RCE của lỗ hổng CVE-20198942 trên Wordpress, cần phải khiến Wordpress xử lý tệp ảnh jpeg độc hại được tải lên dưới dạng một tệp PHP để thực thi mã độc PHP đã tiêm. 

Hình 6. Giá trị _wp_page_tempate độc hại lưu trong cơ sở dữ liệu.

Thông thường, thư mục chủ đề của Wordpress là riêng tư và không thể truy cập bởi người dùng. Tuy nhiên, bằng việc khai thác lỗ hổng Path Traversal CVE-2019-8943 được miêu tả bên trên, ảnh độc hại có thể được lưu vào đường dẫn thư mục chủ đề và sau đó lỗ hổng CVE2019-8942 sẽ sử dụng nó như một template khi xem post.  Khi người dùng sử dụng trình duyệt để xem post đó, mã độc PHP sẽ được thực thi và dẫn tới RCE.

KỸ THUẬT MỚI ĐỂ KHAI THÁC CVE 2019-8942

Tại thời điểm của nghiên cứu này, đã có hai mã khai thác lỗ hổng CVE-2019-8943 được công bố trên Exploit Database (EDB) với số hiệu 46511[8] và 46662 [9]. Dẫu vậy, hai mã khai thác này tồn tại điểm yếu trong cách vận hành và hiệu quả khai thác.

Mã khai thác EDB-46511

Mã khai thác này được viết bằng ngôn ngữ Javascript bởi tác giả Allyshka, công bố vào ngày 01/3/2019 và chưa được xác minh bởi đội ngũ của EDB.

Việc sử dụng mã khai thác này đòi hỏi người dùng phải mở trình duyệt, đăng nhập thủ công vào trang web Wordpress mục tiêu với tài khoản quyền author. Sau đó, mã khai thác có thể được dán trực tiếp vào giao diện dòng lệnh Javascript của trình duyệt để bắt đầu khai thác. Điểm yếu của mã khai thác này là đòi hỏi hành động thủ công của người dùng, khó khăn trong tự động tấn công đa mục tiêu và mức độ tuỳ biến tham số chưa cao.

Mã EDB-46511 cũng chưa được xác minh bởi đội ngũ của EDB. Mã PHP của ảnh nhiễm độc dùng bởi mã khai thác này cũng bị loại bỏ hoàn toàn bởi trình xử lý ảnh GD trên Wordpress.

Tiến hành thử nghiệm sử dụng mã khai thác này đối với Wordpress phiên bản 4.9.8, sử dụng thư viện GD, cấu hình mặc định, thậm chí không thành công trong bước tấn ông Path Traversal.  Mặc dù không có ảnh độc hại nào được thả vào thư mục chủ đề của Wordpress nhưng vẫn báo thông điệp khai thác thành công và một đường dẫn kích hoạt RCE trên mục tiêu như sau:

Hình 7. Kết quả thử nghiệm mã EDB-46511 với Wordpress 4.9.8 sử dụng thư viện GD

Kiểm tra đường dẫn tới post được cho là kích hoạt RCE cho thấy không có mã PHP nào được thực thi ngoại trừ dòng chữ "RCE-HERE" trong phần nội dung post.

Thực tế, thư viện GD thậm chí không nhận dạng ảnh nhiễm độc dùng bởi mã 46511 này như một tệp ảnh hợp lệ. Do vậy, hình ảnh đó không được cắt để lưu theo tỉ lệ pixel khác ngay khi được tải lên theo cài đặt mặc định của Wordpress.

Vậy, mã khai thác 46511 thất bại trong việc thử nghiệm tấn công Wordpress 4.9.8. Nó không thể khai thác cả hai lỗ hổng Path Traversal và Local File Inclusion trên hệ thống Wordpress mà sử dụng thư viện xử lý ảnh GD.

Mã khai thác EDB-46662

Mã khai thác này viết dưới dạng một module của công cụ Metasploit, công bố trên EDB vào ngày 05/04/2019 và có cờ đã xác minh bởi đội ngũ của EDB. Về cơ bản, mã khai thác này tốt hơn mã khai thác Javascript EDB-46511 phía trên, vì nó hỗ trợ tấn công đồng thời đa mục tiêu, tự động tấn công không cần hành động thủ công của người dùng.

Tiến hành thử nghiệm mã khai thác EDB46662 với website Wordpress sử dụng thư viện GD cho kết quả không thành công.

Hình 8. Kết quả thử nghiệm mã khai thác EDB-46662 với Wordpress 4.9.8 dùng thư viện GD

Sau khi phân tích ảnh độc hại được sử dụng, chúng tôi thấy rằng mã PHP được tiêm vào vẫn tồn tại sau quá trình tái tạo ảnh jpeg của thư viện GD.

Hình 9. Mã PHP trong ảnh độc hại sử dụng bởi EDB-4666

Tuy nhiên, mã khai thác này khai thác không thành công là do nó không thể nhận dạng được tên của ảnh sau khi cắt. Hình ảnh sau khi cắt của thư viện có dạng <tên-ảnh>-456132467.jpg thay vì cropped-<tên-ảnh>.jpg (được sử dụng bởi EDB-46662). Việc này là do mã khai thác chỉ tập trung vào hệ thống Wordpress sử dụng trình xử lý ảnh ImageMagick, tên của ảnh được cắt là khác nhau giữa các thư viện xử lý ảnh của Wordpress. Vì vậy, mã EDB-46662 không thể tìm thấy ảnh được cắt để thả vào trong thư mục chủ đề của Wordpress.

Kết luận, mã khai thác EDB-46662 không thành công trong kịch bản tấn công Wordpress phiên bản 4.9.8 sử dụng thư viện GD làm mặc định. Nó không tìm thấy đường dẫn ảnh bị cắt để tiếp tục véc-tơ tấn công là Path Traversal, vì vậy RCE không được khai thác thành công.

Mã khai thác 2019-8942-rce mới

Phần này giới hiệu một mã khai thác mới (2019-8942-RCE) để khai thác lỗ hổng CVE2019-8942, có thể khắc phục điểm yếu và sự không hoàn thiện của các mã khai thác đã biết.

Về chi tiết, mã khai thác mới viết bằng ngôn ngữ Python, cho phép chạy đa nền tảng hệ điều hành, tấn công đa mục tiêu, tự động hoá toàn bộ quá trình tấn công mà không cần hành động thủ công của người dùng (như mã EDB-46511). Nó cũng cho phép khai thác Path Traversal và RCE thành công bất kể trình xử lý ảnh dùng bởi Wordpress là ImageMagick hay GD. Các mã khai thác đã biết chỉ hoạt động nếu website Wordpress sử dụng thư viện ImageMagick. Mã khai thác mới đã được chúng tôi đăng lên GitHub[4]. Wordpress là ImageMagick hay GD. Các mã khai thác đã biết chỉ hoạt động nếu website Wordpress sử dụng thư viện ImageMagick. Mã khai thác mới đã được chúng tôi đăng lên GitHub[4].

Mã khai thác 2019-8942-RCE sử dụng tên tệp ảnh trích xuất trực tiếp từ kết quả trả về của Wordpress khi tải ảnh lên, vì vậy nó không chứa dòng lệnh tìm kiếm tên ảnh được cắt theo dạng "cropped-<tên-ảnh>.jpg" như các mã khai thác cũ. Điều quan trọng nhất là mã khai thác mới dùng ảnh nhiễm độc tạo bởi kỹ thuật đánh bại trình xử lý ảnh PHP-GD [6], giúp ảnh độc hại có thể vượt qua cả ImageMagick và GD, cho tỉ lệ khai thác thành công cao hơn trên các mục tiêu Wordpress.

Thử nghiệm tấn công sử dụng mã khai thác 2019-8942-rce với website Wordpress 4.9.8 cho kết quả thành công:

Hình 10. Kết quả tấn công của mã khai thác mới

Kiểm tra thư mục chủ đề twentyseventeen trên hệ thống Wordpress mục tiêu, đã khai thác được lỗ hổng Path Traversal để lưu ảnh độc hại vào thư mục chủ đề Wordpress với tên ảnh mới sau khi cắt: h-e1598339686667.jpg

Hình 11. Ảnh độc hại được thả vào chủ đề twentyseventeen của Wordpress

Hình 12. Post kích hoạt RCE với wp_page_template post entry bị thay đổi

Sử dụng trình duyệt mở trang web của post độc hại với tham số _wp_page_template post meta entry sau khi chỉnh sửa để xem kết quả như trong hình trên. Mã khai thác mới đã khai thác lỗ hổng RCE trên Wordpress thành công.

KẾT LUẬN

Bài viết này nghiên cứu lỗ hổng CVE-20198942, CVE-2019-8943 trên Wordpress, chỉ ra điểm yếu của các mã khai thác cũ và đề xuất một kỹ thuật mới để khai thác lỗ hổng RCE trên cả hai thư viện ImageMagick và GD cho tỉ lệ khai thác thành công cao hơn.

Các website sử dụng nền tảng Wordpress chứa lỗ hổng này là các phiên bản công bố trước ngày 13/12/2018. Các nhà quản trị Wordpress đang sử dụng các phiên bản Wordpress chứa lỗ hổng cần nhanh chóng cập nhật lên các phiên bản mới nhất. Danh sách các phiên bản Wordpress chứa lỗ hổng CVE-2019-8942 đã được công bố trên cơ sở dữ liệu lỗ hổng quốc gia Hoa Kỳ (NVD) [10].

Để khai thác lỗ hổng CVE-2019-8942, kẻ tấn công phải có một tài khoản với thấp nhất là đặc quyền author, vì vậy, nhà quan trị website Wordpress có thể hạn chế rủi ro bị tấn công trong tương lai bằng cách kiểm soát chặt chẽ quy định cấp quyền người dùng, xoá các tài khoản có quyền author trở lên không sử dụng hoặc yêu cầu mức độ bảo mật cao hơn đối với những người dùng tài khoản này.

TÀI LIỆU THAM KHẢO

1. Riana Macleod “Hacked Website Threat Report – 2019”. https://blog.sucuri.net/2020/01/hacked-website-threat-report-2019.html

2. Wordpress Vulnerability Statistics until 2019. https://www.cvedetails.com/product/4096/ Wordpress-Wordpress.html?vendor_id=2337 Last Accessed: 07/09/2020.

3. GD Graphics Library. https://libgd.github.io/.

4. Wordpress RCE on CVE-2019-8942. https://github. com/kimteawan2411/2019-8942-rce.

5. Simon Scannell, “WordPress 5.0.0 Remote Code Execution”. https://blog.ripstech.com/2019/wordpressimage-remote-code-execution/

6. Injects php payloads into jpeg images. https://github.com/dlegs/php-jpeg-injector.

7. Proof-of-concept to exploit the flaw in the PHP-GD builtin function, imagecreatefromjpeg(). https://github.com/fakhrizulkifli/Defeating-PHP-GD-imagecreatefromjpeg.

8. https://www.exploit-db.com/exploits/46511.

9. https://www.exploit-db.com/exploits/46662.

10. Vulnerable Wordpress versions to CVE-2019-8942. https://nvd.nist.gov/vuln/detail/CVE-2019-8942/cpes?expandCpeRanges=true.