The main function of the downloader module is to fetch the other components and execute the core module.
The downloader module starts by checking if it is located in the working directory /usr/lib64/seahorses/ under the name kbioset.
The framework makes heavy use of typosquatting and masquerading in order to remain undetected. The reference to seahorses masquerades the password and key manager software seahorse. If not it will relocate itself to that working directory and execute that copy. The downloader will fingerprint the host name and network adapters to generate a GUID, which will be sent to the command and control (C2) server.
The downloader will then contact the C2 to fetch the following modules and plugins:
Linux.Plugin.Lightning.SsHijacker
Linux.Plugin.Lightning.Sshd
Linux.Plugin.Lightning.Nethogs
Linux.Plugin.Lightning.iftop
Linux.Plugin.Lightning.iptraf
Lightning.Core
The method of contacting the C2 will be described below in the malleable C2 section (click here to jump to that section). The downloader will then execute the core module (kkdmflush).
The core module is the main module in this framework, it is able to receive commands from the C2 and execute the plugin modules. The module has many capabilities and uses a number of techniques to hide artifacts to remain running under the radar.
The core module modifies the name of the calling thread of the module to kdmflush, to make it appear that it is a kernel thread.
Next the core module sets up persistence by creating a script that is executed upon system boot. This is achieved by first creating a file located at /etc/rc.d/init.d/elastisearch. The name appears to typosquat elasticsearch. The following contents are written to the file:
#!/bin/bash
# chkconfig:2345 90 20
/usr/lib64/seahorses/kbioset &
This script will execute the downloader module upon boot. The service is then added using the chkconfig utility.
The timestamp of the file is modified to hide artifacts, a technique known as “timestomping”. The file has its last modified time edited to match that of either whoami, find, or su. It will look for each file respectively until it finds one.
This technique is used for most of the files that the framework creates.
The malware will attempt to hide its Process ID (PID) and any related network ports. This is achieved by writing the frameworks running PIDs to two files: hpi and hpo. These files are parsed and then the existence of the file proc/y.y is checked.
If the file exists, it means that a rootkit has been installed. The PIDs are written to proc/y.y for use by the rootkit, which may scrub any reference to files running in the framework from commands such as ps and netstat.
The core module will generate a GUID in the same manner as the downloader and contact the C2. The response is parsed and the command is executed.
Network communication in the Core and Downloader modules are performed over TCP sockets. The data is structured in JSON.
The C2 is stored in a polymorphic encoded configuration file that is unique for every single creation. This means that configuration files will not be able to be detected through techniques such as hashes. The key is built into the start of the encoded file.
The decoded configuration is structured in JSON.
The default configuration in the analyzed sample uses a local IP address 10.2.22[.]67 with the port 33229.
There is a passive mode of communication available if the actor executes the RunShellPure command. This starts an SSH service on the infected machine with the Linux.Plugin.Lightning.Sshd plugin. T
he plugin is an OpenSSH daemon that has hardcoded private and host keys, allowing the attacker to SSH into the machine with their own SSH key, creating a secondary backdoor.