In this case, the Path element is parsed via the xps_parse_path() function which allows extraction of the attributes and extended attributes (Clip, Data, Fill, …).
If some conditions are fulfilled, we can trigger a stack overflow in the xps_parse_color() function when it parses the value "ContextColor" of the attribute "Fill".

Exploitation

I decided to use the latest version of the executable provided on the official website.

Software : MuPDF v1.3

Tested on : Windows XP SP3 (fr) / Windows 7 x64 (fr)

It doesn’t matter if the executable is compiled with /GS (this is the case on mupdf.exe). The reason is that the stack concerns a float array and an old version of Visual Studio doesn't add security cookies in this case.If it was the case the vulnerability would be more difficult to exploit. We can't erase the SEH because of the small stack buffer but depending on the concerned software, it maybe possible to replace interesting variables or structures values to control the EIP.

Given that « samples » is a float array, we have to make our payload fit into an array of floats.The size of the temporary buffer is limited to 0x400 bytes as can be seen in fz_strlcpy(…). As said above, we have to make our payload fit into an array of floats. For this reason it's important that each float has a long ansi size (about 22 bytes), otherwise it could be not precise enough to get the real 4-bytes values. So, 1024 / 22 = 46 * 4 bytes = 184 bytes (not enough to put our shellcode).

We need to write our shellcode into the heap, so maybe we could put a stack pivot to return at the beginning of the stack buffer, process the ROP chain and then do an egg hunter to execute the shellcode from the heap but there is a much nicer solution.It's possible to trigger multiple aligned allocations into the heap, even if we can't use javascript scripting routine. I used the "font" attribute to allocate binary data, controlling the size for each of them else it's not possible to make precise allocations. So we can now put the ROP and shellcode directly at 0x0c0c0c0c.

If we take a look at the assembly code, the functions displayed below are used to do most of the allocations of elements and resources :

Finally, our font allocations are done and will remain without being freed.
Practically, we need to generate many font files containing our binary data into a folder and write the path of each of them into the page file using FontUri attribute of Glyphs like shown below to load them.