“Eye” spy: Cyclops Blink returns with extended capabilities
In August 2026, Counter Threat Unit™ (CTU) researchers analyzed a malicious 64-bit Linux executable named timezone_check that was discovered on multiple compromised Cisco Firewall Management Center (FMC) devices. The sophisticated modular implant provides persistent remote access to a compromised Linux system. CTU™ analysis indicates that it is a variant of the Cyclops Blink malware previously analyzed by the UK National Cyber Security Centre (NCSC) in 2022 and is likely associated with the Russia-based IRON VIKING threat group (also known as Sandworm and Seashell Blizzard). Cisco published details about this campaign on September 9, prompting CTU researchers to publicly release their analysis.
Unlike the WatchGuard-focused samples documented in 2022, the 2026 variant runs on x86-64 Linux and uses generic System V (SysV) persistence rather than vendor-specific firmware modification. This change broadens the range of potentially compatible network-edge appliances. The implant’s expanded capabilities include active network and service discovery, programmable packet surveillance, file transfer, and payload execution, allowing a compromised device to serve as a platform for internal reconnaissance, intelligence collection, and follow-on operations.
Malware overview
Cyclops Blink is a modular botnet and malware framework organized around a parent controller and five child-process worker modules. The parent creates dedicated inter-process communication (IPC) channels for each module, routes inbound commands by module identifier, gathers module output, applies cryptographic protection, and sends the resulting records to command and control (C2) infrastructure. The use of separate processes helps isolate module failures and allows several tasks to operate concurrently. Figure 1 shows the relationship between the controller and its worker modules.

Figure 1: Cyclops Blink architecture
The controller masquerades as a process named [kworker/0:1] to blend into Linux process listings and reduce the likelihood of casual discovery (see Figure 2). Genuine kworker threads perform background kernel work and are common on Linux systems.

Figure 2: Cyclops Blink controller pseudo-code
The controller maintains a fixed-size status structure that is distributed to every registered worker module. The structure contains the active C2 IPv4 address list, a session-related value, the recurring beacon interval, the time remaining until the next beacon, outbound queue information, the controller process ID, and the module ID and process ID of each installed worker. The controller rebuilds and broadcasts this structure during initialization, before C2 communications, and after processing recognized controller commands. This mechanism keeps independently executing worker processes synchronized with changes to shared configuration and controller state. Table 1 lists the implemented control codes.
| Control code | Assessed function |
| 0x00 | Terminate the controller |
| 0x01 | Trigger an immediate beacon by setting the next-beacon time to the current time |
| 0x02 | Replace the active in-memory C2 IPv4 address list |
| 0x03 | Schedule the next beacon after a specified delay |
| 0x04 | Set the recurring beacon interval |
| 0x05 | Load or replace a worker module |
| 0x06 | Restart the controller |
| 0x07 | Update a controller or C2 session-related value and then distribute it to worker modules |
| 0x08 | Reserved or unimplemented in the analyzed samples |
| 0x09 | Reserved or unimplemented in the analyzed samples |
| 0x0A | Reserved or unimplemented in the analyzed samples |
| 0x0B | Send the embedded RSA public key to a selected worker module |
| 0x0C | Send the embedded RSA private key to a selected worker module |
| 0x0D | Send the embedded X.509 certificate to a selected worker module |
Table 1: Cyclops Blink control codes
During initialization, the controller adds ACCEPT rules to the Linux iptables OUTPUT chain for TCP destination ports 43856 and 49172, which are the two ports used for its C2 communications. The controller first attempts to modify the filter table directly through the linked libiptc interface and includes a fallback path that invokes the system’s iptables utility. Corresponding rules are removed during controller shutdown or restart. These changes are intended to ensure that local firewall policy permits the implant’s outbound C2 connections.
Module descriptions
The implant analyzed by CTU researchers contains five worker modules that perform host reconnaissance, file transfer and payload execution, active network discovery, selective packet capture, and persistence.
Module 0x08: host reconnaissance
Module 0x08 profiles the compromised Linux system and its immediate network environment, giving the operator detailed insight into the device’s configuration, privileges, operational role, and connectivity. The module collects the following information:
- operating system, kernel, hostname, and uptime information
- processor, memory, filesystem, and storage details
- local users, groups, processes, and command lines
- network interfaces, addresses, ARP data, and resolver configuration
If the implant instance has sufficient privileges on the compromised host, the module may also access /etc/shadow, potentially exposing password hashes for offline analysis (see Figure 3).

Figure 3: High-level pseudo-code view of module 0x08
The reconnaissance module runs by default every 10 minutes or can be executed on demand. The collected information is returned to the controller for transmission to its C2 server. On a network-edge appliance such as a Cisco FMC, this reconnaissance provides valuable context because the host may have access to privileged management networks and multiple internal address ranges. The resulting inventory could help an operator understand the surrounding environment, identify administrative services and adjacent systems, assess available credentials, and plan subsequent network discovery or lateral movement.
Module 0x0F: file transfer and payload execution
Module 0x0F provides the implant’s principal mechanism for transferring files and deploying additional capabilities. The module can upload local files to C2 infrastructure, download content over HTTP or HTTPS, save retrieved payloads to an operator-specified path, and execute downloaded files as child processes. When the C2 server’s command does not provide a usable absolute destination, the module constructs a path beneath /var/tmp using the URL basename. If no usable basename is available, it falls back to /var/tmp/a.tmp.
The module can also write downloaded code directly into executable memory, allowing a payload to run without being stored as a conventional file. Retrieved Linux ELF executables can be registered as additional Cyclops Blink modules, extending the implant’s functionality while it remains active. Module 0x0F handles individual transfer requests from the C2 server in separate child processes, enabling the implant to conduct file transfer and payload execution operations without blocking the controller or other worker modules.
Module 0x0F gives the operator substantial post-compromise flexibility. It can collect and exfiltrate accessible data, retrieve supplementary tools, execute follow-on malware, update the implant’s module set, and establish additional access mechanisms. On a network-management appliance, this flexibility could allow the compromised device to serve as both an intelligence-collection point and a staging platform for operations against systems reachable from its trusted network position.
This module uses an embedded DNS-over-HTTPS resolver when an HTTP or HTTPS transfer target contains a hostname rather than a numeric IPv4 address. The resolver establishes a TLS connection directly to the Google public DNS at 8.8.8.8:443, submits a binary DNS query via an HTTP POST request to /dns-query that contains a hard-coded User-Agent, and extracts an IPv4 address from the returned DNS response (see Figure 4). The resolved address is then available to the module’s HTTP or HTTPS connection routines. This approach allows the implant to resolve operator-supplied transfer destinations independently of the compromised system’s configured DNS service and avoid the forensic evidence of entries in local DNS logs.

Figure 4: Cyclops Blink DNS lookup containing distinctive User-Agent
The User-Agent string deliberately imitates a contemporary desktop browser, although it is internally inconsistent because it combines Firefox’s rv:129.0 and Gecko token with a Chrome product token. These elements are not usually seen together except perhaps in scripts and automated scraping tools that employ open-source User-Agent generators. The same User-Agent string also appears in Cyclops Blink’s HTTP GET requests (see Figure 5). This HTTP GET request is also anomalous because it includes semicolons rather than commas in the Accept-Language field and because the Accept field lacks the expected media type and subtype (a generic wildcard would be Accept: */*).

Figure 5: Cyclops Blink malformed HTTP GET request
Module 0x0F can also use the following procedure to replace the running instance of Cyclops Blink:
- Identify the current executable via /proc/self/exe.
- Rename the current image to a backup path.
- Download the replacement to the original path.
- Restore the previous image if the download fails.
- Remove the backup after success.
- Execute the new image.
Module 0x11: network and service scanner
Module 0x11 provides internal network and service-discovery capabilities. It enumerates locally connected IPv4 networks and probes either an operator-defined port range or an embedded list of ports associated with commonly targeted infrastructure and management services. Scan tasks run in separate child processes, allowing multiple operations to proceed without blocking the module’s command channel.
One scan mode constructs and transmits complete Ethernet, IPv4, and TCP frames through a raw packet socket. It uses randomized source ports and sequence-related values, identifies open ports from matching SYN-ACK responses, and completes a minimal TCP handshake. For open services, the module can collect response data. On TCP port 80, it sends the request GET / HTTP/1.1rnrn, while port 443 is passed to a separate TLS-probing routine. The raw scanning functionality performs only lightweight packet handling and does not implement complete TCP stream processing. Successful findings, including target addresses, destination ports, and optional service-response data, are returned to the controller for protected transmission over the implant’s C2 channel.
This capability is particularly significant when the implant is deployed on a network-edge device. From that position, the module may be able to discover internal systems and management services that are not directly accessible from the internet. The results could provide the operator with a detailed view of the surrounding network, which can support target selection, identification of administrative infrastructure, and subsequent lateral movement. Unlike the host reconnaissance performed by module 0x08, module 0x11 actively interacts with neighboring systems and may therefore generate detectable scanning, connection, and service-probing activity. The implant has an embedded port list that appears designed to discover a wide range of strategically valuable internal systems (see Table 2).
| Category | Ports in the embedded list |
| Remote administration and terminal access | 22, 23 |
| File transfer and file sharing | 20, 69, 115, 139, 445 |
| Email and messaging | 25, 109, 110 |
| Name, directory, and discovery services | 42, 43, 53, 137, 389 |
| Web services | 80, 443, 1080, 3000, 5000, 8000, 8008, 8080, 8291, 8899 |
| Network management and monitoring | 161, 162, 829, 10050, 10051 |
| Routing, tunneling, and VPN-related services | 179, 1701, 1723, 4500 |
| Streaming and media services | 554, 8554 |
| IRC-associated and commonly repurposed high ports | 6665, 6667, 6668, 6669, 6697 |
| VMware services | 902, 903 |
| Other candidates | 18, 37, 49, 54, 56, 58, 68, 119, 156, 194, 458, 546, 547, 666, 751, 752, 760, 843, 853, 987, 1167, 1194, 1241, 1540, 6656 |
Table 2: Ports scanned by Cyclops Blink
Module 0x12: packet capture and content surveillance
Module 0x12 allows the operator to monitor traffic visible to the compromised device and selectively retain packets containing specified content. It captures raw Ethernet frames and efficiently searches IPv4 application payloads for operator-specified terms. It then uses operator-supplied search patterns to identify material relevant to intelligence collection rather than collecting all available traffic, reducing the volume of unnecessary traffic sent to the C2 server.
The module implements programmable network traffic surveillance and supports the three commands listed in Table 3.
| Command | Function |
| 0x01 | Start packet capture |
| 0x02 | Stop and destroy the active capture session |
| 0x03 | Reset the capture subsystem |
Table 3: Cyclops Blink module 0x12 command codes
Module 0x12 uses the following code to open a Linux packet socket, which allows the module to receive raw Ethernet frames visible to the compromised host, subject to its permissions and network position:
socket( AF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );
The operator can configure the capture duration, processing mode, address and port filters, and content-search behavior. The implant compiles supplied patterns into an Aho-Corasick-style matching automaton, enabling efficient simultaneous searching for multiple values. Captured IPv4 packets are parsed to locate TCP or UDP application payloads. The content is searched using the compiled matcher, and qualifying packets are retained. One callback contains a distinctive heuristic that suppresses an initial match when the following bytes are “-AGE” or “-Age”, which is likely an attempt to prevent user-related search terms from repeatedly matching on HTTP User-Agent strings. Qualifying packets are preserved as timestamped pcap-style records, allowing the operator to selectively collect traffic containing credentials, tokens, commands, or other material of interest.
This module could allow an operator to collect the following elements:
- cleartext credentials
- session cookies
- authentication tokens
- application requests
- proprietary protocol traffic
- administrative commands
- other sensitive network content matching operator-defined terms
The module does not reassemble TCP streams, so a search term divided across several TCP segments may evade an individual packet match.
Module 0x50: persistence and self-relocation
Module 0x50 establishes persistence by relocating the implant to a system directory and registering the relocated executable as a SysV init service. When the module starts, it resolves the path of the running executable via /proc/self/exe and compares the output to its intended installation location (/lib/tz/timezone_check in the analyzed samples). If the implant is already running from this location, the module skips the file-copy and service-registration steps. This approach prevents repeated self-relocation and duplication of the persistence artifacts.
When executed from another location, the module creates /lib/tz (setting its permissions to 0755) and copies the running executable to /lib/tz/timezone_check. After confirming that the copy operation succeeded, it unlinks the original executable from the filesystem. The running process is unaffected because Linux permits an executing file to be removed while its image remains mapped in memory. This behavior reduces evidence at the original deployment location and leaves only the more plausibly named persistent copy.
The module then creates an executable initialization script at /etc/init.d/timezone_check using a built-in shell template (see Figure 6).

Figure 6: Template for Cyclops Blink init script
To enable automatic execution, the module creates symbolic links for SysV runlevels 2 through 5, where each link references ../init.d/timezone_check:
- /etc/rc2.d/S89timezone_check
- /etc/rc3.d/S89timezone_check
- /etc/rc4.d/S89timezone_check
- /etc/rc5.d/S89timezone_check
The S89 prefix designates the script as a SysV init startup service and specifies its execution order within the boot sequence. On systems that honor these SysV runlevel directories, the configuration instructs the initialization system to invoke the script automatically per specified runlevel state, whilst ensuring timezone_check will be started after services assigned lower sequence numbers have already executed.
After installing the service, the module notifies the controller, pauses briefly, and forks a child process that launches the relocated implant. Both the installer and its child process terminate if execution fails. When successful, the new process begins running from the persistent pathname. The relocated instance recognizes that it is already installed and does not repeat the filesystem changes.
The installation paths and service name masquerade as legitimate Linux time zone-related components. The persistence code does not contain a privilege-escalation mechanism, so successful installation indicates that the implant was executed with sufficient permissions to write beneath /lib and /etc. On an enterprise Linux system or network appliance, write access to these directories generally requires root or an equivalently privileged execution context.
Command and control
Cyclops Blink communicates with its C2 infrastructure through outbound TCP connections protected by TLS. Samples analyzed by CTU researchers contain the hard-coded C2 address 89[.]34[.]96[.]56 and attempt connections over either TCP port 43856 or 49172. The controller applies ten-second socket send and receive timeouts and tries different address and port combinations until a TLS handshake succeeds. CTU analysis suggests that conventional TLS certificate verification is disabled, allowing the implant to establish an encrypted session without validating the C2 server through the public certificate trust system. After establishing a TLS connection, the implant exchanges a custom network application protocol rather than using HTTP.
The implant contains the version string “OpenSSL 3.5.4 30 Sep 2025” and implementation code consistent with the OpenSSL 3 provider architecture, indicating that it was likely statically linked with OpenSSL 3.5.4. The release date provides a useful build-timeline constraint, although embedded version strings can be modified and do not independently establish the sample’s compilation date.
In the incidents observed by CTU researchers, the implant beacons to its C2 server once per hour. However, the controller supports runtime modification of its communications configuration. As mentioned in the malware overview section, C2 tasking can replace the active IPv4 address list (with as many as 32 alternative addresses), trigger an immediate beacon, schedule the next connection after an operator-defined delay, or change the recurring beacon interval. Updated C2 addresses and timing information are held in memory and distributed to all registered worker modules through a fixed-size controller-state record.
Cryptographic material
In addition to TLS, the controller applies separate application-layer cryptographic protection to individual module output before placing it into the outbound C2 aggregate. This approach provides an additional layer of confidentiality inside the TLS session and encrypts the harvested data — including host details, collected files, network-scan findings, and captured packets — prior to network transmission. The Cyclops Blink binary contains three embedded cryptographic objects:
- a standalone RSA-3072 public key
- an RSA-2048 private key
- a matching self-signed X.509 certificate
The standalone RSA-3072 public key is associated with the implant’s application-layer protection of outbound C2 data. The separate RSA-2048 private key and certificate pair can be supplied to worker modules through controller tasking, indicating that the material is available for module-level cryptographic or TLS operations rather than being an unused build artifact. The precise operational use of this certificate and private key by each module has not been established.
The samples analyzed by CTU researchers contain different RSA-2048 key pairs and self-signed certificates, indicating that these elements are not fixed across all Cyclops Blink builds. This variation may reflect per-build, per-deployment, or other operator-controlled generation, although the available data does not establish how frequently the material is replaced.
The certificate validity periods should also not be interpreted as reliable malware-development or deployment dates. Because the certificates are self-signed, their creators control the validity fields and can assign a notBefore date that precedes the certificate’s actual creation. The embedded certificate metadata is therefore most useful for correlating related samples and identifying cryptographic variation, rather than establishing campaign timelines or providing durable network indicators.
Comparison with 2022 NCSC reporting
The Cyclops Blink samples deployed in 2026 preserve many characteristics documented in 2022, including the parent-controller architecture, forked worker modules, pipe-based IPC, randomized C2 failover, custom protocols, embedded cryptographic material, and the distinctive 0x08 and 0x0F modules. However, the 2026 framework targets x86-64 rather than PowerPC, uses generic SysV persistence instead of WatchGuard-specific firmware modification, includes a restructured module set, and adds active network scanning and programmable packet surveillance. Table 4 summarizes these differences.
| Characteristic | 2022 NCSC samples | 2026 samples |
| Target platform | WatchGuard Firebox and potentially other small office/home office (SOHO) network devices | Observed on Cisco FMC devices; compiled as 64-bit x86-64 Linux ELF files with potential compatibility across other suitable Linux environments |
| Architecture | 32-bit PowerPC, big-endian Linux ELF | 64-bit x86-64 Linux ELF using the System V AMD64 ABI |
| Built-in modules | Four modules supporting host reconnaissance, file transfer, C2 address storage, and WatchGuard-specific update and persistence functions | Five modules supporting host reconnaissance, file and payload management, active network scanning, packet capture, and generic Linux persistence |
| Persistence | Modifies a WatchGuard startup script and patches legitimate firmware images, allowing the infection to survive firmware updates | Copies the implant to /lib/tz/timezone_check and creates a SysV init service with startup links for runlevels 2 through 5 |
| Host reconnaissance | Module 0x08 collects operating system, account, storage, interface, and network information | Module 0x08 retains the same purpose and expands collection to include password hashes, resolver configuration, CPU information, and process command lines |
| Network reconnaissance | No equivalent built-in module was documented | Module 0x11 actively scans IPv4 networks, identifies open ports, collects service banners, and performs HTTP and TLS-related probing |
| Traffic surveillance | No equivalent built-in module was documented | Module 0x12 captures raw Ethernet traffic and selectively retains packets containing operator-defined search terms |
Table 4: Comparison of Cyclops Blink versions
Network devices potentially at risk
The 2022 version of Cyclops Blink was discovered on compromised WatchGuard devices. The 2026 variant is most likely to threaten x86-64 Linux-based network appliances that provide centralized management, security, routing, remote-access, or traffic-inspection functions. While it was discovered on Cisco FMCs, the implant is not tightly coupled to a single vendor platform. Its generic Linux implementation, SysV persistence, modular execution model, raw-socket networking, and reliance on standard Linux interfaces suggest that it could operate on other compatible appliances once an attacker has obtained sufficient privileges and transferred the executable.
SD-WAN controllers, VPN concentrators, network orchestrators, and comparable management platforms should also be considered plausible targets if they use a compatible x86-64 Linux environment. These systems share several relevant characteristics with FMC: centralized administration, privileged access to distributed devices, visibility into multiple network segments, and exposure through web, API, or SSH management services.
Attribution
CTU researchers assess with high confidence that the 2026 Cyclops Blink activity has a Russian nexus and with moderate confidence that it is associated with the IRON VIKING threat group. The assessment is based primarily on the substantial implementation-level continuity between the analyzed implant and Cyclops Blink, which UK and U.S. government agencies previously attributed to the Russian GRU-linked Sandworm threat group. CTU researchers track that group as IRON VIKING. The lower confidence in the threat group attribution reflects the absence of conclusive evidence directly linking IRON VIKING to the observed 2026 deployments.
Recommendations
Generic SysV persistence in the 2026 Cyclops Blink samples removes the dependency on WatchGuard-specific firmware, while active network scanning and selective packet capture substantially expand the implant’s intelligence-collection capabilities. The discovery on Cisco FMC devices highlights the risk posed by compromised network-management infrastructure. Devices in this position can provide access to privileged management networks, visibility across multiple network segments, and a trusted platform from which to conduct reconnaissance or deploy additional payloads. Linux architecture, persistence mechanisms, filesystem layout, available libraries, and security controls vary across products and software versions. Organizations should therefore extend threat hunting beyond the identified Cisco platform and examine compatible Linux-based network appliances for the documented filesystem, process, network, and cryptographic indicators.
Countermeasures and indicators
The following Sophos countermeasure relates to this threat:
- Linux/Agnt-JG
The threat indicators in Table 5 can be used to detect activity related to this threat. Note that IP addresses can be reallocated. The IP address may contain malicious content, so consider the risks before opening it in a browser.
| Indicator | Type | Context |
| 89[.]34[.]96[.]56 | IP address | Cyclops Blink C2 server |
| /lib/tz/timezone_check | File path | Used by 2026 version of Cyclops Blink |
| Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Chrome/129.0.0 | User-Agent | Used by 2026 version of Cyclops Blink |
Table 5: Indicators for this threat
