Threats like these show how vulnerability threats, like malware, are evolving to become more sophisticated. Despite the best attempts of vendors such as Microsoft to incorporate new and emerging technology to make exploitation more difficult, those behind these threats are just as ready to grow and make life more difficult for users.
Once we examined the .PDF file, we noticed a a suspicious FontDescriptor object in it. (A FontDescriptor object describes a font that has been used in the given .PDF file.)
The font’s stream is encoded with FlateDecode. Once we decoded this and found the SING table, we immediately saw something suspicious. The uniqueName field here is supposed to be a 27-character string encoded with 7-bit ASCII encoding and null-terminated.
However, the length of the data exceeds 28 bytes. This has all the hallmarks of a buffer overflow.
Via static analysis, we now know which part of the .PDF file was used in the exploit. We can then use a debugger to verify this and see just how it was used. Once the malicious .PDF file was opened in Adobe Reader, a call to the strcat function was made. Let’s look at what was in the source buffer at the time.
We have seen this “A8AAAAAA…” before. It was actually the content of the uniqueName field from earlier. The destination buffer is on the stack with a fixed size. Combined, this causes an overflow.
After the overflow, a function pointer on the stack will be overwritten with the value 0x4a80cb38. This function pointer will be called later, effectively passing control of execution to the attacker.
By itself, an overflow is not all that interesting nor unusual. However, this particular exploit used ROP to bypass one of Windows’ exploitation mitigation mechanisms, DEP. DEP tries to prevent attacks by disabling the execution of code that comes from nonexecutable pages in memory.
ROP is designed to defeat DEP by using parts of already-loaded code that are marked executable to perform its routines. The logic in ROP is that for any sufficiently large code base, a working exploit can be formed by reusing existing code and forming a “chain.”
The attacker chose the icucnv36.dll component of Reader to target. The said component does not support address space layout randomization (ASLR), which makes it more vulnerable to ROP attacks. The address mentioned earlier—0x4a80cb38—is the starting point in icucnv36.dll for this particular shellcode:
4a80cb38 81c594070000 add ebp,794h
4a80cb3e c9 leave
4a80cb3f c3 ret
The highlighted part will be the double word in memory with the value 0x4a801064 after some replacement and unescape operations.
This is native x86 code, which was used to carry out the actual malicious routines.
Returning to the first-stage ROP code after adjusting the stack pointer, the code looks for portions of icucnv36.dll, calling several APIs:
- It calls CreateFileA to create a file named “iso88591” (the file name is not important).
- It calls CreateFileMappingA with flProtect=0x40 (allows the file to be executed).
- It calls MapViewOfFile to map the created file.
- It calls memcpy to copy the second-stage code to the buffer, which points to the beginning of the shared mapping file.
- It jumps to the beginning of the file-mapping buffer. Since the memory is executable, it bypasses DEP protection.