Mục lục bài viết || Contents of the article

    Telerik UI là một thư viện phổ biến chuyên phát triển giao diện cho các Website, xây dựng trên nền tảng .NET. Từ năm 2014 đến nay, thư viện này thường bị phát hiện các lỗ hổng bảo mật nghiêm trọng, cho phép Hacker có thể tấn công chiếm quyền điều khiển hệ thống. Dó đó, SecurityBox đã thực hiện nghiên cứu chi tiết về lỗ hổng này, và cập nhật kết quả nghiên cứu vào sản phẩm SecurityBox 4Network và SecurityBox 4Website

    • 1. Nghiên cứu tổng quan về lỗ hổng.
    • 2. Cách thức phát hiện và khai thác lỗ hổng.
    • 3. Tích hợp vào SecurityBox

    1. NGHIÊN CỨU TỔNG QUAN VỀ LỖ HỔNG

    1.1. Thông tin lỗ hổng:

    Trong bài này, chúng tôi phân tích về lỗ hổng của Telerik UI có mã  CVE-2017-9248, CVE-2017-11317, CVE-2017-11357 và CVE-2019-18935, đây đều là những lỗ hổng được đánh giá là nghiêm trọng.

    1.2. Các phiên bản ảnh hưởng: 

    Các phiên bản Telerik UI trước 2019.3.1023 đều có khả năng bị ảnh hưởng bởi các lỗ hổng trên này.

    1.3. Mức độ ảnh hưởng:

    Hacker có thể lợi dụng lỗ hổng này để chiếm quyền điều khiển máy chủ cài đặt Telerik UI.

    1.4. Tổng quan về các lỗ hổng:

    CVE-2017-9248 – Cryptographic Weakness 

    Module Text Editor trong Telerik UI for ASP.NET AJAX cung cấp tính năng File Manager cho phép người dùng upload file lên máy chủ web để chèn vào bài viết. Khi người dùng lựa chọn loại đối tượng cần chèn (Image, Document,..), một hộp thoại tương ứng sẽ được load thông qua URL có dạng như sau:

    /Telerik.Web.UI.DialogHandler.aspx?DialogName=DocumentManager&renderMode=2&Skin=Default&Title=Document%20Manager&dpptn=&isRtl=false&dp=XXX

    Trong đó, dp=XXX là một đối tượng đã được serialize, được dùng để chỉ định các tham số cấu hình cho hộp thoại như vị trí lưu trữ file trên máy chủ, định dạng file được phép tải lên,…

    Decompile Telerik.Web.UI.dll, ta có thể thấy tham số dp được xử lý như sau:

    Có thể tóm tắt quá trình này như sau:

    xxx > decode_base64 >  xor(,key) > decode_base64  > deserialize

    Mặc dù Telerik đã bảo vệ đối tượng dp bằng cách mã hóa XOR nó với một giá trị key bí mật (Telerik.Web.UI.DialogParametersEncryptionKey/MachineKey), các phiên bản Telerik UI for ASP.NET AJAX trước R2 2017 SP1 có tồn tại vấn đề khiến cho người dùng bất kỳ có thể dò được giá trị key này bằng tấn công brute force, từ đó giả mạo XXX hợp lệ với cấu hình tùy chỉnh, dẫn tới có thể upload file tùy ý lên máy chủ mà không bị giới hạn định dạng, vị trí,…

    Với tập lỗ hổng CVE-2017-11317, CVE-2017-11357 và CVE-2019-18935

    Tổng quan về lỗ hổng

    Khác với lỗ hổng CVE-2017-9248, tập lỗ hổng CVE-2017-11317, CVE-2017-11357 và CVE-2019-18935 lại được khai thác dựa trên RadAsyncUpload là một file handler trong Telerik UI for ASP.NET AJAX, cho phép người dùng upload file lên máy chủ mà không cần phải tải lại trang (upload file bất đồng bộ). Khi người dùng upload file qua module này, một POST Request được tạo tới đường dẫn tương đối /Telerik.Web.UI.WebResource.axd?type=rau với nội dung POST body như sau:

    • rauPostData (đối tượng lưu cấu hình chi tiết cách tệp được xử lý)
    • blob (nội dung của file được upload)
    • fileName (tên của file được upload)
    • contentType (mimetype của file được upload)
    • lastModifiedDate
    • metadata (đối tượng JSON chứa kích cỡ và tên tạm thời ‘UploadID’ của tệp được upload)
    Nguyên nhân gây ra lỗ hổng

    Trước đó, module này có tồn tại lỗ hổng CVE-2014-2217 cho phép upload file tùy ý lên máy chủ. Telerik đã khắc phục vấn đề này bằng cách kiểm tra tên file để đảm bảo nó không chứa các ký tự như “../” và thêm các cấu hình mới trong web.config. Các cấu hình mới bao gồm ‘ConfgurationEncryptionKey’ và ‘ConfigurationHashKey’, được thiết để để đảm bảo tính bí mật và tính toàn vẹn của các thông tin nhạy cảm (chẳng hạn như thư mục đích trên máy chủ web lưu file được upload). Theo đó, tham số rauPostData trong POST body sẽ được mã hóa thay vì ở dạng rõ.

    Tuy nhiên, với Telerik UI for ASP.NET AJAX phiên bản trước R1 2017 và R2 trước R2 2017 SP2, nếu lập trình viên không tùy chỉnh khóa mã hóa, khóa mặc định cố định sẽ được sử dụng. Dùng công cụ JetBrains dotPeek để decompile Telerik.Web.UI.dll, ta có thể thấy giá trị khóa mặc định này là “PrivateKeyForEncryptionOfRadAsyncUploadConfiguration“:

    Mức độ ảnh hưởng

    Như vậy, nếu máy chủ sử dụng cấu hình RadAsyncUpload mặc định, kẻ tấn công có thể dùng khóa mặc định để giải mã, đọc, sửa đổi, giả mạo đối tượng rauPostData. Do đối tượng này chứa các tham số để chỉ định thư mục lưu file được upload, nếu một kẻ xấu giả mạo giá trị này, hắn có thể upload file tùy ý vào vị trí mong muốn lên máy chủ. Phương thức phá vỡ lớp bảo mật mã hóa mà trình xử lý sử dụng để bảo vệ các POST request để tải lên tệp chính là lỗ hổng CVE-2017-11317, CVE-2017-11357 và CVE-2019-18935 mà sau đây chúng ta sẽ tìm hiểu chi tiết về cách mà lỗ hổng này tồn tại, hướng khai thác và khắc phục.

    CVE-2017-11317 – Unrestricted File Upload via Weak Encryption, CVE-2017-11357 – Telerik UI Insecure Direct Object Reference

    Telerik UI cho ASP.NET AJAX trước R2 2017 SP2, class AsyncUploadHandler cấu hình một mã hóa cứng (hard-coded) được sử dụng để mã hóa form data trong request tải tệp lên máy chủ. 

    Nếu giá trị mặc định của khóa mã hóa: PrivateKeyForEncryptionOfRadAsyncUploadConfiguration không được thay đổi, kẻ tấn công có thể sử dụng khóa đó để tạo một POST request /Telerik.Web.Ui.WebResource.axd?type=rau yêu cầu tải lên tệp với tham số được mã hóa rauPostData. Sau đó, nếu hacker có thể chỉ định một giá trị cho biến TempTargetFolder trong tham số rauPostData, tin tặc có thể có được toàn quyền cho phép upload file ở bất kì thư mục nào mà máy chủ web có quyền ghi.

    CVE-2019-18935 – Remote Code Execution via Insecure Deserialization

    Dù lỗ hổng unrestricted file upload đã được biết đến rộng rãi kể từ khi được phát hiện vào năm 2017, người ta vẫn nghiên cứu sâu hơn vào cách mà RadAsyncUpload xử lý tham số rauPostData trong các request upload file vào đầu năm 2019 và phát hiện ra rằng rauPostData chứa cả thông tin cấu hình object cần chuyển đổi và object type (kiểu dữ liệu mong muốn để chuyển đổi). Tuy nhiên, ngôn ngữ .Net không thể tự làm việc với object mà client truyền lên được, mà phải chuyển đổi lại. 

    Để làm được điều này, cần phân định kiểu trước khi truyền vào hàm JavaScriptSerializer.Deserialize(). Ở đây, AsyncUploadHandler lấy type từ trong rauPostData để truyền vào hàm Deserialize().

    Trong quá trình deserialize, JavaScriptSerializer sẽ gọi đến các phương thức setter cho từng object type riêng biệt và nếu object type đó bị kẻ tấn công kiểm soát, một kịch bản rất xấu có thể xảy ra khi hacker có thể sử dụng nó như là một gadget để tiến hành tấn công hệ thống. Thay vì gửi một type Telerik.Web.UI.AsyncUploadConfiguration thông thường trong rauPostData, kẻ tấn công có thể POST request upload một tập tin chỉ định type dưới dạng một RCE gadget. 

    Sau khi lợi dụng lỗ hổng unrestricted file upload để tải lên hệ thống một file Mixed Mode Assembly DLL độc hại, kẻ tấn công sẽ tiếp tục một request thứ hai chứa nhằm mục đích ép JavaScriptSerializer deserialize một object có type System.Configuration.Install.AssemblyInstaller. Khi server chạy hàm Deserialize() cùng với Path do kẻ tấn công gắn vào được trỏ tới file DLL được tải lên, máy chủ sẽ tải file DLL đó tới domain hiện tại của nó và hàm DLLMain() sẽ được gọi đến khi file DLL load thành công.

    2. CÁCH THỨC PHÁT HIỆN, KHAI THÁC VÀ KHẮC PHỤC

    2.1. Với lỗ hổng CVE-2017-9248 

    Cách phát hiện lỗ hổng CVE-2017-9248

    1. Kiểm tra đường dẫn kết thúc với “/Telerik.Web.UI.DialogHandler.aspx” hoặc “DialogHandler.aspx” có tồn tại hay không

    2. Tìm kiếm và kiểm tra phiên bản Telerik UI đang sử dụng có nằm trong danh sách các phiên bản có nguy cơ tồn tại lỗ hổng hay không thông qua mã nguồn.

    Khai thác lỗ hổng CVE-2017-9248

    Khi thực hiện fuzzing tham số dp, ta có thể nhận được các thông báo lỗi sau:

    Các thông báo này được hiển thị tương ứng khi đầu vào của hàm base64_decode có độ dài không hợp lệ, chứa ký tự không nằm trong tập ký tự base64 hoặc khi cả hai lần decode base64 đều thực hiện thành công nhưng cho ra đầu ra không đúng định dạng nên hàm extract_params không thể xử lý được.

    Nếu gặp thông báo thứ 3, ta có thể kết luận khả năng cao việc giải mã xor được thực hiện thành công (do cho ra kết quả là một giá trị base64). Kết hợp với tính chất mã hóa xor được thực hiện trên từng ký tự, ta có thể dò lần lượt từng ký tự trong key với ý tưởng nếu server và client sử dụng cùng một khóa, server có thể giải mã được tất cả các giá trị client gửi lên. 

    Các bước thực hiện như sau:

    Xác định ký tự đầu tiên của key (key[0]):

    Thử key[0] lần lượt là 1 ký tự trong tập ký tự có thể được dùng trong khóa (hex, ASCII,…), dùng giá trị này để mã hóa lần lượt các ký tự trong tập ký tự base64, xây dựng tham số dp để gửi request tới máy chủ (thao tác ngược lại so với xử lý phía máy chủ). Nếu máy chủ trả về thông báo lỗi thứ 3 cho tất cả các request, giá trị key hiện tại chính là key[0] của máy chủ.

    Xác định các ký tự key tiếp theo (key[n]):

    Thực hiện tương tự như xác định key[0], trong đó giá trị key[n] được thử được nối với chuỗi key đã tìm được trước đó, ký tự base64 được thử được nối với chuỗi base64 bất kỳ để tạo thành chuỗi plaintext có độ dài tương ứng với độ dài key hiện tại.

    Trong khi đây chỉ là một hướng khai thác khả thi, hiện nay đã có một số mã khai thác được tối ưu để có thể tìm ra key một cách nhanh chóng.

    Tiếp đến, xem xét cách Telerik xử lý yêu cầu upload file từ hộp thoại như sau:

    Như có thể thấy, nếu SearchPatterns có chứa “*.*”, người dùng có thể upload file với phần mở rộng bất kỳ, và đây chính là một trong các thuộc tính của dp (nhắc lại: ta có thể giả mạo dp khi có key). Tương tự, ta có thể chỉ định các thuộc tính khác như UploadPathsViewPaths,… để có thể upload file lên vị trí tùy ý trên máy chủ.

    Tóm lại, các bước khai thác lỗ hổng trên có thể được tóm tắt:

    1. Tiến hành brute force để tìm ra được chuỗi key bí mật của máy chủ.
    2. Chỉ định giá trị của các thuộc tính trong đối tượng dp theo mục đích tấn công, chẳng hạn, đặt SearchPatterns chứa  “*.*” để upload file với phần mở rộng bất kỳ lên máy chủ.
    3. Mã hoá giá trị dp sử dụng chuỗi key đã dò được ở phía trên và gửi request tới server. Sau khi truy cập được vào trang upload, kẻ tấn công có thể tiến hành upload file tùy ý lên máy chủ web.

    2.2. Với tập lỗ hổng CVE-2017-11317, CVE-2017-11357 và CVE-2019-18935

    2.2.1 Cách phát hiện 

    Để có thể xác định lỗ hổng này có tồn tại hay không, ta cần thực hiện các bước sau:

    Bước 1. Xác định website có sử dụng thư viện Telerik UI

    Kiểm tra các đường dẫn kết thúc với /Telerik.Web.UI.WebResource.axd?type=rau có tồn tại hay không.

    Bước 2: Kiểm tra nội dung sau có xuất hiện ở các trang

    RadAsyncUpload handler is registered successfully, however, it may not be accessed directly.

    Bước 3: Tìm kiếm và kiểm tra phiên bản Telerik UI đang sử dụng. Từ đó, xác nhận phiên bản đó có nằm trong danh sách các phiên bản chứa nguy cơ tồn tại lỗ hổng hay không thông qua mã nguồn.

    2.2.2 Khai thác CVE-2017-11317 – Unrestricted File Upload via Weak Encryption và CVE-2017-11357 – Insecure Direct Object Reference:

    1. Kiểm tra trong các request cho phép tải file lên và xem trong request có tồn tại tham số rauPostData
    1. Giải mã giá trị của tham số rauPostData ta sẽ thu được các thông tin chứa các trường như sau:

    Giải mã “TempTargetFolder” thu được thư mục cho phép tải lên tệp:

    1. Sau khi đã có đường dẫn tới thư mục Temp trên server, tiến hành tạo request POST tới đường dẫn với tham số rauPostData mới trong đó biến TempTargetFolder được đặt về thư mục gốc (xoá \App_Data\RadUploadTemp), tham số UploadID được đặt về: sbox.aspx và content file là một webshell ASP.NET. Sau khi request thành công, truy cập vào đường dẫn và xác nhận web shell đã được thực thi.

    2.2.3. Khai thác CVE-2019-18935 – Remote Code Execution via Insecure Deserialization:

    Với lỗ hổng CVE-2019-18935, sau khi đã thu thập được các thông tin về phiên bản và đường dẫn trên máy chủ web, chúng ta có thể tiếp tục thực hiện các bước sau để xác thực lỗ hổng deserialization có tồn tại hay không với sleep().

    1. Biên dịch mã nguồn đơn giản với mục đích khiến ứng dụng web sleep trong 10 giây thanh một tệp mixed mode assembly DLL.
    1. Thực hiện tương tự như cách khai thác lỗ hổng CVE-2017-11317, tiến hành upload file DLL đã được build lên phía web server.
    2. Gửi một request thứ 2 với tham số rauPostData sau khi được mã hoá có chứa type là System.Configuration.Install.AssemblyInstaller và giá trị Path trỏ tới đường dẫn file DLL đã được upload lên server ở bước 2. Nếu request mất hơn 10 giây để phản hồi, chúng ta có thể xác nhận website có tồn tại lỗ hổng deserialization và hoàn toàn có thể bị tấn công.
    3. Sau khi đã xác thực chúng ta có thể khai thác phiên bản Telerik UI có tồn tại lỗ hổng, ta có thể thay thế việc sử sleep bằng một file DLL sẽ tạo ra một reverse shell, tiến hành một cuộc tấn công Thực thi mã từ xa (RCE) và chiếm quyền điều khiển server.

    2.3. Cách kiểm tra việc sử dụng Telerik UI trên máy chủ website

    Một số phương thức quản trị viên có thể áp dụng để kiểm tra xem máy chủ web có đang sử dụng Telerik UI hay không:

    • Phương pháp đơn giản và chính xác đó là xác định các Telerik DLL trong thư mục root của trang web. Vì các function chứa lỗ hổng có thể khai thác trong thư viện Telerik đều nằm ở một tệp DLL duy nhất: Telerik.Web.UI.dll, quản trị viên có thể xác định tệp này biết được trang web có đang sử dụng Telerik hay không cũng như xác định được phiên bản hiện tại.
    • Việc sử dụng Telerik cũng có thể được xác định thông qua việc kiểm tra logs của máy chủ web IIS dựa trên những resource của Telerik, đặc biệt là những resource được hacker sử dụng trong việc khai thác và tấn công máy chủ web như Telerik.Web.UI.WebResource.axd.

    2.4. Khắc phục

    Đối với 2 lỗ hổng với mã lỗi CVE-2017-9248

    Cập nhật bản vá cho phiên bản từ Q1 2013 (2013.1.220) và R2 2017 SP1 (2017.2.502).

    Cập nhật bản vá cho một số phiên bản từ Q1 2011 (2011.1.315) và Q3 2012 SP2 (2012.3.1308).

    Nếu muốn khắc phục một cách triệt để, hãy nâng cấp lên R2 2017 SP1 (2017.2.621) trở lên.

    Đối với 2 lỗ hổng với mã lỗi CVE-2017-11317 và CVE-2017-11357

    Để đảm bảo ứng dụng không gặp rủi ro, cần loại bỏ một số đường dẫn. Phương pháp được đề xuất là nâng cấp lên phiên bản mới nhất. Đồng thời, quản trị viên nên làm theo các bước trong bài viết RadAsyncUpload Security. 

    Cập nhật bản vá cho phiên bản từ Q1 2011 (2011.1.315) và R2 2017 SP1 (2017.2.621).

    Nếu muốn khắc phục một cách triệt để, hãy nâng cấp lên R2 2017 SP2 (2017.2.711) trở lên.

    Đối với CVE-2019-18935:

    Nâng cấp lên R3 2019 SP1 trở lên. Áp dụng các cài đặt bảo mật được khuyến nghị bởi Telerik.

    3. TÍCH HỢP VÀO SECURITYBOX

    Hiện tại, chúng tôi đã tích hợp các nghiên cứu trên vào 02 dòng thiết bị của SecurityBox. Điều này cho phép quản trị có thể kiểm tra, phát hiện và khắc phục toàn diện lỗ hổng trên:

    3.1. Tích hợp vào SecurityBox 4Website:

    Cho phép phát hiện tất cả các Website có bị dính các lỗ hổng này hay không.

    https://youtu.be/SOuwmNv5Aw0

    Tìm hiểu thêm về thiết bị SecurityBox 4Website tại: https://securitybox.vn/thiet-bi-danh-gia-an-ninh-cho-website/

    3.2. Tích hợp vào SecurityBox 4Network:

    Việc phát hiện lỗ hổng bằng SecurityBox 4Website có thể gặp một số trường hợp chưa triệt để. Quản trị sẽ sử dụng thêm SecurityBox 4Network. Việc này để thực kiểm tra lỗ hổng chính xác trên từng thiết bị máy chủ do mình quản lý:

    https://youtu.be/uzOXXJfIyAw

    Tìm hiểu thêm về thiết bị SecurityBox 4Network tại: https://securitybox.vn/thiet-bi-danh-gia-an-ninh-cho-mang-noi-bo/

    3.3. Một số hình ảnh phát hiện lỗ hổng của SecurityBox

    Trên SecurityBox 4Website:

    Nguy cơ Telerik UI found

    Nguy cơ Telerik UI Insecure Direct Object Reference

    Kết quả kiểm thử xâm nhập với nguy cơ:Telerik UI Insecure Direct Object Reference

    Nguy cơ Telerik UI Unrestricted File Upload via Weak Encryption

     Kết quả kiểm thử xâm nhập với nguy cơ Telerik UI Unrestricted File Upload via Weak Encryption

    Nguy cơ Telerik UI Remote Code Execution via Insecure Deserialization

    Nguy cơ Telerik UI Cryptographic Weakness

    Kết quả kiểm thử xâm nhập nguy cơ Telerik UI Cryptographic Weakness(CVE-2017-9248)

    Trên SecurityBox 4Network:

    Nguy cơ Telerik.Web.UI.dll Assembly of UI for ASP.NET AJAX RadAsyncUpload .NET Deserialization Vulnerability (CVE-2019-18935)

    Nguy cơ Telerik.Web.UI.dll Assembly of UI for ASP.NET AJAX RadAsyncUpload Multiple Vulnerabilities (CVE-2017-11317, CVE-2017-11357)

    Giải pháp quản trị an ninh website và network đang được miễn phí trải nghiệm 2 tuần để doanh nghiệp có thể bảo vệ mình khỏi các lỗ hổng kể trên và cả các lỗ hổng khác có trên hệ thống.

    [ninja_forms id=9]

    Hoàng Quốc Anh, Thân Hữu Tuấn và Phạm Văn Đắc

    Bài viết đề xuất || Recommended
    Không chỉ website của doanh nghiệp nhỏ mà ngay cả website của nhiều tổ chức, doanh nghiệp lớn tại Việt Nam cũng đã từng bị xâm nhập. Thực trạng này dẫn...
    Kiến thức | 24/03/2021
    Một trong những chìa khóa để kinh doanh online thành công là bảo mật website của doanh nghiệp.  1. Lý do doanh nghiệp kinh doanh online cần đẩy mạnh bảo mật...
    Kiến thức | 24/03/2021
    Bảo mật website hiện đang là yêu cầu cấp thiết với mọi doanh nghiệp. Theo đó, các đơn vị an ninh mạng cũng cho ra đời nhiều dịch vụ bảo mật website đa...