zhuowei/MacDirtyCowDemo

Functions hook

Closed this issue · 4 comments

Hello everyone again, I have a new thought. We have every right to change the addresses in memory (using the example of the same exploit). After thinking about it, I realized that we can also change the addresses of the functions themselves, embedding artificial functions in place of the original functions. (using the handle obtained using dlopen() and then we get the address of the function obtained through dlsym()) By selecting the system library whose function calls are performed with kernel privileges, we can hook this function, thereby executing arbitrary code with kernel privileges. Why not?

Dry05 commented

That’s actually not a bad idea, did you try this?

Unfortunately, once again, it didn't work. As I found out, the system API does not lie in RAM, but is called directly from libraries and frameworks. Accordingly, they simply do not exist in memory, and it will not work to change them either. At the moment, we need to search for an API that lies in memory, and can also be located in user space. That's when we can implement the above

The closest target is the drivers. Because, firstly, they lie in the user space (photo processing, video, etc.), and secondly, these drivers clearly have high privileges. However, at the moment I have no idea what they are represented by, and how to find them.

My understanding is that

  • for system libraries and executables, overwriting their code on disk will cause them to fail codesigning either during execution or the next time they launch
  • overwriting their code in memory doesn't work: dyld maps code as MAP_PRIVATE instead of MAP_SHARED, so any changes are private to our app in memory and gets discarded after our app exits
  • most drivers do not live in userspace: they are kexts in kernel space
  • some drivers are DriverKit drivers in userspace, but again, overwriting executables will cause them to fail codesigning.
  • So only resources can be overwritten as far as I know.
  • (There's also another test case in the XNU source that bypasses copy-on-write on shared memory, so you might be able to change a XPC message after you sent it; Ian Beer had exploited this before. However, I don't know where to start with this, and there's a lot more low-hanging fruit on macOS)
  • I don't know any example of a kernel space driver sharing read-only data with userspace that we can overwrite with this, although maybe there is one? I'm not sure how to find it.
    • (They exist: for example, Hypervisor.framework maps one read-write and one readonly page from the kernel into userspace, but there's nothing on the readonly page worth overwriting, as far as I know, so I didn't try.)
  • There are many data/resource files on macOS that are not codesigned and that we can overwrite - this repo demonstrates overwriting one.

Of course, I don't have much experience here either, so let me know if you find something cool.