The infection chain utilized by the threat actors for delivering the Havoc Demon on the target machines commences with a ZIP Archive named “ZeroTwo.zip” consisting of two files “character.scr” and “Untitled Document.docx”
Further the screen saver file “character.scr” is basically a downloader commissioned to download and execute the Havoc Demon Agent on the victim machine.
The Downloader binary is compiled using a BAT to EXE converter “BAT2EXE” which allows users to convert Batch scripts into executables as shown in the screenshot below.
Once executed the BAT2EXE compiled binary loads and decrypts the Batch Script from the .rsrc section.
The binary then writes and executes the decrypted BAT script from the Temp folder.
The Decrypted BAT Script upon execution performs the following tasks:
Checks whether “teste.exe” exists in the Temp folder, if not, it downloads the final payload from http[:]//146[.]190[.]48[.]229/pics.exe and saves it as “seethe.exe” in the Temp folder via Invoke-WebRequest and then executes it using “start seethe.exe”
Then it checks whether “testv.exe” exists in the Temp folder, if not, it downloads an image from “https[:]//i[.]pinimg[.]com/originals/d4/20/66/d42066e9f8c4b75a0723b8778c370f1d.jpg” and saves it as images.jpg in the Temp folder and opens it using images.jpg.
Havoc Demon is the implant generated via the Havoc Framework – which is a modern and malleable post-exploitation command and control framework created by @C5pider.
The Downloaded payload “pics.exe” is the “Shellcode Loader” which is signed using Microsoft’s Digital certificate.
Upon execution the Shellcode Loader at first disables the Event Tracing for Windows (ETW) by patching the WinApi “EtwEventWrite()” which is responsible for writing an event.
ETW Patching process:
Retrieves module handle of ntdll.dll via GetModuleHandleA
Retrieves address of EtwEventWrite via GetProcAddress
Further it changes the protection of the region via VirtualProtect and then overwrites the first 4 bytes of the EtwEventWrite with following bytes: 0x48,0x33,0xc0,0xc3 (xor rax,rax | ret)
By patching the EtwEventWrite function the ETW will not be able to write any events thus disabling the ETW.
Then the payload AES decrypts the shellcode using CryptDecrypt() as shown in the screenshot below – in this case the Algorithm ID used is “0x00006610” – AES256
Once the Shellcode is decrypted, the Shellcode is executed via CreateThreadpoolWait() where at first it creates an event object in a signaled state via CreateEventA(), then allocates RWX memory via VirtualAlloc() and writes the Shellcode in the allocated memory.
Further it creates a wait object using CreateThreadpoolWait, here the first argument – callback function is set to the address of the shellcode.
Then it set’s the wait object via the NtApi “TpSetWait” and at last calls the WaitForSingleObject which once executed checks if the waitable object is in signaled state, as event was created in signaled state the callback function is been executed i.e the decrypted shellcode is been executed and the control flow is been transferred to the shellcode.
KaynLdr – Shellcode
The Shellcode in this case is the “KaynLdr” which is commissioned to reflectively load the Havoc’s Demon DLL implant by calling its entrypoint function.
Once the Shellcode is executed it retrieves the image base of the Demon DLL which is embedded in the shellcode itself by executing the following inline assembly function called KaynCaller.
Further the KaynLdr performs the API Hashing routine in order to resolve the virtual addresses of various NTAPI’s by walking the export address table of the ntdll.dll (Function: LdrFunctionAddr) and initially the virtual address of the NTDLL.dll is been retrieved by walking the Process Environment Block (Function: LdrFunctionAddr).
Virtual Addresses for the following module and NTAPI’s are retrieved by using the API Hashing routine where the hardcoded DJB2 hashes are compared with the dynamically generated hash.
Further the Embedded Demon DLL is memory mapped and the base relocations are calculated if required in an allocated memory page procured by calling the NtAllocateVirtualMemory().
Also the page protections are changed via multiple calls to NtProtectVirtualMemory.
The Demon DLL is memory mapped in the Allocated memory without the DOS and NT Headers in order to evade detection mechanisms.
Now once the Demon DLL is memory mapped the KaynDllMain i.e the entrypoint of the DLL is executed by the KaynLdr as shown below, from there on the control is transferred to the Havoc Demon DLL Implant.
The entrypoint of the Havoc Demon DLL is executed by the KaynLdr as discussed previously.
Now as the Havoc Demon has many features, Analysts only focus on a few of them in the following blog, as the features can be deduced from its source at: https://github.com/HavocFramework/Havoc
So once the Havoc Demon is been executed there are four functions which are been executed by the DemonMain():
DemonInit
DemonMetaData
DemonConfig
DemonRoutine
The DemonInit is the initialization function which
Retrieves the virtual addresses of functions from modules such as ntdll.dll/kernel32.dll by calling the API Hashing Routine discussed previously.
Retrevies Syscall stubs for various NTAPI’s
Loads various Modules via walking the PEB with stacked strings
Initialize Session and Config Objects such as Demon AgentID, ProcessArch etc.
Now let’s understand how the Configuration is being parsed via the DemonConfig() function.
The DemonConfig function parses the configuration by indexing the various required values from the config.
Following is the configuration for the Demon DLL used in the campaign.
Configuration:
Sleep: 2 (0x2)
Injection:
Allocate: Native/Syscall (0x2)
Execute: Native/Syscall (0x2)
Spawn:
x64: C:WindowsSystem32notepad.exe
x86: C:WindowsSysWOW64notepad.exe
Sleep Obfuscation Technique: Ekko (0x2)
Method: POST
Host: 146[.]190[.]48[.]229
Transport Secure: TRUE
UserAgent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537/36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
The DemonRoutine() function is the main loop for the malware, it is responsible for connecting to the command and control (C2) server, waiting for tasks from the server, executing those tasks, and then waiting again for more tasks and running indefinitely.
It does the following things:
First, it checks if it is connected to the C2 server.
If not, it calls TransportInit() to connect to the server.
If the connection is successful, it enters the CommandDispatcher() function, which is responsible for a task routine which parses the tasks and executes them until there are no more tasks in the queue.
If the malware is unable to connect to the C2 server, it will keep trying to connect to the server again
TransportInit() is responsible for connecting to the C2 server and establishing a session.
It first sends the AES encrypted MetaData packet i.e the Check-in request generated via the DemonMetaData() function through the PackageTransmit() function, which could be sending data over HTTP or SMB, depending on the value of the TRANSPORT_HTTP or TRANSPORT_SMB macro.
If the transmission is successful, it then decrypts the received data using AES encryption with a given key and initialization vector on the TeamServer.
The decrypted data is then checked against the agent’s ID, and if they match, the session is marked as connected and the function returns true.
TransportSend() is used to send data to the C2 server.
It takes a pointer to the data and its size as input, and optionally returns received data and its size.It then creates a buffer with the data to be sent, and depending on the transport method, it either sends the data over HTTP or SMB.
On the Teamserver end the CheckIn request with the metadata packet is been decrypted and showcased on the terminal with both encrypted and decrypted details of packets sent and received.
After the demon is deployed successfully on the target’s machine, the server is able to execute various commands on the target system.
If the command “whoami” is issued to the payload, it would trigger the execution of the command and display the current user running the session.The server logs the command and its response upon execution.
Once the command is executed on the victim machine, the command output is AES Encrypted and then sent to the CnC server.