def get_proc(self, name): global GetProcAddress32 if self.process.bits == 32 and sys.maxsize > 2**32: if GetProcAddress32 is None: fd, path = tempfile.mkstemp(suffix='.exe') try: os.write( fd, zlib.decompress( b64decode(GET_PROC_ADDRESS_32_EXE, validate=True))) finally: os.close(fd) try: GetProcAddress32 = LPVOID( c_uint(subprocess.call([path])).value) finally: os.remove(path) address = GetProcAddress32 else: address = GetProcAddress(GetModuleHandleW('kernel32'), b'GetProcAddress') _LPVOID = c_uint64 if self.process.bits == 64 else c_uint32 _HMODULE = _LPVOID class GetProcAddressParam(Structure): _fields_ = [('procAddress', _LPVOID), ('fnGetProcAddress', _LPVOID), ('hModule', _HMODULE), ('procName', CHAR * (len(name) + 1))] param = GetProcAddressParam() param.fnGetProcAddress = address.value param.hModule = self.handle.value param.procName = name.encode('ascii') if self.process.bits == 64: code = GET_PROC_ADDRESS_64 else: code = GET_PROC_ADDRESS_32 with self.process.alloc_memory(sizeof(param)) as memory: memory.write(byref(param)) ok = self.process.execute_shellcode(code, memory.address) memory.read(byref(param)) if not ok: raise WindowsError() return Process.Module.Proc(self, LPVOID(param.procAddress))
def virtualQueryEx(hProcess, lpAddress): vQuery = windll.kernel32.VirtualQueryEx lpBuffer = MEMORY_BASIC_INFORMATION() dwLength = c.sizeof(MEMORY_BASIC_INFORMATION) success = vQuery(hProcess, LPVOID(lpAddress), c.byref(lpBuffer), dwLength) if success == 0: raise c.WinError() return MemoryBasicInformation(lpBuffer)
def _query_value(self, key): buf = self._buffer ptr = LPVOID() size = ctypes.c_uint() if not VerQueryValue(buf, key, ctypes.byref(ptr), ctypes.byref(size)): err = ctypes.WinError() if err.winerror == 1813: raise ResourceError(key) raise err return ptr, size.value
def suspendWow64Redirection(): """Context manager which disables Wow64 redirection for a section of code and re-enables it afterwards""" oldValue = LPVOID() res = kernel32.Wow64DisableWow64FsRedirection(byref(oldValue)) if res == 0: # Disabling redirection failed. # This can occur if we're running on 32-bit Windows (no Wow64 redirection) # or as a 64-bit process on 64-bit Windows (Wow64 redirection not applicable) # In this case failure is expected and there is no reason to raise an exception. # Inspect last error code to determine reason for the failure. errorCode = kernel32.GetLastError() if errorCode == ERROR_INVALID_FUNCTION: # Redirection not supported or not applicable. redirectionDisabled = False else: raise WinError(errorCode) else: redirectionDisabled = True try: yield finally: if redirectionDisabled: if kernel32.Wow64RevertWow64FsRedirection(oldValue) == 0: raise WinError()
def GetProcAddress(hModule, lpProcName): return LPVOID(_GetProcAddress(hModule, lpProcName))
def VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect): return LPVOID( _VirtualAllocEx(hProcess, lpAddress, SIZE_T(dwSize), flAllocationType, flProtect))
def from_param(cls, param): if isinstance(param, six.string_types): return LPVOID.from_param(six.text_type(param)) return LPARAM.from_param(param)
def BCryptDecrypt(secret, nonce, cipher): # Step one OpenAlgorithm: The BCryptOpenAlgorithmProvider function loads and initializes a CNG provider bcrypt.BCryptOpenAlgorithmProvider.restype = DWORD # restype == return type bcrypt.BCryptOpenAlgorithmProvider.argtypes = [ POINTER(LPVOID), LPWSTR, LPWSTR, ULONG ] algHandle = LPVOID() status = bcrypt.BCryptOpenAlgorithmProvider(byref(algHandle), "AES", None, 0) # print(f"\nBCryptOpenAlgorithmProvider: {hex(status)}") # print(f"handle is {algHandle}\n") bcrypt.BCryptSetProperty.restype = DWORD bcrypt.BCryptSetProperty.argtypes = [ LPVOID, # hCryptHandle LPCWSTR, # pszProperty LPVOID, # pbInput ULONG, # cbInput ULONG # dwFlags ] # Set mode to GCM status = bcrypt.BCryptSetProperty( algHandle, BCRYPT_CHAINING_MODE, BCRYPT_CHAIN_MODE_GCM, (len(BCRYPT_CHAIN_MODE_GCM) + 1) * 2, # This is sizeof(BCRYPT_CHAIN_MODE_GCM) 0) # print(f"BCryptSetProperty: {hex(status)}") bcrypt.BCryptGetProperty.restype = DWORD bcrypt.BCryptGetProperty.argtypes = [ LPVOID, # hObject, LPCWSTR, # pszProperty, LPVOID, # pbOutput, ULONG, # cbOutput, POINTER(ULONG), # pcbResult, ULONG, # dwFlags ] # to store pcbResult bytesDone = ULONG() # needs to be length of the cipherText authTagLengths = BCRYPT_AUTH_TAG_LENGTHS_STRUCT() status = bcrypt.BCryptGetProperty(algHandle, BCRYPT_AUTH_TAG_LENGTH, ctypes.byref(authTagLengths), ctypes.sizeof(authTagLengths), ctypes.byref(bytesDone), 0) # print(f"BCryptGetProperty authTagLengths: {hex(status)}") bcrypt.BCryptGenerateSymmetricKey.argtypes = [ LPVOID, # BCRYPT_ALG_HANDLE hAlgorithm, POINTER(LPVOID), # BCRYPT_KEY_HANDLE * phKey, PCHAR, # PUCHAR pbKeyObject, ULONG, # ULONG cbKeyObject, PCHAR, # PUCHAR pbSecret, ULONG, # ULONG cbSecret, ULONG, # ULONG dwFlags ] bcrypt.BCryptGenerateSymmetricKey.restype = DWORD pKeyHandle = LPVOID() status = bcrypt.BCryptGenerateSymmetricKey(algHandle, ctypes.byref(pKeyHandle), None, 0, secret, len(secret), 0) # print(f"BCryptGenerateSymmetricKey: {hex(status)}") # print(f"key handle: {pKeyHandle}\n") authTagType = CHAR * authTagLengths.dwMinLength authTag = authTagType() origNonceType = (CHAR * len(nonce)) origNonce = origNonceType(*tuple(nonce)) # print(f"origNonceTypeLen: {origNonceType}\norigNonceText: {origNonce.raw}\norigNonce location: {origNonce}\n") cipherType = (CHAR * len(cipher)) cipher = cipherType(*tuple(cipher)) # print(f"cipherTypeLen: {cipherType}\ncipherText: {cipher.raw}\ncipher location:{cipher}\n") # print(f"bytesDone: {bytesDone}") # Decryption bcrypt.BCryptDecrypt.restype = DWORD bcrypt.BCryptDecrypt.argtypes = [ LPVOID, # BCRYPT_KEY_HANDLE hKey, PCHAR, # PUCHAR pbInput, ULONG, # cbInput, LPVOID, # pPaddingInfo, LPVOID, # PUCHAR pbIV, ULONG, # cbIV, LPVOID, # PUCHAR pbOutput, ULONG, # cbOutput, POINTER(ULONG), # pcbResult, ULONG # dwFlags ] # Struct info authInfo = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO() authInfo.cbSize = ctypes.sizeof(authInfo) authInfo.dwInfoVersion = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION authInfo.pbNonce = ctypes.cast(origNonce, LPVOID) authInfo.cbNonce = ctypes.sizeof(origNonce) # print(f"authInfo.cbNonce: {authInfo.cbNonce}") authInfo.pbTag = ctypes.cast(authTag, LPVOID) authInfo.cbTag = ctypes.sizeof(authTag) # Holds the length of the decrypted password, which is the same size of as the cipher text decrypted = (CHAR * len(cipher))() status = bcrypt.BCryptDecrypt(pKeyHandle, cipher, len(cipher), ctypes.byref(authInfo), ctypes.byref(origNonce), ctypes.sizeof(origNonce), decrypted, ctypes.sizeof(decrypted), ctypes.byref(bytesDone), 0) # print("BCryptDecrypt: %s" % hex(status)) # print("bytesDone ", bytesDone) # print("decrypted: ", decrypted.raw[:bytesDone.value]) # Close algorithm, and destroy the key bcrypt.BCryptCloseAlgorithmProvider.argtypes = [ LPVOID, # hAlgorithm ULONG # dwFlags ] bcrypt.BCryptCloseAlgorithmProvider(algHandle, 0) bcrypt.BCryptDecrypt.argtypes = [ LPVOID # hKey ] bcrypt.BCryptDestroyKey(pKeyHandle) return decrypted.raw[:bytesDone.value]
with open(PAYLOAD_EXE, "rb") as h_payload: payload_data = h_payload.read() if pe_payload.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE: logger.debug(f"{PAYLOAD_EXE} is 32-bit") else: logger.debug(f"{PAYLOAD_EXE} is 64-bit") logger.info("Getting thread context") context = CONTEXT64() if USING_64_BIT else WOW64_CONTEXT() context.ContextFlags = CONTEXT_FULL if USING_64_BIT else WOW64_CONTEXT_FULL if windll.kernel32.GetThreadContext(process_info.hThread, byref(context)) == 0: logger.error(f"Error in GetThreadContext: {FormatError(GetLastError())}") sys.exit(1) logger.info("Reading base address of process image") target_image_base = LPVOID() if windll.kernel32.ReadProcessMemory( process_info.hProcess, LPVOID((context.Rdx if USING_64_BIT else context.Ebx) + 2 * sizeof(c_size_t)), byref(target_image_base), sizeof(LPVOID), None) == 0: logger.error(f"Error in ReadProcessMemory: {FormatError(GetLastError())}") sys.exit(1) logger.debug(f"Base address of process: {hex(target_image_base.value)}") if target_image_base == pe_payload.OPTIONAL_HEADER.ImageBase: logger.info("Unmapping target executable from the process ") if windll.ntdll.NtUnmapViewOfSection(process_info.hProcess, target_image_base) == 0: logger.error( f"Error in NtUnmapViewOfSection: {FormatError(GetLastError())}")