|
|
|
@@ -6,29 +6,12 @@ import sys
|
|
|
|
|
import code
|
|
|
|
|
|
|
|
|
|
import windows
|
|
|
|
|
from . import k32testing as kernel32proxy
|
|
|
|
|
from .generated_def import windef
|
|
|
|
|
from .generated_def.winstructs import *
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def fixedpropety(f):
|
|
|
|
|
cache_name = "_" + f.__name__
|
|
|
|
|
def prop(self):
|
|
|
|
|
try:
|
|
|
|
|
return getattr(self, cache_name)
|
|
|
|
|
except AttributeError:
|
|
|
|
|
setattr(self, cache_name, f(self))
|
|
|
|
|
return getattr(self, cache_name)
|
|
|
|
|
return property(prop)
|
|
|
|
|
|
|
|
|
|
def swallow_ctypes_copy(ctypes_object):
|
|
|
|
|
new_copy = type(ctypes_object)()
|
|
|
|
|
ctypes.memmove(ctypes.byref(new_copy), ctypes.byref(ctypes_object), ctypes.sizeof(new_copy))
|
|
|
|
|
return new_copy
|
|
|
|
|
from .. import k32testing
|
|
|
|
|
from ..generated_def import windef
|
|
|
|
|
from ..generated_def.winstructs import *
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Function resolution !
|
|
|
|
|
|
|
|
|
|
def get_func_addr(dll_name, func_name):
|
|
|
|
|
dll = ctypes.WinDLL(dll_name)
|
|
|
|
|
modules = windows.current_process.peb.modules
|
|
|
|
@@ -47,7 +30,7 @@ def get_remote_func_addr(target, dll_name, func_name):
|
|
|
|
|
def is_wow_64(hProcess):
|
|
|
|
|
try:
|
|
|
|
|
fnIsWow64Process = get_func_addr("kernel32.dll", "IsWow64Process")
|
|
|
|
|
except kernel32proxy.Kernel32Error:
|
|
|
|
|
except k32testing.Kernel32Error:
|
|
|
|
|
return False
|
|
|
|
|
IsWow64Process = ctypes.WINFUNCTYPE(BOOL, HANDLE, ctypes.POINTER(BOOL))(fnIsWow64Process)
|
|
|
|
|
Wow64Process = BOOL()
|
|
|
|
@@ -66,23 +49,19 @@ def get_handle_from_file(f):
|
|
|
|
|
return msvcrt.get_osfhandle(f.fileno())
|
|
|
|
|
|
|
|
|
|
def create_console():
|
|
|
|
|
"""| Create a new console displaying STDOUT
|
|
|
|
|
| Useful in injection of GUI process
|
|
|
|
|
"""
|
|
|
|
|
kernel32proxy.AllocConsole()
|
|
|
|
|
stdout_handle = kernel32proxy.GetStdHandle(windef.STD_OUTPUT_HANDLE)
|
|
|
|
|
"""Create a new console displaying STDOUT
|
|
|
|
|
Useful in injection of GUI process"""
|
|
|
|
|
k32testing.AllocConsole()
|
|
|
|
|
stdout_handle = k32testing.GetStdHandle(windef.STD_OUTPUT_HANDLE)
|
|
|
|
|
console_stdout = create_file_from_handle(stdout_handle, "w")
|
|
|
|
|
sys.stdout = console_stdout
|
|
|
|
|
|
|
|
|
|
stdin_handle = kernel32proxy.GetStdHandle(windef.STD_INPUT_HANDLE)
|
|
|
|
|
stdin_handle = k32testing.GetStdHandle(windef.STD_INPUT_HANDLE)
|
|
|
|
|
console_stdin = create_file_from_handle(stdin_handle, "r+")
|
|
|
|
|
sys.stdin = console_stdin
|
|
|
|
|
|
|
|
|
|
stderr_handle = kernel32proxy.GetStdHandle(windef.STD_ERROR_HANDLE)
|
|
|
|
|
stderr_handle = k32testing.GetStdHandle(windef.STD_ERROR_HANDLE)
|
|
|
|
|
console_stderr = create_file_from_handle(stderr_handle, "w")
|
|
|
|
|
#print(stderr_handle, console_stderr)
|
|
|
|
|
import os
|
|
|
|
|
#os.dup2(console_stderr.fileno(), 2)
|
|
|
|
|
sys.stderr = console_stderr
|
|
|
|
|
|
|
|
|
|
def create_process(path, show_windows=False):
|
|
|
|
@@ -92,12 +71,65 @@ def create_process(path, show_windows=False):
|
|
|
|
|
StartupInfo = STARTUPINFOA()
|
|
|
|
|
StartupInfo.cb = ctypes.sizeof(StartupInfo)
|
|
|
|
|
StartupInfo.dwFlags = 0
|
|
|
|
|
#StartupInfo.wShowWindow = SW_HIDE
|
|
|
|
|
lpStartupInfo = ctypes.byref(StartupInfo)
|
|
|
|
|
windows.k32testing.CreateProcessA(path, lpProcessInformation=ctypes.byref(proc_info), lpStartupInfo=lpStartupInfo)
|
|
|
|
|
proc = [p for p in windows.system.processes if p.pid == proc_info.dwProcessId][0]
|
|
|
|
|
return proc
|
|
|
|
|
|
|
|
|
|
def enable_privilege(lpszPrivilege, bEnablePrivilege):
|
|
|
|
|
"""Enable of disable a privilege: enable_privilege(SE_DEBUG_NAME, True)"""
|
|
|
|
|
tp = TOKEN_PRIVILEGES()
|
|
|
|
|
luid = LUID()
|
|
|
|
|
hToken = HANDLE()
|
|
|
|
|
|
|
|
|
|
k32testing.OpenProcessToken(k32testing.GetCurrentProcess(), TOKEN_ALL_ACCESS, byref(hToken))
|
|
|
|
|
k32testing.LookupPrivilegeValueA(None, lpszPrivilege, byref(luid))
|
|
|
|
|
tp.PrivilegeCount = 1
|
|
|
|
|
tp.Privileges[0].Luid = luid
|
|
|
|
|
if bEnablePrivilege:
|
|
|
|
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED
|
|
|
|
|
else:
|
|
|
|
|
tp.Privileges[0].Attributes = 0
|
|
|
|
|
k32testing.AdjustTokenPrivileges(hToken, False, byref(tp), sizeof(TOKEN_PRIVILEGES))
|
|
|
|
|
k32testing.CloseHandle(hToken)
|
|
|
|
|
if k32testing.GetLastError() == windef.ERROR_NOT_ALL_ASSIGNED:
|
|
|
|
|
raise ValueError("Failed to get privilege {0}".format(lpszPrivilege))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def check_is_elevated():
|
|
|
|
|
"""Return True if process is Admin"""
|
|
|
|
|
tp = TOKEN_PRIVILEGES()
|
|
|
|
|
hToken = HANDLE()
|
|
|
|
|
elevation = TOKEN_ELEVATION()
|
|
|
|
|
cbsize = DWORD()
|
|
|
|
|
|
|
|
|
|
bcsize = sizeof(elevation)
|
|
|
|
|
k32testing.OpenProcessToken(k32testing.GetCurrentProcess(), TOKEN_ALL_ACCESS, byref(hToken))
|
|
|
|
|
k32testing.GetTokenInformation(hToken, TokenElevation, byref(elevation), sizeof(elevation), byref(cbsize))
|
|
|
|
|
k32testing.CloseHandle(hToken)
|
|
|
|
|
return elevation.TokenIsElevated
|
|
|
|
|
|
|
|
|
|
def check_debug():
|
|
|
|
|
"""Check that kernel is in debug mode
|
|
|
|
|
beware if NOUMEX (https://msdn.microsoft.com/en-us/library/windows/hardware/ff556253(v=vs.85).aspx#_______noumex______)"""
|
|
|
|
|
hkresult = HKEY()
|
|
|
|
|
cbsize = DWORD(1024)
|
|
|
|
|
bufferres = (c_char * cbsize.value)()
|
|
|
|
|
|
|
|
|
|
k32testing.RegOpenKeyExA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control", 0, KEY_READ, byref(hkresult))
|
|
|
|
|
k32testing.RegGetValueA(hkresult, None, "SystemStartOptions", RRF_RT_REG_SZ, None, byref(bufferres), byref(cbsize))
|
|
|
|
|
k32testing.RegCloseKey(hkresult)
|
|
|
|
|
|
|
|
|
|
control = bufferres[:]
|
|
|
|
|
if "DEBUG" not in control:
|
|
|
|
|
#print "[-] Enable debug boot!"
|
|
|
|
|
#print "> bcdedit /debug on"
|
|
|
|
|
return False
|
|
|
|
|
if "DEBUG=NOUMEX" not in control:
|
|
|
|
|
pass
|
|
|
|
|
#print "[*] Warning noumex not set!"
|
|
|
|
|
#print "> bcdedit /set noumex on"
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
class FixedInteractiveConsole(code.InteractiveConsole):
|
|
|
|
|
def raw_input(self, prompt=">>>"):
|
|
|
|
@@ -105,15 +137,17 @@ class FixedInteractiveConsole(code.InteractiveConsole):
|
|
|
|
|
return raw_input("")
|
|
|
|
|
|
|
|
|
|
def pop_shell():
|
|
|
|
|
"""Pop a console with an InterativeConsole"""
|
|
|
|
|
create_console()
|
|
|
|
|
FixedInteractiveConsole(locals()).interact()
|
|
|
|
|
|
|
|
|
|
def get_kernel_modules():
|
|
|
|
|
cbsize = DWORD()
|
|
|
|
|
kernel32proxy.NtQuerySystemInformation(SystemModuleInformation, None, 0, byref(cbsize))
|
|
|
|
|
|
|
|
|
|
k32testing.NtQuerySystemInformation(SystemModuleInformation, None, 0, byref(cbsize))
|
|
|
|
|
raw_buffer = (cbsize.value * c_char)()
|
|
|
|
|
buffer = SYSTEM_MODULE_INFORMATION.from_address(ctypes.addressof(raw_buffer))
|
|
|
|
|
kernel32proxy.NtQuerySystemInformation(SystemModuleInformation, byref(raw_buffer), sizeof(raw_buffer), byref(cbsize))
|
|
|
|
|
k32testing.NtQuerySystemInformation(SystemModuleInformation, byref(raw_buffer), sizeof(raw_buffer), byref(cbsize))
|
|
|
|
|
modules = (SYSTEM_MODULE * buffer.ModulesCount).from_address(addressof(buffer) + SYSTEM_MODULE_INFORMATION.Modules.offset)
|
|
|
|
|
return list(modules)
|
|
|
|
|
|
|
|
|
@@ -134,19 +168,20 @@ class VirtualProtected(object):
|
|
|
|
|
|
|
|
|
|
def __enter__(self):
|
|
|
|
|
self.old_protect = DWORD()
|
|
|
|
|
kernel32proxy.VirtualProtect(self.addr, self.size, self.new_protect, ctypes.byref(self.old_protect))
|
|
|
|
|
k32testing.VirtualProtect(self.addr, self.size, self.new_protect, ctypes.byref(self.old_protect))
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
|
|
def __exit__(self, exc_type, exc_value, traceback):
|
|
|
|
|
kernel32proxy.VirtualProtect(self.addr, self.size, self.old_protect.value, ctypes.byref(self.old_protect))
|
|
|
|
|
k32testing.VirtualProtect(self.addr, self.size, self.old_protect.value, ctypes.byref(self.old_protect))
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
class DisableWow64FsRedirection(object):
|
|
|
|
|
"""A context manager that disable the Wow64 Fs Redirection"""
|
|
|
|
|
def __enter__(self):
|
|
|
|
|
self.OldValue = PVOID()
|
|
|
|
|
kernel32proxy.Wow64DisableWow64FsRedirection(ctypes.byref(self.OldValue))
|
|
|
|
|
k32testing.Wow64DisableWow64FsRedirection(ctypes.byref(self.OldValue))
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
|
|
def __exit__(self, exc_type, exc_value, traceback):
|
|
|
|
|
kernel32proxy.Wow64RevertWow64FsRedirection(self.OldValue)
|
|
|
|
|
k32testing.Wow64RevertWow64FsRedirection(self.OldValue)
|
|
|
|
|
return False
|