This submit breaks the two-year silence of this blog, showcasing a selection of Memory Wave corruption vulnerabilities in Bitdefender’s anti-virus engine. The aim of binary packing is to compress or obfuscate a binary, often to save space/bandwidth or to evade malware evaluation. A packed binary typically contains a compressed/obfuscated information payload. When the binary is executed, a loader decompresses this payload after which jumps to the precise entry point of the (inner) binary. Most anti-virus engines support binary unpacking at the least for packers (equivalent to UPX) which might be very talked-about and which can be additionally utilized by non-malware software program. This weblog submit is about UPX unpacking of PE binaries in the Bitdefender core engine. The next vulnerabilities are presented in the control-flow order of the UPX unpacker. Disclaimer: In the following, decompiled code from Bitdefender’s core engine is presented. The naming of variables, fields, and macros is closely impressed by the original UPX. For memory improvement solution some snippets, a reference to the original function is added for comparison.
It is probably going that some sorts are incorrect. After the UPX loader has been detected, the Bitdefender engine tries to detect whether the loader applies a specific kind of deobfuscation to the compressed knowledge payload earlier than extracting it. LEFT. If this deobfuscation is detected, then the engine iterates by the corresponding directions of the loader and parses them with their operands in order to be able to deobfuscate the information as nicely. Observe how the sure-check on the index variable i is carried out. 16. Specifically, we are able to increase i from 15 to 17, after which we will overwrite the stack with utterly arbitrary information. The debug break is because of the stack canary which we've got overwritten. If we proceed, we see that the return fails as a result of the stack is corrupted. Clearly, this offsets must be checked earlier than writing to it. Each checks check in opposition to the sector dword10.
The field dword10, sitting on the calling functions’s stack frame, isn't initialized. This makes the sure check ineffective and Memory Wave introduces a totally attacker-managed heap buffer overflow. After the extraction, the engine attempts to deobfuscate the extracted knowledge with a static XOR key. The bound verify is completely unsuitable. It should verify in opposition to the size of the extracted information buffer. Instead, it checks in opposition to a value that is previously set to the uncooked information size of the part we extracted the data from. These two sizes have nothing to do with each other. Particularly, one may be a lot smaller than the other, or vice-versa. Because the perform does not return after the first deobfuscation run, the memory improvement solution corruption could be triggered up to 0x300 instances in a row. This allows us to bypass the limitation that in a single deobfuscation run we at all times XOR with the same byte. Overall, we then have XORed with C0 C0 C1 C1 C1 C2 C2 for completely arbitrary C0, C1, and C2.
We can essentially XOR with such a sample of nearly arbitrary size, and switch the byte at most 0x300 occasions. For sure, this vulnerability is a helpful exploitation primitive because it allows very powerful memory corruptions: XORing allows us to change selectively only certain parts of information, leaving other parts (for instance heap metadata or important objects) untouched. A filter is a simple transformation on binary code (say, x86-sixty four code) that is applied earlier than compression, with the goal to make the code extra compressible. After we have decompressed the data, we have to revert this filtering. Bitdefender helps about 15 different filters. Of the 15 filters, about eight seem to be affected by such a heap buffer overflow. I handled all of them together as one bug (in spite of everything, it's not unlikely that they share code). The next memory corruption occurs in a loop of the perform PeFile::rebuildImports (cf.