By Mitja Kolsek, 0patch Team
As you may know, we at 0patch wrote a micropatch for Equation Group's ESTEEMAUDIT exploit last month. It took us quite a while to reproduce the issue until we figured out that the attack only works against computers joined in a Windows domain, but after that, writing a patch was fairly simple. The image below shows its source code and the "Exploit Attempt Blocked" dialog that gets shown when ESTEEMAUDIT attack is detected and blocked.
Our patch is really simple: we check whether the data received from the remote smart card (imitated by ESTEEMAUDIT) is larger than 80h, which is the size of the destination buffer in gpkcsp.dll. If the received data is larger - and with ESTEEMAUDIT it is - we first alert our locally running 0patch agent (which pops up the alert) and then reduce the size of received data to 80h to prevent buffer overflow. This effectively blocks the attack without disrupting legitimate functionality by introducing just 4 machine instructions into the original code.
About a month later, Microsoft published their official update for ESTEEMAUDIT and several other vulnerabilities despite originally indicating that they would only provide these updates to customers with extended support. This is good: official vendor updates are the preferred way to fix vulnerabilities, and 0patch aims to provide most value when fixing issues that have no official fixes, or to provide protection from critical vulnerabilities to organizations in their security update gap.
Naturally, we were interested in how Microsoft fixed this vulnerability and compare their fix to ours. Enter IDA Pro and BinDiff; after a few minutes, we could compare the two side-by-side.
With fixed code on the left, and vulnerable code on the right, it's not-surprisingly obvious that Microsoft's patch also introduces the same check we did, at the exact same location. The main difference between our fixes is that while we just cut the received data to valid length, they spawn an error if the data is too long, and abandon the connection.
This makes sense: an official patch should provide troubleshooting info, wile a micropatch should just close the hole with minimum code.
But surprise: BinDiff shows another change.
Elsewhere in the code, Microsoft added another similar check, also checking for the received data length exceeding 80h - and responding with an error if so.
They obviously reviewed their code and noticed that a similar bug exists after another DoSCardTransmit call, and fixed it as well. Note that this second bug is not exploited by ESTEEMAUDIT, but would likely be found by interested parties based on the first one. Microsoft and other decent software vendors routinely search their code for vulnerabilities similar to those they learn about (either internally or externally), and proactively fix them.
This second bug, however, begs the question: Are there any other similar bugs there?
There are 66 calls to DoSCardTransmit in gpkcsp.dll, and we briefly looked at them. We were interested in cases where the received buffer would be copied to some other buffer. There actually was one such case, apart from those patched by Microsoft, as shown on the image below.
Again, the latest gpkcsp.dll is on the left side, and apparently no data length check was added to it. The code is suspiciously similar to the vulnerable code, but it really all depends on the size of the destination buffer at ds:[edx+ebx]. We had no time to look further into this but we hope Microsoft did and found it to be non-exploitable.
[Update 2019/4/15: We have subsequently learned that CVE-2017-9073 got marked a duplicate of CVE-2017-0176.]