From b1d4f23bb7f09c1ab909dba837682cd5ed2e7514 Mon Sep 17 00:00:00 2001 From: Clement Rouault Date: Wed, 23 Sep 2015 09:47:58 +0200 Subject: [PATCH] widows.utils is now a directory --- generated_def/windef.py | 7 ++- remote_callback.py | 20 ------ utils/__init__.py | 2 + utils/pythonutils.py | 18 ++++++ utils.py => utils/winutils.py | 111 ++++++++++++++++++++++------------ 5 files changed, 99 insertions(+), 59 deletions(-) delete mode 100644 remote_callback.py create mode 100644 utils/__init__.py create mode 100644 utils/pythonutils.py rename utils.py => utils/winutils.py (52%) diff --git a/generated_def/windef.py b/generated_def/windef.py index 6e7d2a9..e64c7a9 100644 --- a/generated_def/windef.py +++ b/generated_def/windef.py @@ -470,4 +470,9 @@ KEY_READ = Flag("KEY_READ", ( ( STANDARD_RIGHTS_READ|KEY_QUERY_VALUE|KEY_ENUMERA KEY_WRITE = Flag("KEY_WRITE", ( ( STANDARD_RIGHTS_WRITE|KEY_SET_VALUE|KEY_CREATE_SUB_KEY ) & ( ~SYNCHRONIZE ) )) KEY_EXECUTE = Flag("KEY_EXECUTE", ( ( KEY_READ ) & ( ~SYNCHRONIZE ) )) KEY_ALL_ACCESS = Flag("KEY_ALL_ACCESS", ( ( STANDARD_RIGHTS_ALL|KEY_QUERY_VALUE|KEY_SET_VALUE|KEY_CREATE_SUB_KEY|KEY_ENUMERATE_SUB_KEYS|KEY_NOTIFY|KEY_CREATE_LINK ) & ( ~SYNCHRONIZE ) )) -STATUS_INFO_LENGTH_MISMATCH = Flag("STATUS_INFO_LENGTH_MISMATCH", ( 0xC0000004 )) \ No newline at end of file +STATUS_INFO_LENGTH_MISMATCH = Flag("STATUS_INFO_LENGTH_MISMATCH", ( 0xC0000004 )) +ERROR_NOT_ALL_ASSIGNED = Flag("ERROR_NOT_ALL_ASSIGNED", 1300) +S_OK = Flag("S_OK", 0) +S_FALSE = Flag("S_FALSE", 1) +E_NOINTERFACE = Flag("E_NOINTERFACE", 0x80004002) +E_FAIL = Flag("E_FAIL", 0x80004005) \ No newline at end of file diff --git a/remote_callback.py b/remote_callback.py deleted file mode 100644 index d4c5a5c..0000000 --- a/remote_callback.py +++ /dev/null @@ -1,20 +0,0 @@ -import ctypes -import ctypes.wintypes -from windows.hooks import * - -# Example of callback for IAT hooks - -@Callback(ctypes.c_void_p, ctypes.c_ulong) -def exit_callback(x, real_function): - print("Try to quit with {0} | {1}".format(x, type(x))) - if x == 3: - print("TRYING TO REAL EXIT") - return real_function(1234) - return 0x4242424243444546 - -@CreateFileACallback -def createfile_callback(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, real_function): - print("Trying to open {0}".format(lpFileName)) - if "dick" in lpFileName: - return 0x4242 - return real_function() diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..5cf9c13 --- /dev/null +++ b/utils/__init__.py @@ -0,0 +1,2 @@ +from pythonutils import * +from winutils import * \ No newline at end of file diff --git a/utils/pythonutils.py b/utils/pythonutils.py new file mode 100644 index 0000000..a9fc8a5 --- /dev/null +++ b/utils/pythonutils.py @@ -0,0 +1,18 @@ +"""utils fonctions non windows-related""" +import ctypes + + +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 \ No newline at end of file diff --git a/utils.py b/utils/winutils.py similarity index 52% rename from utils.py rename to utils/winutils.py index 54b55ee..c8e253d 100644 --- a/utils.py +++ b/utils/winutils.py @@ -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