The chronicles of Bumblebee: The Hook, the Bee, and the Trickbot connection

  1. PART 1: The hook- unpacking the bumblebee’s crypter
    - Unpacking mechanism
    - Enters the hook
    - Executing the code
    - Bumblebee dropper high-level summary
  2. PART 2: The bee- Investing the bumblebee’s payload
    - Stolen anti-analysis code
    - Searching for processes
    - Searching registry keys
    - Searching file paths
    - Executing processes
    - The little ones inside the flask: hiding additional DLLs
  3. PART 3: The Trickbot connection- Investigating the hooking DLL
    - Check for existing hooks
    - Setting the hooks
    - First hooks: Disable exceptions
    - Second hooks: Further code execution
    - The Trickbot hooking engine
    - Static differences and code evolution
    - Additional similarities
    - Customize flattened RC4
    - RapportGP.dll high-level summary

PART 1

The Hook: Unpacking the bumblebee’s crypter

Bumblebee dropper as seen in PEstudio
Bumblebee dropper exports and internal name in PE-Bear

Unpacking mechanism

Bumblebee loader\crypter main
Bumblebee loader unexplored bytes
  1. Click Optional Header
  2. Go to DllCharacteristics
  3. Remove the V from “DLL can move”
Disabling ASLR
  1. In IDA \ PE-Bear, copy the address of the required export function
  2. In Xdbg, right click on RIP
  3. Click on “Modify Value”
  4. Paste the address of the export function
Changing the address
Bumblebee SetPath
  1. sub_1800021D0 - which will allocate virtual memory using HeapAlloc (this function will happen multiple times during the crypter unpacking)
  2. sub_1800029BC - Which gets an embedded content and writes it into the newly allocated memory
Bumblebee loader\crypter main
  1. Allocate new virtual memory using the same sub_1800021D0 function.
  2. Manipulate the content from the first allocated buffer and write the output into the newly allocated memory
Bumblebee loader\crypter main
  1. It executes a function named sub_180001670 that will allocate multiple virtual memories using the already mentioned sub_1800021D0.
  2. Call the function named sub_180003CE that will use the virtual memory that was allocated in sub_180002FF4, do additional manipulations, and eventually writes an unpacked MZ into the last allocated buffer from the function sub_180001670.
Bumblebee loader\crypter main
Bumblebee loader payload decryption
Bumblebee loader payload decryption
Bumblebee loader payload decrypted in process hacker
  1. The code section of the payload does not have Execute permission, so it cant run.
  2. What makes this loader special?

Enters the hook

Bumblebee loader payload decryption
Assign functions to addresses
  1. Get Ntdll handle with LoadLibrary
  2. Get the address of NtOpenFile
  3. Get the address of NtCreateSection
  4. Get the address of NtMapViewOfSection
  5. Return the data
Getting NT functions
Getting NT functions
  1. Call VirtualProtect to change the protection of the area it wants to write into to be writeable
  2. Call sub_180002978 that will take as arguments:
    1. The function to write into
    2. The content it wants to write
    3. The size
  3. Call VirtualProtect to change the protection again to not be writeable
Setting hook
  1. sub_180001D4 for NtMapViewOfSection
  2. sub_1800023D4 for NtOpenFile
  3. sub_1800041EC for NtCreateSection
Hooked NT functions
View hooks using hollow hunter
View hooks using hollow hunter
Bumblebee loader install hook mechanism

Executing the code

Bumblebee loader\crypter main
LoadLibrary loading GdiPlus.dll
LoadLibrary loading GdiPlus.dll
  1. When LoadLibrary loads a DLL file, it uses internally the hooked NT function as part of its internal activity.
  2. The malware chooses a DLL that is not loaded yet.
  3. NtOpenFile will get a file handle of GdiPlus.dll
  4. NtCreateSection will create a section for the file handle of GdiPlus.dll
  1. It will use CreateSection to create a new section with READ-WRITE-EXECUTE permissions, without any file handle to associate it with.
  2. It will write the unpacked malicious content into this section
  3. It returns NTSTATUS_SUCCESS to the LoadLibrary so it will seem to it as if GdiPlus.dll was mapped successfully.
Hooked NtMapViewOfSection mechanism
Relocated module point to RWX section

Bumblebee dropper high lever summary

Bumblebee dropper overview

PART 2

The bee: Investigating the bumblebee’s payload

Unpacked Bumblebee payload

Stolen anti-analysis code

Searching for processes in Bumblebee
al-khaser source code
Searching for Vmware processes in Bumblebee
Searching for Vmware registry key in Bumblebee
Searching for VBOX files in Bumblebee

Executing processes

Executing Wscript
Executing PowerShell

The little ones inside the flask

Two hidden DLL files inside the unpacked Bumblebee
Bumblebee hooking DLL aka RapportGP.dll

PART 3: The shadow of Trickbot- Investigating the hooking DLL

Check for existing hooks

  1. A handle to Ntdll.dll, Kernel32.dll, Kernelbase.dll, Advapi32.dll obtained
  2. The requested DLL’s path obtained
  3. A call to the function sub_100059B0 was made to get a copy of NtProtectVirtualMemory that stored in the allocated memory
  4. The arguments are sent to another function named sub_10005B90
1. RapportGP.dll checking and disabling existing hooks
RapportGP.dll list of Ntdll functions to check
RapportGP.dll list of Kernel32 functions to check
RapportGP.dll list of Kernelbase functions to check
RapportGP.dll list of Advapi32 functions to check
2. RapportGP.dll checking and disabling existing hooks
  1. The malware iterate through the export functions of the legitimate DLL file that was mapped to memory by the process when it loads.
  2. The malware will check if the name is one of the function names it wants to check
  3. Once found, the malware calls sub_10001040 that checks for hooks evidence in the DLL that was mapped by the process loader
  4. The malware will do the same for the DLL that was mapped by the malware itself (in sub_10005B90).
  5. If no hooks are found, it will continue to iterate
3. RapportGP.dll checking and disabling existing hooks
  1. Get information about the original function
  2. It will change the protection
  3. Check if it's writable
  4. Write the content of the mapped function to the original function. In this way, it restores it to the state it should be if there are no hooks.
4. RapportGP.dll checking and disabling existing hooks
  1. Original function at 775222C0
  2. The function that mapped by the malware at 02E022C0
5. RapportGP.dll checking and disabling existing hooks
6. RapportGP.dll checking and disabling existing hooks
7. RapportGP.dll checking and disabling existing hooks
8. RapportGP.dll checking and disabling existing hooks
9. RapportGP.dll checking and disabling existing hooks
10. RapportGP.dll checking and disabling existing hooks

Setting the hooks

First hooks: Disable Exceptions

RapportGP.dll hooks to disable exceptions

Second hooks: Further code execution

RapportGP.dll second hooks
RapportGP.dll second hooks

The Trickbot hooking engine

Bumblebee’s RapportGP.dll vs Trickbot’s web-inject module
  1. Trickbot writes 35 bytes of NOPS (0x90)
  2. Add the traditional function prologue
  3. Write the jump to the targeted function at the end of the NOPS
Trickbot’s web-inject module evasion technique
Bumblebee’s RapportGP.dll evasion technique
Bumblebee’s RapportGP.dll evasion technique

Static differences and code evolution

Bumblebee’s RapportGP.dll vs Trickbot’s web-inject module install hook functions
  1. In Trickbot its sub_10001650
  2. In Bumblebee its sub_10002870
Bumblebee’s RapportGP.dll vs Trickbot’s web-inject module- same functionality, different flow
Bumblebee’s RapportGP.dll vs Trickbot’s web-inject module- same functionality, different flow
Bumblebee’s RapportGP.dll vs Trickbot’s web-inject module-Bindiff

Additional similarities

Bumblebee’s RapportGP.dll vs Trickbot’s web-inject module- same functionality, a different approach
Bumblebee’s RapportGP.dll vs Trickbot’s web-inject module

Customize flattened RC4

Custom RC4 with CFF obfuscation

RapportGP.dll High-level summary

RapportGP.dll overall activity

Conclusion

References

IOC

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store

Eli Salem

Malware Researcher & Threat Hunter