Talos Vulnerability Report

TALOS-2019-0796

May 14, 2019

CVE Number

CVE-2019-7831

Summary

A specific JavaScript code embedded in a PDF file can lead to a heap corruption when opening a PDF document in Adobe Acrobat Reader DC 2019.10.20098. With careful memory manipulation, this can lead to arbitrary code execution. In order to trigger this vulnerability, the victim would need to open the malicious file or access a malicious web page.

Tested Versions

Adobe Acrobat Reader DC 2019.010.20098

Product URLs

CVSSv3 Score

8.0 - CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-416: Use After Free

Details

Adobe Acrobat Reader is the most popular and feature-rich PDF reader. It has a big user base, is usually a default PDF reader on systems and integrates into web browsers as a plugin for rendering PDFs. As such, tricking a user into visiting a malicious web page or sending a specially crafted email attachment can be enough to trigger this vulnerability.

Adobe Acrobat Reader DC supports embedded JavaScript code in the PDF to allow for interactive PDF forms. This gives the potential attacker the ability to precisely control memory layout and poses additional attack surface. One method call required to trigger this vulnerability is privileged and can only be called from trusted functions or from a trusted location.

A use after free vulnerability can be triggered by using an undocumented FormWorkflow.setFormFolderForMultipleForms function with an app.thermometer GUI element. The following code triggers the allocation, freeing, and reuse of the freed object:

In the above code, the first line calls an undocumented function FormWorkflow.setFormFolderForMultipleForms with app.thermometer as a second parameter. This, as a side-effect, allocates an object and affects app.thermometer. Object app.thermometer is a sort of progress bar that is to be displayed to a user while something dynamic is happening with the document. Second line, although not directly related, frees the previously allocated object as a side effect. Accessing or manipulating the app.thermometer object in the third line then reuses the freed object causing memory corruption. This can be seen in the following debug output:

In the above output, we put a breakpoint right before calling a function where the object is first used. PageHeap shows us an object of size 0x48 allocated at 0x3e7d8fb8. This breakpoint is hit after the first line in the PoC is triggered. As the second line causes an object to be freed, when the same breakpoint is hit after the 3rd line is executed we see:

We can observe that eax is still the same pointer, but now pointing to invalid memory. PageHeap also confirms this, showing where the object is freed. Continuing the execution leads to the following crash:

Notice that eax is still the same and the process crashed due to read access violation. Without PageHeap, by making additional allocations between 2nd and 3rd line in the PoC , we can place another object in place of the freed one. With precise control over the allocated object, this could lead to further memory corruption, information leaks and ultimately arbitrary code execution.