Example #1
0
        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))
Example #2
0
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)
Example #3
0
 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
Example #4
0
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()
Example #5
0
def GetProcAddress(hModule, lpProcName):
    return LPVOID(_GetProcAddress(hModule, lpProcName))
Example #6
0
def VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect):
    return LPVOID(
        _VirtualAllocEx(hProcess, lpAddress, SIZE_T(dwSize), flAllocationType,
                        flProtect))
Example #7
0
 def from_param(cls, param):
     if isinstance(param, six.string_types):
         return LPVOID.from_param(six.text_type(param))
     return LPARAM.from_param(param)
Example #8
0
 def from_param(cls, param):
     if isinstance(param, six.string_types):
         return LPVOID.from_param(six.text_type(param))
     return LPARAM.from_param(param)
Example #9
0
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())}")