Wacom Driver Arbitrary File Read\Write Vulnerability

ZDI-CAN-16318 (0-day)

Table of Contents 📜

  1. Premise
  2. Why another exploit?
  3. Analyzing /hex parameter
  4. From /hex parameter to Arbitrary File Read primitive
  5. POC - Arbitrary File Read
  6. From /hex parameter to Arbitrary File Write* primitive
  7. POC - Arbitrary File Write*
  8. Two primitives, one exploit
  9. Final considerations

Premise

This article aims to describe another way to exploit the Wacom Driver 6.3.45-1 vulnerability that I've already extensively detailed and discussed (in this report), so reading that report is necessary (and strongly recommended) to fully understand what you’re going to read (and this article can be helpful as well).
The topics, treated in a technical and concise way, can also be deepened through the links that you can find in the various paragraphs.

Why another exploit? ❔

In my previous report I've already explained how to exploit the vulnerability to get a Local Privilege Escalation, so why should I explain how to exploit the same vulnerability to get an Arbitrary File Read\Write primitive (that is less advantageous than the previous one)?
Mainly for the following two reasons:
  1. Before getting a LPE I found out how to get an Arbitrary File Read\Write primitive (and also an Arbitrary File Read primitive), and I think it's a shame not to explain how I did it.
  2. The technique I used to exploit the vulnerability is different from the one I used to get a LPE. It contains valuable logical concepts, which may be useful for developing other attack techniques and may not be known to many researchers.
  3. If I were the reader, and were interested in deepening more about logical vulnerabilities, I would like to know as many attack techniques as possible.
  4. For myself: explaining something is the best way to learn it (The Feynman Technique).
  5. To improve my poor written English 😟

Analyzing /hex parameter 🔍

This time everything revolves around the /hex parameter shown in the table.
Playing with this parameter I found out, using Process Monitor (in the same way I did here), that it expects a file path as a parameter; let's take an example to understand how it works:
/hex "C:\foo.jpg"
Remove.exe performs the following operations under the context of SYSTEM:
  1. Reads the contents of C:\foo.jpg
  2. Converts the read contents to hexadecimal format.
  3. Creates the C:\foo.jpg.txt file and saves the converted contents in it.
Have you already figured out how to exploit this behavior? If you've already read this article, you probably have.

From /hex parameter to Arbitrary File Read primitive 💡

If you've already read this paragraph you probably already guessed that, even in this case, a mount point and a symbolic link are what we need to get what we want.
In this case we don't need a directory traversal attack because, through the /hex parameter we can directly specify the full path of the file we want to read.
Theoretically, since we can directly specify the file on which we don't have read permission, it's not necessary to use a mount point combined with a symbolic link in this case, because Remove.exe would generate a copy of the file (in hexadecimal format) that the regular user can read.
But... What if the regular user doesn't have read permission on the entire folder where the file is located? It couldn't read the hex file created by Remove.exe either! Therefore, to avoid this situation, we can use a mount point combined with a symbolic link as it was done here, but with the following slight variations:

We want to read the C:\Users\Admin\Desktop\secret.txt file, but we don't have the privileges to read it.
We can perform the following steps to solve the problem:
  1. Create the C:\Users\StandardUser\Desktop\MountPoint mount point to \RPC Control
  2. Create the \RPC Control\Target.txt symbolic link to C:\Users\Admin\Desktop\secret.txt
  3. Create the \RPC Control\Target.txt.txt symbolic link to a folder that the user can read (e.g. C:\Users\StandardUser\Desktop\Target.txt.hex).
  4. Force Remove.exe to execute the following malicious parameter:
    /hex "C:\Users\StandardUser\Desktop\MountPoint\Target.txt"
  5. C:\Users\StandardUser\Desktop\MountPoint\Target.txt redirects Remove.exe to \RPC Control\Target.txt
  6. \RPC Control\Target.txt redirects Remove.exe to C:\Users\Admin\Desktop\secret.txt
    (We're doing all these redirects because we can no longer use hard links).
  7. Remove.exe reads C:\Users\Admin\Desktop\secret.txt and copies it contents (converted in hexadecimal format) to C:\Users\StandardUser\Desktop\MountPoint\Target.txt.txt
  8. C:\Users\StandardUser\Desktop\MountPoint\Target.txt.txt redirects Remove.exe to \RPC Control\Target.txt.txt
  9. \RPC Control\Target.txt.txt redirects Remove.exe to C:\Users\StandardUser\Desktop\secret.hex (where the file is actually written).
  10. Now the regular user can finally read the C:\Users\StandardUser\Desktop\secret.hex file 👀
As you can see, even if the regular user can't read any file located in the admin's desktop, this wouldn't be a problem because the copy (in hexadecimal format) of the file he wants to read, isn't saved in the same folder as the source file, but in a folder where the regular user has read permissions (C:\Users\StandardUser\Desktop in this case).

There is only one thing left to do...
The file that we couldn't read is now readable (C:\Users\StandardUser\Desktop\secret.hex), however it has been converted to hexadecimal according to this format (established by Remove.exe). What we need is a tool that can perform the reverse conversion to get the original file back.
To save some time I surfed the net for a tool that could work well for this purpose, but I didn't find anything convincing, so I decided to develop it on my own: HexFileConverter.
For my purpose it's sufficient to implement the conversion algorithm from the hexadecimal format (established by Remove.exe) to the original one but, since I was there, I also implemented the algorithm for the reverse conversion.
Here you can see how HexFileConverter works.
Here you can download HexFileConverter.
Now, using HexFileConverter, you can convert the hex file and read its contents in the original format ✔️

POC - Arbitrary File Read 🎦

I have tested the exploit only for Wacom Driver 6.3.45-1 but, most likely, it also works for the previous versions (and I hope not on the future ones 🙄).

Here you can find the C# source code of my exploit (Visual Studio Project.zip).
Here you can find the executable file (Exploit.exe).

CreateMountPoint.exe and CreateSymlink.exe are programs developed by James Forshaw and are downloadable from his symboliclink-testing-tools repository, respectively here and here.

From /hex parameter to Arbitrary File Write* primitive 💡

You may have noticed the asterisk next to Write, this means that it's possible to obtain an Arbitrary File Write primitive with partial control over the contents of the written\overwritten file, just like in this case with the /debug parameter.
The idea used to obtain the Arbitrary File Write* primitive is very similar to the one used to obtain the Arbitrary File Read primitive previously described but, in this case, the symbolic link to the file to be read points to a file whose contents (converted to hexadecimal format) will be written in the file we want to write (or overwrite), while the symbolic link from \RPC Control\Target.txt.txt points to the file we want to write (or overwrite).

Let's take a practical examples!
We want to overwrite the C:\Windows\win.ini file, but we don't have the privileges to write it.
We can perform the following steps to solve the problem:
  1. Create the C:\Users\StandardUser\Desktop\MountPoint mount point to \RPC Control
  2. Create the \RPC Control\Target.txt symbolic link to C:\Users\StandardUser\Desktop\ARB_RW\FileToConvertAndWrite.txt
    Note: FileToConvertAndWrite.txt is the file whose content (converted to hexadecimal format) will be written in the file we want to write\overwrite (win.ini in this case). If, for example, we want to overwrite the win.ini file with the 4F 56 45 52 57 52 49 54 54 45 4E string, we must write into FileToConvertAndWrite.txt the OVERWRITTEN string (because 4F 56 45 52 57 52 49 54 54 45 4E is the conversion of the text OVERWRITTEN into hexadecimal format (try this tool to do some tests)). A special case occurs when FileToConvertAndWrite.txt file is left blank; in this case the file we want to write\overwrite will be blank too.
  3. Create the \RPC Control\Target.txt.txt symbolic link to the file we want to write\overwrite (C:\Windows\win.ini in this case).
    Note: if the file pointed by the symbolic link doesn't exist, it will be created, otherwise it will be overwritten.
  4. Force Remove.exe to execute the following malicious parameter:
    /hex "C:\Users\StandardUser\Desktop\MountPoint\Target.txt"
  5. C:\Users\StandardUser\Desktop\MountPoint\Target.txt redirects Remove.exe to \RPC Control\Target.txt
  6. \RPC Control\Target.txt redirects Remove.exe to C:\Users\StandardUser\Desktop\ARB_RW\FileToConvertAndWrite.txt
    (We're doing all these redirects because we can no longer use hard links).
  7. Remove.exe reads C:\Users\StandardUser\Desktop\ARB_RW\FileToConvertAndWrite.txt and copies it contents (converted in hexadecimal format) to C:\Users\StandardUser\Desktop\MountPoint\Target.txt.txt
  8. C:\Users\StandardUser\Desktop\MountPoint\Target.txt.txt redirects Remove.exe to \RPC Control\Target.txt.txt
  9. \RPC Control\Target.txt.txt redirects Remove.exe to C:\Windows\win.ini (where the hexadecimal content is actually written).
  10. Now the contents of the target file (C:\Windows\win.ini) has been overwritten with the contents (converted to hexadecimal format) of FileToConvertAndWrite.txt

POC - Arbitrary File Write* 🎦

I have tested the exploit only for Wacom Driver 6.3.45-1 but, most likely, it also works for the previous versions (and I hope not on the future ones 🙄).

Here you can find the C# source code of my exploit (Visual Studio Project.zip).
Here you can find the executable file (Exploit.exe).

CreateMountPoint.exe and CreateSymlink.exe are programs developed by James Forshaw and are downloadable from his symboliclink-testing-tools repository, respectively here and here.

Two primitives, one exploit ☠️

It seemed to me more convenient to combine the read and write primitives in a single exploit instead of writing two separate ones.
As you have noticed from the two previous POCs, the user can easily choose which of the two primitives to use, typing 1 for the Arbitrary File Read and 2 for the Arbitrary File Write*.
The primitives are implemented via the two respective functions (arbr() and arbw()) which you can easily find in Program.cs (inside Visual Studio Project.zip) and separate for your uses.

Final considerations

The conclusions are the same as I wrote in my main report; I report below, for convenience, the most interesting paragraphs. Since the new concepts introduced by this report are essentially symbolic links and mount points, I want to add some other articles that may be useful to those who know nothing (or little) about them: And don't forget to read my report in which I explain how to exploit the same vulnerability to get an Arbitrary File Read primitive!



If you liked this article, what do you think about buying me a unicorn? Yeees! I'll buy it for you! 🦄