0x0 背景介绍

SmarterTools SmarterMail 9511版本之前的构建中存在ConnectToHub API方法的未授权远程代码执行漏洞。攻击者可诱导SmarterMail连接至恶意HTTP服务器,该服务器会下发恶意操作系统命令。该命令将被存在漏洞的应用程序执行。

0x1 环境搭建

1.1、Ubuntu24搭建配置

#1、创建项目
mkdir Smarter-rce && cd Smarter-rce
#2、下载安装包
wget https://downloads.smartertools.com/smartermail/100.0.9504/smartermail_9504
#3、安装所需环境
apt install -y curl libicu70
#4、安装smartermail服务
chmod +x smartermail_9504
sudo ./smartermail_9504 install
#5、检查服务状态
systemctl status smartermail


#6、重启服务
systemctl restart smartermail

  • 过程参考
root@iubuntu:~/Smarter-rce# sudo ./smartermail_9504 install
------------------------------
OS: Ubuntu 22.04.5 LTS
Installer version: 100.0.9504.27800
------------------------------

Selected build: 100.0.9504.27800

Please review the End User License Agreement at:
https://www.smartertools.com/company/eula

Do you accept the End User License Agreement? (y/n) y
Downloading SmarterMail and prerequisites

                       Downloading SmarterMail ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 00:00:00   106.9 MiB
          Downloading Message Sniffer Antispam ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 00:00:00   507.2 KiB
            Downloading Cyren Premium Antispam ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 00:00:00   4.1 MiB
Downloading Cyren Zero-hour Outbreak Detection ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 00:00:00   6.9 MiB

Finished downloading files: Success
Downloaded SmarterMail 100.0.9504.27800
Successfully extracted SmarterMail files

Extracting into /opt/smartermail ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 00:00:00

Extracted SmarterMail to /opt/smartermail
Configuring web server...
AppArmor was detected on this system. Please remember to manually configure AppArmor for SmarterMail to work properly.
Ports 80 and 443 are now open for SmarterMail
Created /opt/smartermail/run-webserver.txt file
SmarterMail is now configured as the web server
Checking for prerequisite packages...
Completed check for prerequisite packages...
Configuring MailService permissions...
Configuring Cyren permissions...
Configuring MessageSniffer permissions...
Opening default mail ports...
Installing ClamAV...
Installing curl...
Configuring SmarterMail as a systemd Service...
Starting SmarterMail Service...
Starting ClamAV service...

SmarterMail is now running.
Installation complete!

0x2 漏洞复现

2.1、手动复现步骤

  • 模拟HUB链接
https://github.com/Kai-One001/cve-/blob/main/SmarterTools_SmarterMail_CVE-2026-24423.py

利用成功

  • 服务器状态查看
    可见自动请求
  • 成功创建文件
    文件创建成功
  • 其它命令执行成功
    curl恶意文件

2.2、复现流量特征 (PCAP)

  • 无认证请求接口,但是响应中可查看到具体的明文命令,还是方便溯源的
    明文响应执行命令

0x3 漏洞原理分析

通过dnSpyEx反编译核心DLL文件:MailService.dll文件

3.1、漏洞入口点:未授权 API 接口

  • 命名空间:SmarterMail.Web.Api
  • 类名:SystemAdminSettingsController
  • 方法名:ConnectToHub
  • 文件路径:MailService\SmarterMail\Web\Api\SystemAdminSettingsController.cs
		// Token: 0x0600F9B6 RID: 63926 RVA: 0x005CF9CC File Offset: 0x005CDBCC
		[ShortDescription("Attempts to connect this node to a hub")]
		[Description("Attempts to connect this node to a hub.")]
		[AuthenticatedService(AllowAnonymous = true)]
		[HttpPost]
		[Route("connect-to-hub")]
		public Task<ActionResult<ConnectToHubResult>> ConnectToHub([FromBody] ConnectToHubInput input)
		{
			SystemAdminSettingsController.<ConnectToHub>d__273 <ConnectToHub>d__;
			<ConnectToHub>d__.<>t__builder = AsyncTaskMethodBuilder<ActionResult<ConnectToHubResult>>.Create();
			<ConnectToHub>d__.<>4__this = this;
			<ConnectToHub>d__.input = input;
			<ConnectToHub>d__.<>1__state = -1;
			<ConnectToHub>d__.<>t__builder.Start<SystemAdminSettingsController.<ConnectToHub>d__273>(ref <ConnectToHub>d__);
			return <ConnectToHub>d__.<>t__builder.Task;
		}
  • 该接口使用了 [AuthenticatedService(AllowAnonymous = true)],即未要求任何认证即可调用。
  • 同控制器内其他管理接口(如 GetThrottledUsersGetDomainSettings)均使用 [AuthenticatedService(Role = "SysAdmin")],仅ConnectToHub允许匿名,构成缺失认证

3.2、命令执行点:CommandMount 字段被用于系统命令执行

  • 文件路径:MailService\SmarterMail\MailService\Core\MountConfiguration.cs
  • 类名:MountConfiguration
3.2.1. Mount 方法(入口)
		// Token: 0x0600B4F9 RID: 46329 RVA: 0x0053AB80 File Offset: 0x00538D80
		public static Task<SuccessResult> Mount(MountPointConfig mount, bool isSystemMount = false)
		{
			MountConfiguration.<Mount>d__20 <Mount>d__;
			<Mount>d__.<>t__builder = AsyncTaskMethodBuilder<SuccessResult>.Create();
			<Mount>d__.mount = mount;
			<Mount>d__.isSystemMount = isSystemMount;
			<Mount>d__.<>1__state = -1;
			<Mount>d__.<>t__builder.Start<MountConfiguration.<Mount>d__20>(ref <Mount>d__);
			return <Mount>d__.<>t__builder.Task;
		}
  • RunCommand接收 path、command、includeArgs;command 也就是来自 MountPointConfig.CommandMount字段
3.2.2. RunCommand 方法(执行层)
private static Task RunCommand(string path, string command, bool includeArgs)
{
    MountConfiguration.<RunCommand>d__23 <RunCommand>d__;
    <RunCommand>d__.<>t__builder = AsyncTaskMethodBuilder.Create();
    <RunCommand>d__.path = path;
    <RunCommand>d__.command = command;        // ← 来自 MountPointConfig.CommandMount
    <RunCommand>d__.includeArgs = includeArgs;
    <RunCommand>d__.<>1__state = -1;
    <RunCommand>d__.<>t__builder.Start<MountConfiguration.<RunCommand>d__23>(ref <RunCommand>d__);
    return <RunCommand>d__.<>t__builder.Task;
}
  • 可惜的是<RunCommand>d__23MoveNext 实现不是完整展开的**,但根据方法签名与调用关系,最终会通过 Process.Start 或等价方式执行 command(即恶意 Hub 下发的 CommandMount)。
  • 同项目中可参考的显式 Process.Start 用法:
//MailService\SmarterMail\MailService\Spam\Clam\SmClamClient.cs
SmClamClient.ClamDProcess = Process.Start(processStartInfo);
Process process = Process.Start(processStartInfo);
process = Process.Start(processStartInfo);
  • RunCommand最终通过Process.Start或等价方式执行command 参数。

3.3、数据模型:CommandMount 定义

  • 项目: SmarterMail.Standard(SmarterMail.Standard.dll)
  • 文件: SmarterMail.Standard\SmarterMail\Standard\Files\Json
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Newtonsoft.Json;

namespace SmarterMail.Standard.Files.Json
{
	// Token: 0x0200015D RID: 349
	[NullableContext(2)]
	[Nullable(0)]
	public class MountPointConfig
	{
		// Token: 0x170002C4 RID: 708
		// (get) Token: 0x06000C45 RID: 3141 RVA: 0x0007C412 File Offset: 0x0007A612
		// (set) Token: 0x06000C46 RID: 3142 RVA: 0x0007C41A File Offset: 0x0007A61A
		[JsonProperty(DefaultValueHandling = 3)]
		[DefaultValue(true)]
		public bool Enabled { get; set; } = true;

		// Token: 0x170002C5 RID: 709
		// (get) Token: 0x06000C47 RID: 3143 RVA: 0x0007C423 File Offset: 0x0007A623
		// (set) Token: 0x06000C48 RID: 3144 RVA: 0x0007C42B File Offset: 0x0007A62B
		[Nullable(1)]
		public string MountPath
		{
			[NullableContext(1)]
			get;
			[NullableContext(1)]
			set;
		}

		// Token: 0x170002C6 RID: 710
		// (get) Token: 0x06000C49 RID: 3145 RVA: 0x0007C434 File Offset: 0x0007A634
		// (set) Token: 0x06000C4A RID: 3146 RVA: 0x0007C43C File Offset: 0x0007A63C
		public string CommandMount { get; set; }

		// Token: 0x170002C7 RID: 711
		// (get) Token: 0x06000C4B RID: 3147 RVA: 0x0007C445 File Offset: 0x0007A645
		// (set) Token: 0x06000C4C RID: 3148 RVA: 0x0007C44D File Offset: 0x0007A64D
		public string CommandUnmount { get; set; }

		// Token: 0x170002C8 RID: 712
		// (get) Token: 0x06000C4D RID: 3149 RVA: 0x0007C456 File Offset: 0x0007A656
		// (set) Token: 0x06000C4E RID: 3150 RVA: 0x0007C45E File Offset: 0x0007A65E
		public bool ReadOnly { get; set; }

		// Token: 0x170002C9 RID: 713
		// (get) Token: 0x06000C4F RID: 3151 RVA: 0x0007C467 File Offset: 0x0007A667
		// (set) Token: 0x06000C50 RID: 3152 RVA: 0x0007C46F File Offset: 0x0007A66F
		public bool UseArgumentsInCommand { get; set; }
	}
}
  • CommandMount 为纯字符串字段,无任何校验或白名单限制。
  • 攻击者可通过控制Hub响应,将任意系统命令写入此字段。

3.4、涉及项目与关键类

项目 类/类型 作用
MailService SystemAdminSettingsController.ConnectToHub 未授权 API 入口
MailService SystemSettingsService.ConnectToHub(ConnectToHubInput) 业务入口,向 Hub 发起连接与请求
MailService ConnectToHubInput / ConnectToHubResult API 入参/出参,Result 含 systemMount(MountPointConfig)
SmarterMail.Standard MountPointConfig(Files.Json) CommandMountCommandUnmountMountPath
SmarterMail.Standard HANodeConfig(Hub) SystemMount(类型为 MountPointConfig)
SmarterMail.Standard HttpClients(Network) 静态 HttpClient,可用于向 hubAddress 发 HTTP 请求
MailService MountConfiguration.Mount / RunCommand 使用 MountPointConfig,执行 CommandMount

3.5、攻击链



攻击者 → POST /api/v1/settings/sysadmin/connect-to-hub
       ↓(无认证)
SmarterMail → 连接 attacker-controlled hubAddress
       ↓
接收 JSON 响应:{ "systemMount": { "CommandMount": "恶意命令" } }
       ↓
解析为 MountPointConfig
       ↓
调用 MountConfiguration.Mount(...)
       ↓
调用 RunCommand(command = "恶意命令")
       ↓
执行 Process.Start("恶意命令") → RCE

0x4 修复建议

修复方案

  1. 升级最新版本: 将SmarterMail 升级至Build 9511 或更高版本,官方已发布补丁Public Vulnerability List

  2. 临时防护措施:
    限制API接口:仅允许受信任的Hub地址(白名单、内网段或预配置域名),禁止将用户可控的URL 直接用于发起连接。
    暂时取消 Hub 执行命令:取消远程响应的字符串直接传给进程执行,若必须支持“挂载脚本”,应改为预定义命令模板 + 严格参数校验,或完全移除从 Hub 下发可执行命令的能力。
    禁用未使用的 Hub 功能:若环境无需多节点集群,可考虑关闭Hub连接功能,减少攻击面;

免责声明:本文仅用于安全研究目的,未经授权不得用于非法渗透测试活动。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐