This post is part of our short articles on analyzing malicious Office documents. The content addresses the old, and yet, very relevant, Equation Editor exploits that are used to execute malicious code on infected machines, without any warning (like in VBA macros "Enable Content" warning).
Background
The Equation Editor is an old Microsoft binary that was compiled in the 2000's. The developers compiled it without any stack protections such as DEP (Data Execution Prevention) allowing execution of code from the stack itself. In addition, some functions were in the Equation binary process were found vulnerable to stack buffer overflow as the length of certain arguments is not validated in comparison to the maximum size of the destination buffer (where the actual function parameter value is stored). In this blog post we will give a quick overview of two dominant Equation Editor vulnerabilities and their exploitation. The content is intended for analysts with some knowledge in assembly, memory structures and reverse engineering skills.
The Equation Editor Exploit
CVE-2017-11882: Microsoft Office Memory Corruption Vulnerability
A stack buffer overflow vulnerability where the Equation Editor process does not validate the buffer size of an argument to a vulnerable function. The vulnerable argument is a font and the expected size of the buffer is 40 bytes. In most cases, an attacker will store a malicious command or shellcode in an Equation object, which is loaded and processed by the EQNEDT32.exe process (Equation Editor 3.0).
Below, shellcode is loaded instead of a font (a string representing the font name. For example: "Calibri"). The buffer size (ECX) is 48 bytes, which overrides the maximum size by 8 bytes.
CVE-2018-0802: Microsoft Office Memory Corruption Vulnerability
A Zero-Day vulnerability found on 8th January 2018, where Office mishandles OLE objects in memory - in this case, an Equation OLE object. The vulnerability relies in ASLR being disabled (back in 2018 it was not enforced, but recently Microsoft enforced it on processes to randomize the process image base address on each execution).
A global variable located at 0x0045bd3c is abused and incremented via the "get_byte()" function. Checkpoint researchers mentioned that "the get_byte() function increases the global variable dword_45BD3C and copies its pointed content into AL. In the vulnerable function this went on looping until a null was encountered, which could lead to a stack based overflow when no null was present. In a nutshell, that’s pretty much all there is to this vulnerability.". The research can be found here.
Below, the global variable stores a pointer which eventually leads to the shellcode itself:
The shellcode is stored inside the Equation object (OLE), which is stored as raw hexadecimal content inside the RTF document:
When manually following the pointers chain (0x18f564 > 0x04ca0074 >0x068f0020) the actual shellcode entry point is seen at 0x68f0020:
The shellcode will eventually call "WinExec()" to execute a malicious payload it downloaded from the Internet:
The process tree (ANY.RUN) shows the initial WINWORD.EXE process and the invoked EQNEDT32.EXE process, as a result of the loaded Equation object by the RTF doc.
The Equation Editor process calls the WinExec() API function, hence EQNEDT32.exe is the parent process of the executed payload process.
The exploit fires when the document is opened by the user without any warning. In this case, the payload binary was identified as a Redline stealer malware variant.
References
We hope the content was useful. Thank you for reading!
PreCySec team.