Copy My Write

Abusing DDMA alongside Copy on Write for cross-process code execution leading to a $3000 Bug Bounty.

  ·   3 min read

Introduction #

In my previous blog post, Runtime Hyper-V Hijacking, I discussed the implications of direct SCSI commands to disk drives, including the ability to read/write directly to physical memory. The only issue was, to manipulate pages, they must be mapped into the current virtual address space for translation by the disk driver before reaching the disk itself. In the context of a kernel driver, this is not an issue as the kernel has access to manipulate page tables directly; however, in usermode, this is not the case. Given this limitation, I explored other ideas for exploitation, and one idea stood out: Copy On Write (CoW). Copy On Write is a memory management technique where multiple processes can share the same underlying physical memory pages until one of them attempts to modify the page. At that point, a copy of the page is created for the modifying process, allowing it to make changes without affecting the original page. CoW is used in order to save physical memory for identical memory across multiple processes, such as RX sections of DLLs. The vulnerability lies in the fact that CoW is only triggered upon the CPU writing to the page, and does not handle writes from other devices, such as disk controllers. This means that we can manipulate the physical memory of shared pages directly via DDMA, without triggering the CoW mechanism. This opens up the possibility of modifying memory in other processes without their knowledge, such as the executable sections of DLLs, leading to code execution. In this blog post, I will demonstrate my POC CopyMyWrite, and how it achieves cross-process code execution via DDMA and Copy on Write.

Implementation #

My idea was to follow in the footsteps of the very popular Perfect Injector, and its method to execute in the target process through only physical memory manipulation. For more details, I recommend reading Can’s article on his blog. To sum it up, we will hook the TlsGetValue stub in kernel32.dll (which is only a jmp instruction to the main function body), and redirect it to a shellcode stub stored at the end of the DLLs .text section. Because we evade Copy on Write through direct disk commands, we should end up with a system-wide hook. From there, we can filter for our target process through checking the PID from the TEB. Once it is confirmed we are executing within the target process, the rest of the payload can proceed to be executed. The source code for the POC can be found on GitHub, and I encourage you to read through the specific details of how it works. This vulnerability is also entirely HVCI/VBS compliant as it runs entirely from usermode.

Results #

I tested the CopyMyWrite POC against all large commercial anticheats, and was able to achieve code execution in all of them. For example, against Vanguard in Valorant, I was able to execute a simple shellcode payload that enabled chams on player models, allowing for wallhacks. Whilst the method of doing so may be detected, the fact that I was able to achieve code execution is the significant achievement.

The same method was successful against EDR solutions such as Microsoft Defender, where executing the NtTerminateProcess syscall kills the process from the inside.

I also submitted the vulnerability to an undisclosed major game company, and was awarded a $3000 bounty for the finding. As a high schooler, that felt like a pretty big deal to me!

bounty

Thanks for reading!

Resources #