The Splunk Threat Research Team continues to address ongoing threats in relation to geopolitical events in eastern Europe. The following payload named Cyclops Blink seems to target Customer Premise Equipment devices (CPE). These devices are generally prevalent in commercial and residential locations enabling internet connectivity (Cable, DSL Modems, Satellite Modems, Firewalls, etc).
Cyclops Blink is said to be a replacement for VPNFilter and includes the following features:
Cyclops Blink malware is compiled in either x86 or PowerPC elf binary. Below is the deep-dive analysis of its behavior and features.
It sets the default handler for SIGTERM, SIGINT, SIGIO, SIGPIPE, and SIGBUS which is SIGHUP where it will send a signal to a process when its controlling terminal is closed.
We also found that it will redirect the stdout or possible error of command it will execute to the /dev/null file.
It also modifies the iptables firewall setting to allow TCP traffic via a hard-coded list of port numbers. Below is the code snippet of how it initializes this command.
With this command, we also verify the redirection of stdout or error to /dev/null to hide error messages or output of its command in the user as the screenshot below shows.
Below is a short table of ports we’ve seen in 2 samples we’ve analyzed:
SHA256 |
PORT |
fc1e50172c0ce221452b967d1ef705f11bbfe2d54c533d68bd2a7a094605df2d |
3269 |
fc1e50172c0ce221452b967d1ef705f11bbfe2d54c533d68bd2a7a094605df2d |
636 |
fc1e50172c0ce221452b967d1ef705f11bbfe2d54c533d68bd2a7a094605df2d |
989 |
4ec5e0c5dccc5891d39ea76e3c3d3e26d8830d7aa4d63db6084dbfbec6f0d211 |
994 |
4ec5e0c5dccc5891d39ea76e3c3d3e26d8830d7aa4d63db6084dbfbec6f0d211 |
995 |
4ec5e0c5dccc5891d39ea76e3c3d3e26d8830d7aa4d63db6084dbfbec6f0d211 |
8443 |
This malware will check if its current process starts with “[kw” if yes it will check again if it is “[kworker:0/1]” . If not it will reload itself by creating a child process using “execl(“/proc/self/exe”. “[kworker:0/1]”) function like the code snippet below shows.
The name it uses for its process “[kworker:0/1]” is one of its techniques to blend into the several normal kworker processes running on compromised Linux machines.
As soon as this malware is running on its anticipated process name, it will fork several processes that will communicate via pipe, signal, and do different tasks that will be discussed further in the next few subheadings.
One of its fork spawned processes will be responsible for gathering information from the compromised host. Some of that system information is the disk free size, disk size, memory size, free memory, /etc/passwd, /etc/group, /proc/mount and /proc/partition. Below is the code snippet showing how it parses that information.
Another spawned process is responsible for downloading files from its C2 or uploading the gathered information to its C2 server. Below is the code snippet showing how it formatted the http GET command with hardcoded user agent to communicate to its C2 server.
If the download operation does not specify a file path, it will be saved in /var/tmp/a.tmp file.
Another fork process will try to check if the “/pending/WGUpgrade-dl” exists on the compromised host which is the legitimate device firmware update of WatchGuard. Below is the screenshot of the strace logs of the child process doing this task.
This malware has several backdoor commands which range from 0x0 - 0xd. For example, the command “0x0” is responsible for terminating the Cyclops Blink process, while 0xb-0xd is the command responsible for sending or preparing RSA public key, private key, and X.509 certificate to the specified spawn process.
Below is the code screenshot of how it prepares the following public and private keys as well as the RSA certificate that will be passed in one of its running modules.
Below is the screenshot of public keys, private keys, and the x.509 certificate we found in 2 Cyclops Blink malware we’ve analyzed.
Below is one of the decoded x.509 certificates of Cyclops Blink.
We also saw some of its C2 IP addresses that it tries to connect to during our analysis. Below is a screenshot of wireshark capturing the initial TCP traffic of its initial connections to some of its C2.
IPv4 C2 Server |
IP Address |
C2 Server |
212[.]202.147.10 |
C2 Server |
212[.]234.179.113 |
C2 Server |
185[.]82.169.99 |
C2 Server |
93[.]51.177.66 |
C2 Server |
80[.]15.113.188 |
C2 Server |
80[.]153.75.103 |
C2 Server |
109[.]192.30.125 |
C2 Server |
24[.]199.247.222 |
C2 Server |
105[.]159.248.137 |
C2 Server |
217[.]57.78.18 |
C2 Server |
2[.]229.24.16 |
C2 Server |
37[.]71.147.186 |
C2 Server |
80[.]155.38.210 |
C2 Server |
81[.]4.177.118 |
C2 Server |
37[.]99.163.162 |
This analytic looks for suspicious command lines that modify the iptables firewall setting of a linux machine.
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes where Processes.process = "*iptables *" AND Processes.process = "* --dport *" AND Processes.process = "* ACCEPT*" AND Processes.process = "*&>/dev/null*" AND Processes.process = "* tcp *" AND NOT(Processes.parent_process_path IN("/bin/*", "/lib/*", "/usr/bin/*", "/sbin/*")) by Processes.process_name Processes.process Processes.process_id Processes.parent_process_id Processes.process_guid Processes.dest Processes.user Processes.parent_process_name Processes.parent_process_path Processes.process_path | rex field=Processes.process "--dport (?<port>3269|636|989|994|995|8443)" | stats values(Processes.process) as processes_exec values(port) as ports values(Processes.process_guid) as guids values(Processes.process_id) as pids dc(port) as port_count count by Processes.process_name Processes.parent_process_name Processes.parent_process_id Processes.dest Processes.user Processes.parent_process_path Processes.process_path firstTime lastTime | where port_count >=3 | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` |
|
This analytic looks for suspicious process kworker command lines in a linux machine. kworker process name or thread are common names of kernel threads in linux process.
This hunting detections can lead to an investigation process containing the kworker commandline and process path in writable directory in linux like /home/, /var/log and /tmp/.
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes where Processes.parent_process = "*[kworker/*" Processes.parent_process_path IN ("/home/*", "/tmp/*", "/var/log/*") Processes.process="*iptables*" by Processes.parent_process_name Processes.parent_process Processes.process_name Processes.process Processes.process_id Processes.parent_process_id Processes.parent_process_path Processes.process_guid Processes.dest Processes.user | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `linux_kworker_process_commandline_filter`
|
Name |
Technique ID |
Tactic |
Description |
Linux Iptables Firewall Modification |
Defense Evasion |
This analytic looks for suspicious command lines that modify the iptables firewall setting of a Linux machine. |
|
Linux Kworker Process CommandLine |
Defense Evasion |
This analytic looks for suspicious process kworker command lines in a Linux machine. |
Filename |
Size |
Sha256 |
cyclopblink1 |
2332316 bytes (2277 KiB) |
4ec5e0c5dccc5891d39ea76e3c3d3e26d8830d7aa4d63db6084dbfbec6f0d211 |
cyclopblink2 |
7346456 bytes (7174 KiB) |
fc1e50172c0ce221452b967d1ef705f11bbfe2d54c533d68bd2a7a094605df2d |
Here are two vendor advisories that provide mitigation information:
The key to implementing these types of detections is the ability to monitor via a logging mechanism (i.e Syslog). If devices are vulnerable to these payloads and cannot be monitored, these devices must be discarded to eliminate the possibility of reinfection, or resistance to reset and reboot. Please also follow guidelines from CISA on prevention and mitigation.
You can find the latest content about security analytic stories on GitHub and in Splunkbase. Splunk Security Essentials also has all these detections available via push update. In the upcoming weeks, the Splunk Threat Research Team will be releasing a more detailed blog post on this analytic story. Stay tuned!
For a full list of security content, check out the release notes on Splunk Docs.
Any feedback or requests? Feel free to put in an issue on GitHub and we’ll follow up. Alternatively, join us on the Slack channel #security-research. Follow these instructions If you need an invitation to our Splunk user groups on Slack.
We would like to thank the following for their contributions to this post:
The Splunk platform removes the barriers between data and action, empowering observability, IT and security teams to ensure their organizations are secure, resilient and innovative.
Founded in 2003, Splunk is a global company — with over 7,500 employees, Splunkers have received over 1,020 patents to date and availability in 21 regions around the world — and offers an open, extensible data platform that supports shared data across any environment so that all teams in an organization can get end-to-end visibility, with context, for every interaction and business process. Build a strong data foundation with Splunk.