서문
BLOODALCHEMY is an x86 backdoor written in C and found as shellcode injected into a signed benign process. It was discovered in our analysis and is part of the REF5961 intrusion set, which you can read about here.
BLOODALCHEMY requires a specific loader to be run because it isn't reflexive (it doesn’t have the capability to load and execute by itself). Additionally, BLOODALCHEMY isn’t compiled as position independent (when loaded at a different base address than the preferred one the binary has to be patched to take into account the new “position”).
In our analysis, the signed benign process was previously sideloaded with a malicious DLL. The DLL was missing from the sample data but was likely the container and the loader of the BLOODALCHEMY shellcode.
We believe from our research that the malware is part of a bigger toolset and is still in active development based on its current lack of capabilities, enabled debug logging of exceptions, and the existence of test strings used for persistence service setup.
핵심 사항
- BLOODALCHEMY is likely a new backdoor and is still in active development
- BLOODALCHEMY abuses a legitimate binary for loading
- BLOODALCHEMY has multiple running modes, persistence mechanisms, and communication options
Initial execution
During the initial execution phase, the adversary deployed a benign utility, BrDifxapi.exe
, which is vulnerable to DLL side-loading. When deploying this vulnerable utility the adversary could side-load the unsigned BLOODALCHEMY loader (BrLogAPI.dll
) and inject shellcode into the current process.
BrDifxapi.exe
is a binary developed by the Japanese company Brother Industries and the version we observed has a revoked signature.
The legitimate DLL named BrLogApi.dll
is an unsigned DLL also by Brother Industries. BLOODALCHEMY uses the same DLL name.
코드 분석
Data Obfuscation
To hide its strings the BLOODALCHEMY malware uses a classic technique where each string is encrypted, preceded by a single-byte decryption key, and finally, all concatenated together to form what we call an encrypted blob.
While the strings are not null-terminated, the offset from the beginning of the blob, the string, and the size are passed as a parameter to the decryption function. Here is the encrypted blob format:
Blob = Key0 :EncryptedString0 + Key1:EncryptedString1 + ... + KeyN:EncryptedStringN
The implementation in Python of the string decryption algorithm is given below:
def decrypt_bytes(encrypted_data: bytes, offset: int, size: int) -> bytes:
decrypted_size = size - 1
decrypted_data = bytearray(decrypted_size)
encrypted_data_ = encrypted_data[offset : offset + size]
key = encrypted_data_[0]
i = 0
while i != decrypted_size:
decrypted_data[i] = key ^ encrypted_data_[i + 1]
key = (key + ((key << ((i % 5) + 1)) | (key >> (7 - (i % 5))))) & 0xFF
i += 1
return bytes(decrypted_data)
The strings contained in the configuration blob are encrypted using the same scheme, however the ids (or offsets) of each string are obfuscated; it adds two additional layers of obfuscation that must be resolved. Below, we can resolve additional obfuscation layers to decrypt strings from the configuration:
def decrypt_configuration_string(id: int) -> bytes:
return decrypt_bytes(
*get_configuration_encrypted_string(
get_configuration_dword(id)))
Each function is given below:
The get_configuration_dword
function
def get_configuration_dword(id: int) -> int:
b = ida_bytes.get_bytes(CONFIGURATION_VA + id, 4)
return b[0] + (b[1] + (b[2] + (b[3] << 8) << 8) << 8)
The get_configuration_encrypted_strng
function
def get_configuration_encrypted_string(id: int) -> tuple[int, int]:
ea = CONFIGURATION_VA + id
v2 = 0
i = 0
while i <= 63:
c = ida_bytes.get_byte(ea)
v6 = (c & 127) << i
v2 = (v2 | v6) & 0xFFFFFFFF
ea += 1
if c >= 0:
break
i += 7
return ea, v2
지속성 유지
BLOODALCHEMY maintains persistence by copying itself into its persistence folder with the path suffix \Test\test.exe
,
The root directory of the persistence folder is chosen based on its current privilege level, it can be either:
%ProgramFiles%
%ProgramFiles(x86)%
%Appdata%
%LocalAppData%\Programs
Persistence is achieved via different methods depending on the configuration:
- As a service
- As a registry key
- As a scheduled task
- Using COM interfaces
To identify the persistence mechanisms, we can use the uninstall command to observe the different ways that the malware removes persistence.
As a service named Test
.
As a registry key at CurrentVersion\Run
As a scheduled task, running with SYSTEM privilege via schtask.exe
:
b'schtasks.exe /CREATE /SC %s /TN "%s" /TR "\'%s\'" /RU "NT AUTHORITY\\SYSTEM" /Fb'
Using the TaskScheduler::ITaskService
COM interface. The intent of this persistence mechanism is currently unknown.
Running modes
The malware has different running modes depending on its configuration:
- Within the main or separate process thread
- Create a Windows process and inject a shellcode into it
- As a service
The malware can either work within the main process thread.
Or run in a separate thread.
Or create a Windows process from a hardcoded list and inject a shellcode passed by parameter to the entry point using the WriteProcessMemory+QueueUserAPC+ResumeThread method.
The shellcode is contained in the parameters we call p_interesting_data
. This parameter is actually a pointer to a structure containing both the malware configuration and executable binary data.
Or install and run itself as a service. In this scenario, the service name and description will be Test
and Digital Imaging System
:
Also when running as a service and started by the service manager the malware will masquerade itself as stopped by first setting the service status to “SERVICE_RUNNING” then setting the status to “SERVICE_STOPPED” while in fact the malware is still running.
커뮤니케이션
The malware communicates using either the HTTP protocol, named pipes, or sockets.
When using the HTTP protocol the malware requests the following URI /Inform/logger/.
In this scenario, BLOODALCHEMY will try to use any proxy server found in the registry key SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings
.
We did not uncover any C2 infrastructure with our sample, but the URL could look something like this: https://malwa[.]re/Inform/logger
When using a named pipe, the name is randomly generated using the current PID as seed.
While waiting for a client to connect to this named pipe the malware scans the running processes and checks that its parent process is still running, this may be to limit access to the named pipe. That said, the malware is not checking that the pipe client is the correct parent process, only that the parent process is running. This introduces flawed logic in protecting the named pipe.
From the malware strings and imports we know that the malware can also operate using TCP/UDP sockets.
While we haven’t made any conclusions about their usage, we list all the protocols found in the encrypted strings.
- DNS://
- HTTP://
- HTTPS://
- MUX://
- UDP://
- SMB://
- SOCKS5://
- SOCKS4://
- TCP://
For all protocols the data can be encrypted, LZNT1 compressed, and/or Base64-encoded.
명령
The malware only contains a few commands with actual effects:
- Write/overwrite the malware toolset
- Launch its malware binary
Test.exe
- Uninstall and terminate
- 호스트 정보 수집
There are three commands that write (or overwrite) the malware tool set with the received Base64-encoded binary data:
- Either the malware binary (
Test.exe
) - the sideloaded DLL (
BrLogAPI.dll
) - or the main trusted binary (
BrDifxapi.exe
)
One command that launches the Test.exe
binary in the persistence folder.
The uninstall and terminate itself command will first delete all its files at specific locations then remove any persistence registry key or scheduled task, then remove installed service and finish by terminating itself.
One host information gathering command: CPU, OS, display, network, etc.
요약
BLOODALCHEMY is a backdoor shellcode containing only original code(no statically linked libraries). This code appears to be crafted by experienced malware developers.
The backdoor contains modular capabilities based on its configuration. These capabilities include multiple persistence, C2, and execution mechanisms.
While unconfirmed, the presence of so few effective commands indicates that the malware may be a subfeature of a larger intrusion set or malware package, still in development, or an extremely focused piece of malware for a specific tactical usage.
BLOODALCHEMY and MITRE ATT&CK
Elastic uses the MITRE ATT&CK framework to document common tactics, techniques, and procedures that advanced persistent threats used against enterprise networks.
전술
전술은 기술 또는 하위 기술의 이유를 나타냅니다. 이는 적의 전술적 목표, 즉 행동을 수행하는 이유입니다.
Malware prevention capabilities
YARA
Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the BLOODALCHEMY malware:
BLOODALCHEMY
rule Windows_Trojan_BloodAlchemy_1 {
meta:
author = "Elastic Security"
creation_date = "2023-05-09"
last_modified = "2023-06-13"
threat_name = "Windows.Trojan.BloodAlchemy"
license = "Elastic License v2"
os = "windows"
strings:
$a1 = { 55 8B EC 51 83 65 FC 00 53 56 57 BF 00 20 00 00 57 6A 40 FF 15 }
$a2 = { 55 8B EC 81 EC 80 00 00 00 53 56 57 33 FF 8D 45 80 6A 64 57 50 89 7D E4 89 7D EC 89 7D F0 89 7D }
condition:
all of them
}
rule Windows_Trojan_BloodAlchemy_2 {
meta:
author = "Elastic Security"
creation_date = "2023-05-09"
last_modified = "2023-06-13"
threat_name = "Windows.Trojan.BloodAlchemy"
license = "Elastic License v2"
os = "windows"
strings:
$a1 = { 55 8B EC 83 EC 54 53 8B 5D 08 56 57 33 FF 89 55 F4 89 4D F0 BE 00 00 00 02 89 7D F8 89 7D FC 85 DB }
$a2 = { 55 8B EC 83 EC 0C 56 57 33 C0 8D 7D F4 AB 8D 4D F4 AB AB E8 42 10 00 00 8B 7D F4 33 F6 85 FF 74 03 8B 77 08 }
condition:
any of them
}
rule Windows_Trojan_BloodAlchemy_3 {
meta:
author = "Elastic Security"
creation_date = "2023-05-10"
last_modified = "2023-06-13"
threat_name = "Windows.Trojan.BloodAlchemy"
license = "Elastic License v2"
os = "windows"
strings:
$a = { 55 8B EC 83 EC 38 53 56 57 8B 75 08 8D 7D F0 33 C0 33 DB AB 89 5D C8 89 5D D0 89 5D D4 AB 89 5D }
condition:
all of them
}
rule Windows_Trojan_BloodAlchemy_4 {
meta:
author = "Elastic Security"
creation_date = "2023-05-10"
last_modified = "2023-06-13"
threat_name = "Windows.Trojan.BloodAlchemy"
license = "Elastic License v2"
os = "windows"
strings:
$a = { 55 8B EC 83 EC 30 53 56 57 33 C0 8D 7D F0 AB 33 DB 68 02 80 00 00 6A 40 89 5D FC AB AB FF 15 28 }
condition:
all of them
}
관찰
모든 관측값은 결합된 압축 파일 번들로 ECS 및 STIX 형식으로도 다운로드할 수 있습니다.
이 연구에서는 다음과 같은 관찰 가능성에 대해 논의했습니다.
Observable | 유형 | 이름 | 참조 |
---|---|---|---|
e14ee3e2ce0010110c409f119d56f6151fdca64e20d902412db46406ed89009a | SHA-256 | BrLogAPI.dll | BLOODALCHEMY loader |
25268bc07b64d0d1df441eb6f4b40dc44a6af568be0657533088d3bfd2a05455 | SHA-256 | NA | BLOODALCHEMY payload |