Lightning Framework is a robust malware framework that consists of various modules and plugins with diverse capabilities, including the ability to download and install multiple types of rootkits. The framework targets Linux endpoints and utilizes several techniques to hide the presence of the malware. It also communicates with the threat actor using a combination of active and passive attack techniques.
In this blog post, we identify Indicators of Compromise (IoC) for the Lightning Framework, and detect the activity of the malware using Wazuh.
Lightning Framework architecture
The Lightning Framework uses a modular architecture consisting of three modules listed below:
1. The downloader module (Lightning.Downloader
): The malware downloader fetches multiple plugins and the core module from a remote server and executes the downloaded core module.
2. The core module (Lightning.Core
): This is the main module of the framework. Fundamentally, it establishes a connection with the C2 server (command and control) and is capable of receiving commands, hiding malware artifacts, and executing the plugin modules.
3. The plugin modules: The plugins supported by the framework include the Plugin.Kernel
, Plugin.RootkieHide
, Plugin.SsHijacker
, Plugin.Sshd
, Plugin.Nethogs
, Plugin.iftop
, and Plugin.iptraf
. The downloader module downloads these plugins to support the core module in the overall execution of the Lightning Framework.
Malware behavior analysis
- The Lightning Framework infection chain starts with the
Lightning.Downloader
module. The downloader first verifies if it is presently located under the namekbioset
within the/usr/lib64/seahorses/
working directory. To evade detection, the working directory of the downloader module uses typosquatting to masquerade asseahorses
. This looks similar to a legitimate GNOME password and encryption key manager calledseahorse
. When the endpoint is infected, the downloader will copy itself to the/usr/lib64/seahorses/
directory and then execute itself.
# cd /usr/lib64/seahorses/ # ls cpc kbioset kbioset.lock
Lightning.Downloader
generates a GUID (globally unique identifier) by fingerprinting the network adapters and hostname of the endpoint. The GUID is sent to the C2 server which fetches and installs the other malware components and executesLightning.Core
on the endpoint.Lightning.Core
disguises itself as a legitimate kernel thread by using theprctl
utility to rename its calling thread tokkdmflush
. This is done within the earlier created/usr/lib64/seahorses/
directory as shown below:
# ls cpc kbioset kbioset.lock hpi kkdmflush.lock
- The core module establishes persistence by creating a
/etc/rc.d/init.d/elastisearch
file on the endpoint. Theelastisearch
file mimics the legitimate analytics engine, Elasticsearch.
# cd /etc/rc.d/init.d/ # ls elastisearch functions README
- Upon system boot, the malicious
elastisearch
script executes the downloader module and adds the persistent service using thechkconfig
utility. The content of the script is shown below:
#!/bin/bash # chkconfig:2345 90 20 /usr/lib64/seahorses/kbioset &
The command to execute the elastisearch
script is shown below:
sh -c chkconfig -add elastisearch
- The timestamp of the persistence
elastisearch
script is modified to match the timestamp of a fundamental Linux file such asfind
,whoami
orsu
using a cloaking method called “timestomping”. - The core module will then hide its PID (process ID) and associated network ports using a Linux kernel module (LKM) rootkit. The running PIDs of the malware are first written into two files named
hpi
andhpo
. Both files are inspected, and a check is done for the presence of a/proc/y.y
file path which verifies the existence of a rootkit. Once found, the PIDs get written to the/proc/y.y
file which the rootkit uses to hide its PID from commands such asnetstat
,ps
andss
, by removing any reference to the malicious framework. - A GUID is generated by
Lightning.Core
for communication with the C2 server using the same technique as the downloader module mentioned earlier. Based on responses from the C2, the core module is able to run shell commands, run plugins, fingerprint the endpoint, overwrite file contents, delete files or directories, send files to the C2, update or remove the malicious payload, and carry out many other actions based on the command executed. - The
Lightning.Core
andLightning.Downloader
modules communicate over TCP sockets. The data structure uses the JSON format. - The C2 profile is stored in a polymorphic encoded configuration file. This file cannot be detected by techniques that utilize hashes because it is unique for every creation instance. The analyzed malware sample makes use of a local IP address
10.2.22[.]67
with port33229
. Below we show the connection to the C2 server:
# netstat -antpl | egrep ':33229' tcp 0 1 10.0.2.15:39730 10.2.22.67:33229 SYN_SENT 38951/kdmflush
- The malware framework has its OpenSSH daemon named
Linux.Plugin.Lightning.Sshd
(sshod
) to initiate a passive mode of communication. This plugin is used to start an SSH service on the infected endpoint. TheLinux.Plugin.Lightning.Sshd
plugin contains the attacker’s hardcoded SSH keys. Using the host key shown below, the attacker is able to create an SSH-based secondary backdoor by establishing an SSH session to the infected endpoint using their own SSH key.
# The attacker's hardcoded host key in the sshod plugin is shown below! ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJtfoCJIxOtTRnimA8Ut3KtrcCdHPAGMqeOJFnDZkI4FZHWl1hSkDUKUxxCLb/fLBMmDGZ0YYpUBQD9h3VltS5IR7Qe/wNV69w2iOvO10BEabskvPxBzjT1Tc6kDKYOdBh6PyI9HPeGEiSj13CyZcJ3sMg8vnEvFE2NH0CTv3ZBaI0YCNq14rUU2MRjsx9U7Sz3fJHhLQMvLVs33bVTsYCVzGAaTtjcxpffpEfvhTapVr2Ke9TMe81aYtGtVsSHLBjjMtNsKXH58NUth6YOT9oUKArEI/ojYKbFLV4zSbwqSBkhV2MLBzoV8agyheYW5uxUsL80Fo5baoKXZM/iziV root@desktop-udluksg
The hashes of some components of the Lightning Framework analyzed are shown below:
Filename | sha256 |
---|---|
Lightning.Downloader | 48f9471c20316b295704e6f8feb2196dd619799edec5835734fc24051f45c5b7 |
Lightning.Core | fd285c2fb4d42dde23590118dba016bf5b846625da3abdbe48773530a07bcd1e |
Linux.Plugin.Lightning.Sshd | ad16989a3ebf0b416681f8db31af098e02eabd25452f8d781383547ead395237 |
The other components of the malware which are referenced based on strings and source code of the obtained framework modules are yet to be found in the wild and analyzed.
Detection with Wazuh
To understand the Lightning Framework malware and create detection mechanisms, we simulated and detected its activities using the following infrastructure:
1. A pre-built ready-to-use Wazuh OVA 4.3.9. Follow this guide to download the virtual machine.
2. CentOS 8.4.2105 endpoint with a Wazuh agent installed and enrolled to the Wazuh server. A Wazuh agent can be installed by following the deploying Wazuh agents guide.
The Wazuh capabilities we will utilize in detecting Lightning Framework malware are the Security Configuration Assessment (SCA) module and Osquery integration.
Security Configuration Assessment
The Wazuh SCA module is used to run checks that test system hardening, detect vulnerable software, and validate configuration policies. In this blog post, we utilize SCA to find the known IoCs of the Lightning Framework.
Note
Root user privileges are required to run the commands described below.
Wazuh server
1. Create a new policy file /var/ossec/etc/shared/default/lightning_framework.yml
:
policy: id: "lightning_framework" file: "lightning_framework.yml" name: "Lightning Framework Linux malware check" description: "Detecting Lightning Framework Linux malware" requirements: title: "Checking Lightning Framework malware on Unix/Linux based systems." description: "Check that system is Unix/Linux based." condition: any rules: - 'f:/etc/passwd' checks: - id: 20000 title: "Checking for Lightning Framework artifacts in \"/usr/lib64/*\" directory" description: "Check for Lightning Framework Linux malware artifacts." condition: all rules: - 'not c:find /usr/lib64/ -type d -name "seahorses" -> r:/usr/lib64/seahorses$' - id: 20001 title: "Checking for Lightning Framework persistence" description: "Checking for Lightning Framework persistence." condition: all rules: - 'not c:find /etc/rc.d/init.d/ -name "elastisearch" -> r:/etc/rc.d/init.d/elastisearch$' - id: 20002 title: "Checking for Lightning Framework Linux Kernel Module rootkit" description: "Checking for Lightning Framework LKM rootkit." condition: all rules: - 'not c:lsmod -> r:elastisearch'
2. Modify the owner and group of the newly created SCA policy file to belong to Wazuh:
# chown wazuh:wazuh /var/ossec/etc/shared/default/lightning_framework.yml
3. Edit /var/ossec/etc/shared/default/agent.conf
to contain the SCA block. This SCA policy will be shared with all agents in the default group:
<agent_config os="linux"> <sca> <enabled>yes</enabled> <scan_on_start>yes</scan_on_start> <interval>30m</interval> <skip_nfs>yes</skip_nfs> <policies> <policy>/var/ossec/etc/shared/lightning_framework.yml</policy> </policies> </sca> </agent_config>
4. Restart the Wazuh manager to apply the changes:
# systemctl restart wazuh-manager
Monitored endpoint
1. Edit the /var/ossec/etc/local_internal_options.conf
file directly on the monitored Linux endpoint. This is to enable command execution in the SCA policies which are sent from the Wazuh server. By default, remote commands are disabled for security reasons and need to be explicitly enabled by users:
# echo "sca.remote_commands=1" >> /var/ossec/etc/local_internal_options.conf
2. Restart the Wazuh agent to apply the changes:
# systemctl restart wazuh-agent
Testing the configuration
To test that the SCA policy is working correctly, we run the malware samples within our sandboxed CentOS 8 endpoint.
# ./Lightning.Downloader # ./Lightning.Core # ./Linux.Plugin.Lightning.Sshd
We can see the SCA scan results for an endpoint infected with Lightning Framework Linux malware:
Osquery integration
Using the Osquery integration, we are able to utilize SQL-based queries to detect the malware activities on the Linux endpoint. The data generated from Osquery is sent from the Wazuh agent to the Wazuh server, and the alerts can be viewed on the Wazuh dashboard.
We use an Osquery pack from Ryan Robinson to create the detection rules. The rules use information gathered via the reverse engineering process to detect Lightning Framework IoCs. Using this module we are able to find other related Lightning Framework samples with a unique file hash. To use Osquery with Wazuh to scan for the Lightning Framework IoCs, do the following:
Note
Root user privileges are required to run the commands described below.
Monitored endpoint
1. Install Osquery on the monitored endpoint:
# yum install yum-utils # curl -L https://pkg.osquery.io/rpm/GPG | tee /etc/pki/rpm-gpg/RPM-GPG-KEY-osquery # yum-config-manager --add-repo https://pkg.osquery.io/rpm/osquery-s3-rpm.repo # yum-config-manager --enable osquery-s3-rpm-repo # yum install osquery
2. Create a query pack /opt/osquery/share/osquery/packs/lightning.json
. This file contains specific detection queries which are used to detect Lightning Framework file artifacts, malware persistence, and installed rootkits:
{ "queries": { "artifacts": { "query": "SELECT path, filename, username, groupname, mtime, ctime, atime, md5, sha1, sha256 FROM file JOIN users using (uid) JOIN hash using (path) JOIN groups using (gid) WHERE file.directory in('/usr/lib64/seahorses/');", "interval": "60", "version": "1.0.0", "description": "https://www.intezer.com/blog/research/lightning-framework-new-linux-threat/", "platform": "linux", "value": "Possible Lightning Framework files" }, "startup-item": { "query": "SELECT * FROM startup_items WHERE name = 'elastisearch';", "interval": "60", "version": "1.0.0", "description": "https://www.intezer.com/blog/research/lightning-framework-new-linux-threat/", "platform": "linux", "value": "Possible Lightning Framework startup item" }, "kernel-module": { "query": "SELECT * FROM kernel_modules WHERE name = 'elastisearch';", "interval": "60", "version": "1.0.0", "description": "https://www.intezer.com/blog/research/lightning-framework-new-linux-threat/", "platform": "linux", "value": "Possible Lightning Framework rootkit" } } }
Where:
artifacts
is the query that detects the created malware artifacts.startup-item
is the query that detects the persistence startup script.kernel-module
is the query that detects the installed Linux kernel module rootkit.
3. Create a custom Osquery configuration file /etc/osquery/osquery.conf
and add the newly created lightning.json
query pack shown below:
Note
For users with Osquery previously installed and a /etc/osquery/osquery.conf
file present, all you need to do is update the configuration file by adding the highlighted lightning-framework query pack shown below.
{ "options": { "config_plugin": "filesystem", "logger_plugin": "filesystem", "utc": "true" }, "schedule": { "system_info": { "query": "SELECT hostname, cpu_brand, physical_memory FROM system_info;", "interval": 3600 }, "high_load_average": { "query": "SELECT period, average, '70%' AS 'threshold' FROM load_average WHERE period = '15m' AND average > '0.7';", "interval": 900, "description": "Report if load charge is over 70 percent." }, "low_free_memory": { "query": "SELECT memory_total, memory_free, CAST(memory_free AS real) / memory_total AS memory_free_perc, '10%' AS threshold FROM memory_info WHERE memory_free_perc < 0.1;", "interval": 1800, "description": "Free RAM is under 10%." } }, "packs": { "lightning-framework": "/opt/osquery/share/osquery/packs/lightning.json", "osquery-monitoring": "/opt/osquery/share/osquery/packs/osquery-monitoring.conf", "incident-response": "/opt/osquery/share/osquery/packs/incident-response.conf", "it-compliance": "/opt/osquery/share/osquery/packs/it-compliance.conf", "vuln-management": "/opt/osquery/share/osquery/packs/vuln-management.conf", "hardware-monitoring": "/opt/osquery/share/osquery/packs/hardware-monitoring.conf", "ossec-rootkit": "/opt/osquery/share/osquery/packs/ossec-rootkit.conf" } }
4. Validate the file to ensure there are no mistakes:
# osqueryctl config-check
5. Edit /var/ossec/etc/ossec.conf
and enable the Osquery module:
<ossec_config> <wodle name="osquery"> <disabled>no</disabled> <run_daemon>yes</run_daemon> <log_path>/var/log/osquery/osqueryd.results.log</log_path> <config_path>/etc/osquery/osquery.conf</config_path> <add_labels>yes</add_labels> </wodle> </ossec_config>
6. Restart the Wazuh agent to apply the changes:
# systemctl restart wazuh-agent
Wazuh automatically reads the /var/log/osquery/osqueryd.results.log
file and generates alerts related to these logs.
Testing the configuration
To view the Osquery events, it is necessary to enable the Osquery module on the Wazuh dashboard. This can be enabled on the Wazuh dashboard by navigating to Settings > Modules > Osquery and checking the box.
To test that the rules are working correctly, we trigger an alert by executing the obtained malware samples in our sandboxed CentOS 8 endpoint:
# ./Lightning.Downloader # ./Lightning.Core # ./Linux.Plugin.Lightning.Sshd
The screenshot below shows the alerts triggered by the Lightning Framework samples:
Conclusion
The Lightning Framework is a broad Linux malware framework that can compromise endpoints using various techniques. This versatile and complex framework is one of the recent malware strains targeting Linux endpoints. Wazuh has many modules that can be used in detecting the Lightning Framework. In this article, we have demonstrated how to detect the Lightning Framework using both the Wazuh SCA module and the Osquery integration with Wazuh.
References
- Lightning Framework: New Undetected “Swiss Army Knife” Linux Malware
- Detection Rules for Lightning Framework (with Osquery)
If you have any questions about this, join our Slack community channel!