Langsung ke konten utama

Attacking The Windows Nvidia Driver

Posted yesteryear Oliver Chang

Modern graphic drivers are complicated in addition to furnish a large promising assault surface for EoPs in addition to sandbox escapes from processes that receive got access to the GPU (e.g. the Chrome GPU process). In this spider web log post service we’ll convey a aspect at attacking the NVIDIA essence fashion Windows drivers, in addition to a few of the bugs that I found. I did this enquiry every bit component of a 20% projection amongst , during which a full of 16 vulnerabilities were discovered.

Kernel WDDM interfaces

The essence fashion element of a graphics driver is referred to every bit the display miniport driver. Microsoft’s documentation has a overnice diagram that summarises the human relationship betwixt the diverse components:

Modern graphic drivers are complicated in addition to furnish a large promising assault surface for Eo Attacking the Windows NVIDIA Driver

In the DriverEntry() for display miniport drivers, a DRIVER_INITIALIZATION_DATA construction is populated amongst callbacks to the vendor implementations of functions that truly interact amongst the hardware, which is passed to dxgkrnl.sys (DirectX subsystem) via DxgkInitialize(). These callbacks tin give the axe either last called yesteryear the DirectX essence subsystem, or inwards to a greater extent than or less cases larn called straight from user fashion code.

DxgkDdiEscape

A good known entry dot for potential vulnerabilities hither is the DxgkDdiEscape interface. This tin give the axe last called straight from user mode, in addition to accepts arbitrary information that is parsed in addition to handled inwards a vendor specific way (essentially an IOCTL). For the residuum of this post, we’ll exercise the term “escape” to announce a special command that’s supported yesteryear the DxgkDdiEscape function.

NVIDIA has a whopping 400 escapes hither at fourth dimension of writing, hence this was where I spent most of my fourth dimension (the necessity of many of these beingness inwards the essence is questionable):


// (names of these structs are made upwards yesteryear me)
// Represents a grouping of escape codes
struct NvEscapeRecord {
 DWORD action_num;
 DWORD expected_magic;
 void *handler_func;
 NvEscapeRecordInfo *info;
 _QWORD num_codes;
};

// Information nearly a specific escape code.
struct NvEscapeCodeInfo {
 DWORD code;
 DWORD unknown;
 _QWORD expected_size;
 WORD unknown_1;
};

NVIDIA implements their mortal information (pPrivateDriverData inwards the DXGKARG_ESCAPE struct) for each escape every bit a header followed yesteryear data. The header has the next format:

struct NvEscapeHeader {
 DWORD magic;
 WORD unknown_4;
 WORD unknown_6;
 DWORD size;
 DWORD magic2;
 DWORD code;
 DWORD unknown[7];
};

These escapes are identified yesteryear a 32-bit code (first fellow member of the NvEscapeCodeInfo struct above), in addition to are grouped yesteryear their most pregnant byte (from 1 - 9).

There is to a greater extent than or less validation beingness done earlier each escape code is handled. In particular, each NvEscapeCodeInfo contains the expected size of the escape information next the header. This is validated against the size inwards the NvEscapeHeader, which itself is validated against the PrivateDriverDataSize plain given to DxgkDdiEscape. However, it’s possible for the expected size to last 0 (usually when the escape information is expected to last variable sized) which agency that the escape handler is responsible for doing its ain validation. This has led to to a greater extent than or less bugs (1, 2).

Most of the vulnerabilities works life (13 inwards total) inwards escape handlers were really basic mistakes, such every bit writing to user provided pointers blindly, disclosing uninitialised essence retentiveness to user mode, in addition to wrong bounds checking. There were also numerous issues that I noticed (e.g. OOB reads) that I didn’t study because they didn’t seem exploitable.

DxgkDdiSubmitBufferVirtual

Another interesting entry dot is the DxgkDdiSubmitBufferVirtual function, which is newly introduced inwards Windows 10 in addition to WDDM 2.0 to back upwards GPU virtual retentiveness (deprecating the erstwhile DxgkDdiSubmitBuffer/DxgkDdiRender functions). This business office is fairly complicated, in addition to also accepts vendor specific information from the user fashion driver for each command submitted. One põrnikas was works life here.

Others

There are a few other WDDM functions that convey vendor-specific data, only zilch of involvement were works life inwards those later on a quick review.

Exposed devices

NVIDIA also exposes to a greater extent than or less additional devices that tin give the axe last opened yesteryear whatever user:

  • \\.\NvAdminDevice which appears to last used for NVAPI. H5N1 lot of the ioctl handlers seem to telephone band into DxgkDdiEscape.
  • \\.\UVMLite{Controller,Process*}, probable related to NVIDIA’s “unified memory”. 1 bug was works life here.
  • \\.\NvStreamKms, installed yesteryear default every bit component of GeForce Experience, only yous tin give the axe opt out during installation. It’s non precisely clear why this special driver is necessary. 1 bug was works life hither also.

More interesting bugs

Most of the bugs I works life were yesteryear manual reversing in addition to analysis, along amongst to a greater extent than or less custom IDA scripts. I also ended upwards writing a fuzzer, which was surprisingly successful given how uncomplicated it was.

While most of the bugs were rather slowly (simple cases of missing validation), at that spot were a few that were a fight to a greater extent than interesting.

NvStreamKms

This driver registers a procedure creation notification callback using the PsSetCreateProcessNotifyRoutineEx function. This callback checks if novel processes created on the organisation fit icon names that were previously laid yesteryear sending IOCTLs.

This creation notification routine contained a bug:

(Simplified decompiled output)

wchar_t Dst[BUF_SIZE];

...

if ( cur->image_names_count > 0 ) {
 // info_ is the PPS_CREATE_NOTIFY_INFO that is passed to the routine.
 image_filename = info_->ImageFileName;
 buf = image_filename->Buffer;
 if ( buf ) {
   filename_length = 0i64;
   num_chars = image_filename->Length / 2;
   // Look for the filename yesteryear scanning for backslash.
   if ( num_chars ) {
     while ( buf[num_chars - filename_length - 1] != '\\' ) {
       ++filename_length;
       if ( filename_length >= num_chars )
         goto DO_COPY;
     }
     buf += num_chars - filename_length;
   }
DO_COPY:
   wcscpy_s(Dst, filename_length, buf);
   Dst[filename_length] = 0;
   wcslwr(Dst);

This routines extracts the icon shout out from the ImageFileName fellow member of PS_CREATE_NOTIFY_INFO yesteryear searching backwards for backslash (‘\’). This is in addition to hence copied to a stack buffer (Dst) using wcscpy_s, only the length passed is the length of the calculated name, in addition to non the length of the finish buffer.

Even though Dst is a fixed size buffer, this isn’t a straightforward overflow. Its size is bigger than 255 wchars, in addition to for most Windows filesystems path components cannot last greater than 255 characters. Scanning for backslash is also valid for most cases because ImageFileName is a canonicalised path.

It is however, possible to transcend a UNC path that keeps forrad slash (‘/’) every bit the path separator later on beingness canonicalised (credits to James Forshaw for pointing me to this). This agency nosotros tin give the axe larn a filename of the shape “aaa/bbb/ccc/...” in addition to displace an overflow.

For example: CreateProcessW(L"\\\\?\\UNC\\127.0.0.1@8000\\DavWWWRoot\\aaaa/bbbb/cccc/blah.exe", …)

Another interesting banking concern annotation is that the wcslwr next the bad re-create doesn’t truly boundary the contents of the overflow (the exclusively requirement is valid UTF-16). Since the calculated filename_length doesn’t include the null terminator, wcscpy_s volition retrieve that the finish is every bit good pocket-sized in addition to volition clear the finish string yesteryear writing a null byte at the showtime (after copying the contents upwards to filename_length bytes firstly hence the overflow still happens). This agency that the wcslwr is useless because this wcscpy_s telephone band in addition to component of the code never worked to get with.

Exploiting this is trivial, every bit the driver is non compiled amongst stack cookies (hacking similar it’s 1999). H5N1 local privilege escalation exploit is attached inwards the original issue that sets upwards a simulated WebDAV server to exploit the vulnerability (ROP, pin stack to user buffer, ROP i time again to allocate rwx mem containing shellcode in addition to bound to it).

Incorrect validation inwards UVMLiteController

NVIDIA’s driver also exposes a device at \\.\UVMLiteController that tin give the axe last opened yesteryear whatever user (including from the sandboxed Chrome GPU process). The IOCTL handlers for this device write results straight to Irp->UserBuffer, which is the output pointer passed to DeviceIoControl (Microsoft’s documentation  says non to create this).The IO command codes specify METHOD_BUFFERED, which agency that the Windows essence checks that the address hit provided is writeable yesteryear the user earlier passing it off to the driver.

However, these handlers lacked bounds checking for the output buffer, which agency that a user fashion context could transcend a length of 0 amongst whatever arbitrary address (which passes the ProbeForWrite check) to number inwards a express write-what-where (the “what” hither is express to to a greater extent than or less specific values: including 32-bit 0xffff, 32-bit 0x1f, 32-bit 0, in addition to 8-bit 0).

A uncomplicated privilege escalation exploit is attached inwards the original issue.

Remote assault vector?

Given the quantity of bugs that were discovered, I investigated whether if whatever of them tin give the axe last reached from a completely remote context without having to compromise a sandboxed procedure firstly (e.g. through WebGL inwards a browser, or through video acceleration).

Luckily, this didn’t appear to last the case. This wasn’t every bit good surprising, given that the vulnerable APIs hither are really depression score in addition to exclusively reached later on going through many layers (for Chrome, libANGLE -> Direct3D runtime in addition to user fashion driver -> essence fashion driver), in addition to to a greater extent than ofttimes than non called amongst valid arguments constructed inwards the user fashion driver.

NVIDIA’s response

The nature of the bugs works life showed that NVIDIA has a lot of piece of occupation to do. Their drivers contained a lot of code which in all probability shouldn’t last inwards the kernel, in addition to most of the bugs discovered were really basic mistakes. One of their drivers (NvStreamKms.sys) also lacks really basic mitigations (stack cookies) fifty-fifty today.

However, their response was mostly quick in addition to positive. Most bugs were fixed good nether the deadline, in addition to it seems that they’ve been finding to a greater extent than or less bugs on their ain internally. They also indicated that they’ve been working on re-architecturing their essence drivers for security, only weren’t ready to portion whatever concrete details.

Timeline

2016-07-26
First põrnikas reported to NVIDIA.
2016-09-21
6 of the bugs reported were fixed silently inwards the 372.90 release. Discussed field gap issues amongst NVIDIA.
2016-10-23
Patch released that includes prepare for residuum (all 14) of the bugs that were reported at the fourth dimension (375.93).
2016-10-28
Public bulletin released, in addition to P0 bugs derestricted.
2016-11-04
Realised that https://bugs.chromium.org/p/project-zero/issues/detail?id=911 wasn’t fixed properly. Notified NVIDIA.
2016-12-14
Fix for number 911 released along amongst bulletin.
2017-02-14
Final 2 bugs fixed.

Patch gap

NVIDIA’s firstly patch, which included fixes to vi of the bugs I reported, did non include a world bulletin (the release notes cite “security updates”). They had planned to loose world details a calendar month later on the field is released. We noticed this, in addition to allow them know that nosotros didn’t consider this to last expert practise every bit an aggressor tin give the axe contrary the field to uncovering the vulnerabilities earlier Earth is made aware of the details given this large window.

While the firstly vi bugs fixed did non receive got details released for to a greater extent than than xxx days, the remaining 8 at the fourth dimension had a field released v days earlier the firstly bulletin was released. It looks similar NVIDIA has been trying to cut down this gap, only based on recent bulletins it appears to last inconsistent.

Conclusion

Given the large assault surface exposed yesteryear graphics drivers inwards the essence in addition to the to a greater extent than ofttimes than non lower character of tertiary political party code, it appears to last a really rich target for finding sandbox escapes in addition to EoP vulnerabilities. GPU vendors should attempt to boundary this yesteryear moving every bit much assault surface every bit they tin give the axe out of the kernel.

Komentar

Postingan populer dari blog ini

Chrome Bone Exploit: 1 Byte Overflow As Well As Symlinks

The next article is an invitee weblog post from an external researcher (i.e. the writer is non a or Google researcher). This post is most a Chrome OS exploit I reported to Chrome VRP inward September. The folks were squeamish to allow me do a invitee post most it, therefore hither goes. The study includes a detailed writeup , therefore this post volition have got less detail. 1 byte overflow inward a DNS library In Apr I constitute a TCP port listening on localhost inward Chrome OS. It was an HTTP proxy built into shill, the Chrome OS network manager. The proxy has at nowadays been removed equally component of a fix, but its source tin give notice nonetheless move seen from an one-time revision: shill/http_proxy.cc . The code is unproblematic in addition to doesn’t seem to incorporate whatever obvious exploitable bugs, although it is real liberal inward what it accepts equally incoming HTTP. It calls into the c-ares library for resolving DNS. There was a possible 1 byte ov...

Exception-Oriented Exploitation On Ios

Posted past times Ian Beer, This postal service covers the regain in addition to exploitation of CVE-2017-2370 , a heap buffer overflow inwards the mach_voucher_extract_attr_recipe_trap mach trap. It covers the bug, the evolution of an exploitation technique which involves repeatedly in addition to deliberately crashing in addition to how to build alive meat introspection features using onetime meat exploits. It’s a trap! Alongside a large number of BSD syscalls (like ioctl, mmap, execve in addition to so on) XNU also has a pocket-sized number of extra syscalls supporting the MACH side of the meat called mach traps. Mach trap syscall numbers start at 0x1000000. Here’s a snippet from the syscall_sw.c file where the trap tabular array is defined: /* 12 */ MACH_TRAP(_kernelrpc_mach_vm_deallocate_trap, 3, 5, munge_wll), /* xiii */ MACH_TRAP(kern_invalid, 0, 0, NULL), /* xiv */ MACH_TRAP(_kernelrpc_mach_vm_protect_trap, 5, 7, munge_wllww), Most of the mach traps a...

Lifting The (Hyper) Visor: Bypassing Samsung’S Real-Time Total Protection

Posted yesteryear Gal Beniamini, Traditionally, the operating system’s total is the concluding security boundary standing betwixt an assaulter together with total command over a target system. As such, additional aid must hold upwards taken inwards lodge to ensure the integrity of the kernel. First, when a organization boots, the integrity of its primal components, including that of the operating system’s kernel, must hold upwards verified. This is achieved on Android yesteryear the verified kicking chain . However, only booting an authenticated total is insufficient—what most maintaining the integrity of the total spell the organization is executing? Imagine a scenario where an assaulter is able to abide by together with exploit a vulnerability inwards the operating system’s kernel. Using such a vulnerability, the assaulter may endeavor to subvert the integrity of the total itself, either yesteryear modifying the contents of its code, or yesteryear introducing novel attacker-co...