Hack the Box Dirty Money 2022 - Mr. Abilgate

Another challenge from Hack The Box. This time, we are given an PE file, KeyStorage.exe and an encrypted file, ImportantAssets.xls.bhtbr. Assuming the binary will traverse the filesystem en encrypt some files, we can guess what function calls could be made.

TLDR: Patch the BCryptEncrypt function pointer to BCryptDecrypt using Frida.

Quick look

The PE file is packed with UPX, uses API hashing and got at least one anti-debugging techniques.

$ strings KeyStorage.exe

!This program cannot be run in DOS mode.
RichXC
UPX0
UPX1
.rsrc
3.96
UPX!

Upx can be used to unpack the binary, but it doesn’t help that much. The main looks like this.

Main

The API hashing and the antidebug:

API hashing and antidebug

I didn’t want to dig more and spend more time reversing the binary and I though running it with API Monitor could help. This led to an interesting NtOpenFile call.

NtOpenFile

I just created all the folders and put a file in it. The binary continued its execution and cryptographic functions were eventually called.

BCryptEncrypt

From there, we could either dump the memory, extract the encryption key, IV, algorithm used and code a function that would decrypt the xlsx… or we could just patch the function pointer to BCryptDecrypt. This is easy to do because both functions share the same parameters in the same order!

NTSTATUS BCryptEncrypt(
  [in, out]           BCRYPT_KEY_HANDLE hKey,
  [in]                PUCHAR            pbInput,
  [in]                ULONG             cbInput,
  [in, optional]      VOID              *pPaddingInfo,
  [in, out, optional] PUCHAR            pbIV,
  [in]                ULONG             cbIV,
  [out, optional]     PUCHAR            pbOutput,
  [in]                ULONG             cbOutput,
  [out]               ULONG             *pcbResult,
  [in]                ULONG             dwFlags
);
NTSTATUS BCryptDecrypt(
  [in, out]           BCRYPT_KEY_HANDLE hKey,
  [in]                PUCHAR            pbInput,
  [in]                ULONG             cbInput,
  [in, optional]      VOID              *pPaddingInfo,
  [in, out, optional] PUCHAR            pbIV,
  [in]                ULONG             cbIV,
  [out, optional]     PUCHAR            pbOutput,
  [in]                ULONG             cbOutput,
  [out]               ULONG             *pcbResult,
  [in]                ULONG             dwFlags
);

Instrumentation

It is also quite trivial to do using Frida, as it offers a way to simply replace pointers and run it like this frida -f KeyStorage.exe -l script.js

const BCryptEncryptPtr = Module.getExportByName("Bcrypt.dll", "BCryptEncrypt");
const BCryptDecryptPtr = Module.getExportByName("Bcrypt.dll", "BCryptDecrypt");

Interceptor.replace(BCryptEncryptPtr, BCryptDecryptPtr);

This should give us a decrypted xls file, an thus the flag. For some reason, I wasn’t able to open it in Excel, but it did work when changing the extension to xlsx.

Flag