In mid-April 2026, researchers at Darktrace published a detailed breakdown of a malware sample that occupies a narrow but alarming niche in the threat landscape: a Windows-based OT weapon apparently designed from the ground up to sabotage Israeli water treatment and desalination infrastructure. The malware identifies itself internally as ZionSiphon — the name appears in a core function called directly from the main execution path — and the sample’s SHA-256 hash was submitted to VirusTotal for community visibility.
Unlike commodity ransomware or generic infostealers that occasionally wander into industrial networks, ZionSiphon was architected with specific knowledge of desalination engineering, Israeli water sector geography, and industrial control system protocols. Its code demonstrates familiarity with reverse osmosis plant software naming conventions, Modbus TCP framing, and the physical consequences of manipulating chlorine dosing registers. This is not the work of opportunists who stumbled into an OT environment. It reflects deliberate research into the target domain.

What prevented it from triggering its payload on discovery is a logic error in the country validation function — a broken XOR routine where the developer encoded a comparison string with one method and attempted to verify it at runtime with an incompatible one. The result: the malware consistently concludes it is not running in Israel and initiates self-deletion. Every other mechanism — persistence, privilege escalation, configuration file tampering, Modbus register writes, USB propagation — operates as intended.
Threat Actor Identity and Ideological Framing
Before examining the technical mechanisms, understanding the political context encoded directly into the binary is essential because it shapes every design decision the author made. The malware embeds two Base64-encoded strings that serve no operational function whatsoever — they are ideological signatures, the digital equivalent of spray-painting a manifesto on a wall. The actor identifies themselves using the handle 0xICS — a deliberate construction borrowing the hexadecimal prefix common in programming and reversing communities, combined with the acronym for Industrial Control Systems. This suggests a developer self-conscious about their technical identity within the ICS security space.
The first string is stored under a variable named Netanyahu and its Base64 value, SW4gc3VwcG9ydCBvZiBvdXIgYnJvdGhlcnMgaW4gSXJhbiwgUGFsZXN0aW5lLCBhbmQgWWVtZW4gYWdhaW5zdCBaaW9uaXN0IGFnZ3Jlc3Npb24uIEkgYW0gIjB4SUNTIi4=, decodes unambiguously to a statement of solidarity with Iran, Palestine, and Yemen framed against what the author terms Zionist aggression.
Variable name
Netanyahu
Base64 encoded
SW4gc3VwcG9ydCBvZiBvdXIgYnJvdGhlcnMgaW4gSXJhbiwgUGFsZXN0aW5lLCBhbmQgWWVtZW4gYWdhaW5zdCBaaW9uaXN0IGFnZ3Jlc3Npb24uIEkgYW0gIjB4SUNTIi4=
Decoded UTF-8
In support of our brothers in Iran, Palestine, and Yemen against Zionist aggression. I am “0xICS”.
The second string is stored under the variable Dimona — a reference to the Israeli city in the Negev desert that hosts the Shimon Peres Negev Nuclear Research Center, Israel’s assumed nuclear weapons facility. The choice of this name as a variable label is itself a geopolitical signal. Its Base64 value, UG9pc29uaW5nIHRoZSBwb3B1bGF0aW9uIG9mIFRlbCBBdml2IGFuZCBIYWlmYQo=, decodes to a threat against the civilian populations of Tel Aviv and Haifa — Israel’s two largest metropolitan areas.
Variable name
Dimona
Base64 encoded
UG9pc29uaW5nIHRoZSBwb3B1bGF0aW9uIG9mIFRlbCBBdml2IGFuZCBIYWlmYQo=
Decoded UTF-8
Poisoning the population of Tel Aviv and Haifa
Darktrace researchers note these strings perform no runtime function. They are not passed to any execution path, are not used in comparisons, and do not influence program flow. Their presence is purely declarative — the author wanted them visible to anyone who reversed the binary. This behavior is consistent with hacktivist-adjacent actors who blend operational capability development with public political messaging, a pattern seen repeatedly in the Iran-aligned threat ecosystem over the past several years.
The broader geopolitical context reinforces this reading. In the same month ZionSiphon was analyzed, a suspected Iran-nexus password spray campaign was documented targeting Microsoft 365 tenants in the UAE and Israel, and the Iranian threat actor tracked as MuddyWater was observed conducting intrusions against networks in Israel, the United States, and Canada. In March 2026, a separate campaign distributed a trojanized version of Israel’s RedAlert emergency notification app via SMS spoofing, stealing contacts and GPS data from victims. ZionSiphon sits within a demonstrably active pattern of Iran-aligned cyber operations targeting Israeli civilian infrastructure, though Darktrace has not made a formal state attribution claim, and neither does this analysis.
Geographic and Sectoral Targeting Architecture
ZionSiphon implements targeting at two distinct layers, each serving as a gate that must be passed before any destructive action is taken. The first layer is geographic, implemented through hardcoded Israeli IP address ranges. The second layer is environmental, implemented through process name inspection and filesystem artifact detection. Only when both layers return a positive match does the malware proceed to payload execution. This dual-gate design reflects awareness that simply landing within an Israeli IP range is insufficient — the attacker specifically wanted to hit operational water infrastructure, not generic IT systems.
Layer One: IP Geofencing via Hardcoded CIDR Blocks
The malware’s class initializer populates an ipRanges data structure with three IPv4 ranges, each obfuscated via Base64 encoding to avoid trivial pattern matching:
// Decoded from Base64 in the static constructoripRanges[0] = "2.52.0.0 - 2.55.255.255" // HOT TELECOM / Israeli ISP allocations
ipRanges[1] = "79.176.0.0 - 79.191.255.255" // Bezeq International allocations
ipRanges[2] = "212.150.0.0 - 212.150.255.255" // Israeli ISP allocations
All three blocks are IANA-allocated to Israeli network operators. The IsTargetCountry() function converts the host’s local IPv4 address to a 32-bit unsigned integer and performs a numeric range comparison against each entry. If the host IP falls within any of the three ranges, the geographic gate would theoretically pass. The IP-to-integer conversion is a standard technique — an address like 79.180.0.1 becomes 1336934401, which is then compared arithmetically against the integer representations of the range bounds. This avoids string parsing overhead and is computationally efficient for the comparison loop.
The decision to hardcode multiple separate ISP ranges rather than a single broad CIDR like 2.0.0.0/8 indicates specific knowledge of Israeli internet topology. The author targeted blocks associated with Israeli ISPs rather than applying a coarse country-level net, which would have included non-Israeli traffic and increased the risk of unintended execution.
Layer Two: OT Environment Fingerprinting
The IsDamDesalinationPlant() function performs the second layer of targeting checks using two parallel approaches: live process enumeration and static filesystem inspection. The process list check iterates through all running processes on the host and compares their names against nineteen hardcoded strings. The specificity of these strings is notable — they are not generic industrial terms but reflect knowledge of how water treatment software vendors actually name their executable components:
// Process name targets (selected from full list)"DesalPLC" // Desalination PLC management software
"ROController" // Reverse Osmosis controller interface
"SchneiderRO" // Schneider Electric RO management
"ChlorineCtrl" // Chlorine dosing control process
"WaterPLC" // Generic water-treatment PLC HMI
"OsmosisPLC" // Osmosis process PLC interface
"BrineControl" // Brine discharge management
"SalinityCtrl" // Salinity monitoring and control
The filesystem checks reinforce this, scanning for directories under C:\Program Files\ specific to IDE Technologies — the Israeli company that built the Sorek and Ashdod desalination plants — alongside Schneider Electric’s desalination management suite. Configuration files targeted include C:\DesalConfig.ini, C:\ROConfig.ini, C:\ChlorineControl.dat, and C:\SalinityControl.ini. The presence of IDE Technologies in the directory list is particularly significant: IDE Technologies is a subsidiary of Delek Group and is directly responsible for operating several of the desalination plants named in the malware’s targeting strings. Including their software path suggests the author had plant-specific knowledge, not just generic OT awareness.
The target string list embedded in the malware’s binary directly maps to real Israeli water infrastructure. Mekorot is the state-owned national water company that owns and operates the country’s distribution network. Sorek (in Rishon LeZion), Hadera, Ashdod, and Palmachim are four of Israel’s five major seawater reverse osmosis desalination plants, together producing hundreds of millions of cubic meters of potable water annually and supplying a substantial fraction of the country’s drinking water. Shafdan, located near Rishon LeZion, is Israel’s central wastewater reclamation facility, treating effluent from the Tel Aviv metropolitan area for agricultural reuse. An attacker disrupting Shafdan’s chlorination systems would affect both wastewater discharge safety and the reclaimed water supply for agriculture. The author’s inclusion of these specific sites demonstrates reconnaissance into the national water architecture, not generic targeting.



Execution Chain: From Launch to Payload Gate
Privilege Escalation via PowerShell UAC Bypass
On first execution, the malware immediately calls RunAsAdmin(), which in turn invokes IsElevated() — a function that retrieves the current Windows principal identity and queries its membership in the local Administrators security group using the WindowsIdentity and WindowsPrincipal .NET classes. If the process is already elevated, execution continues normally. If not, the malware enters a brief wait on a named mutex (to prevent concurrent execution instances), then launches a new instance of itself through PowerShell:
powershell.exe Start-Process -FilePath <current_executable_path> -Verb RunAs
The -Verb RunAs parameter triggers a Windows UAC elevation dialog asking the user to approve administrator access. This is not a UAC bypass in the true technical sense — it does not exploit a vulnerability to silently elevate — but rather uses a legitimate OS mechanism to request elevation interactively. The original process then waits for the elevated child process to complete before exiting. This approach is reliable across Windows 10 and 11 without triggering antivirus heuristics, since PowerShell invoking a process with RunAs is a common administrative workflow. The tradeoff is that it requires the user to click through a UAC prompt, limiting stealth on systems with standard user accounts that have no administrative rights at all.
Persistence: Registry Run Key with Process Name Spoofing
With administrative rights confirmed, the persistence routine s1() executes. This function constructs a stealthPath by combining the LocalApplicationData environment variable path with the hardcoded filename svchost.exe, resulting in a path like C:\Users\[username]\AppData\Local\svchost.exe. The choice of svchost.exe as the filename is deliberate camouflage — the Windows Service Host process, which genuinely runs as multiple instances simultaneously in every standard Windows installation, is one of the most commonly ignored process names during casual triage.
The routine then checks whether the currently executing binary is already at the stealth path. If not, it copies itself there and sets the file’s attributes to Hidden using the .NET File.SetAttributes() method with the FileAttributes.Hidden flag. Hidden files are invisible in Windows Explorer with default settings and in many basic directory listings. The persistence key is then written:
// Registry persistence entry
Key: HKCU\Software\Microsoft\Windows\CurrentVersion\Run
Value: "SystemHealthCheck"
Data: "C:\Users\[user]\AppData\Local\svchost.exe"
HKCU\...\Run (current user hive) is significant because it does not require SYSTEM or elevated privileges to write — a standard user can set their own Run keys. This means the persistence mechanism works even if the UAC step is partially constrained. The value name SystemHealthCheck is chosen to blend with legitimate monitoring software names visible in the Run key of typical enterprise machines. The combination of a plausible autorun name, hidden file attribute, and a filename shared with a core Windows process represents a three-layer stealth stack that would evade casual inspection.
Target Validation Logic and Its Fatal Flaw
After establishing persistence, the malware executes its gate-checking sequence. The main validation function calls both IsTargetCountry() and IsDamDesalinationPlant(). IsTargetCountry() performs the IP range comparison described above, but then makes a secondary string comparison that is where the logic collapses entirely.
In the static constructor, each ipRanges entry is associated with a decoded companion string "Nqvbdk", derived from the Base64 value "TnF2YmRr". At runtime, IsTargetCountry() compares this stored string against the runtime result of calling EncryptDecrypt("Israel", 5). The EncryptDecrypt function is a simple XOR cipher — it iterates through each character of the input string and XORs its ASCII value with the integer key, then converts the result back to a character:
function EncryptDecrypt(text: string, key: int) → string:
result = []
for ch in text:
result.append(char(ord(ch) XOR key))
return result.join()
// Applying the function: EncryptDecrypt("Israel", 5)
// I(73) XOR 5 = 76 → 'L'
// s(115) XOR 5 = 118 → 'v'
// r(114) XOR 5 = 119 → 'w'
// a(97) XOR 5 = 100 → 'd'
// e(101) XOR 5 = 100 → 'd'
// l(108) XOR 5 = 105 → 'i'
// Result: "Lvwddi" ← NOT "Nqvbdk"
As Darktrace’s analysis establishes, no XOR key value will transform "Israel" into "Nqvbdk". The two strings are derived from different encoding operations that are mutually incompatible. Analytically, this suggests one of three scenarios: the developer generated "Nqvbdk" using a different cipher or encoding pass and later replaced the encoding function with the XOR routine without recalculating the stored comparison value; or a different version of the string — perhaps not "Israel" but a differently spelled or cased variant — was intended as the input; or the mismatch is intentional, deployed as a defanged testing version with the kill switch left engaged. Darktrace researchers leave this question open, noting the behavior is consistent with either a development build or a prematurely deployed sample.
The consequence is absolute: IsTargetCountry() always returns false. The malware never reaches its payload. Instead, it immediately calls SelfDestruct().
Self-Destruct: Anti-Forensics Through Cascading Deletion
The SelfDestruct() function implements a multi-step evidence removal sequence. First, it removes the SystemHealthCheck value from the Run registry key, eliminating the persistence artifact. Second, it writes a log entry to %TEMP%\target_verify.log containing the string “Target not matched. Operation restricted to IL ranges. Self-destruct initiated.” — notably, the log file itself becomes an indicator of compromise for forensic analysts, as it leaves behind proof of the malware’s attempted execution and targeting logic even as the binary erases itself. Third, it creates %TEMP%\delete.bat, a batch script that loops with retry logic to delete the malware’s executable (handling file lock timing), and then deletes itself:
:retry
del /F /Q "C:\Users\[user]\AppData\Local\svchost.exe"
if exist "C:\Users\[user]\AppData\Local\svchost.exe" goto retry
del /F /Q "%~f0" ; deletes delete.bat itself
The retry loop is necessary because Windows file handles can prevent immediate deletion of a running or recently-closed executable. This self-destruct pattern is sophisticated relative to the rest of the malware — the developer clearly thought about forensic residue and built a mitigation into the default execution path.
The Sabotage Payload: Configuration File Poisoning and Modbus Register Manipulation
Phase One — Configuration File Tampering
If the country check ever passes (as it would in a corrected build), the malware’s first action is not network-based — it is direct, local filesystem modification through IncreaseChlorineLevel(). This function iterates through the same list of OT configuration files identified during the environment fingerprinting phase. The moment it finds any of the target files present, it appends the following fixed text block and immediately returns without processing any remaining files in the list:
; Block appended to first matched OT config file Chlorine_Dose=10 Chlorine_Pump=ON Chlorine_Flow=MAX Chlorine_Valve=OPEN RO_Pressure=80
The physical implications of these values require explanation. In water treatment, chlorine is dosed in carefully calibrated parts-per-million concentrations — typically between 0.2 and 4 mg/L in treated drinking water. A Chlorine_Dose=10 entry setting chlorine delivery to maximum, combined with Chlorine_Flow=MAX and Chlorine_Valve=OPEN, would instruct dosing pumps to inject chlorine at their physical maximum rate. The resulting concentration in water reaching consumers could reach levels far exceeding WHO guidelines of 5 mg/L for acute exposure, potentially causing mucous membrane irritation, respiratory distress, and in high enough concentrations, chemical burns to the gastrointestinal tract. The RO_Pressure=80 entry targets reverse osmosis membrane pressure. Typical seawater RO systems operate at 55–70 bar; setting pressure to an unnaturally high value risks membrane rupture, piping failure, and damage to the high-pressure pump assemblies that are among the most expensive components in a desalination plant.
Whether these configuration values would actually be read and acted upon by the plant’s control software depends on implementation-specific factors — whether the targeted .ini and .dat files are actively polled at runtime, whether they represent read-only reference configurations or live control parameters, and whether the plant’s SCADA/DCS layer validates input ranges. The malware’s approach assumes a direct relationship between filesystem configuration values and physical actuator commands, which may or may not hold in any given plant’s specific architecture. This is an important caveat: the damage potential is real but not guaranteed by the file write alone.
Phase Two — Modbus TCP Register Manipulation
If none of the target configuration files are found on the local filesystem, the malware escalates to network-based OT device discovery and attack through the function UZJctUZJctUZJct() — a deliberately obfuscated name that provides no semantic hint to analysts or defenders scanning process lists or logs. This function derives the local /24 subnet from the host IP, then launches a parallelized TCP connection sweep across all 255 host addresses, probing three industrial protocol ports simultaneously:
| Protocol | Port | Validation Signature | Function Code Targeted |
|---|---|---|---|
| Modbus TCP | 502 | Response byte[0] in range 1–255 | FC03 Read, FC06 Write Single Register |
| DNP3 | 20000 | Bytes[0,1] == 05 64 | Incomplete placeholder only |
| S7comm (Siemens) | 102 | Byte[0] == 03 | WriteVar (0x05) — incomplete |
The connection timeout is 100 milliseconds per attempt. Because all probes are launched concurrently via parallel tasks, the total sweep time across a /24 network is approximately 100–300 ms in practice — fast enough to complete before most network monitoring tools would flag systematic behavior as a scan. Each responsive device is recorded as an ICSDevice object storing its IP, port, and protocol label.
For Modbus — the most developed attack path — the second-stage validation sends a single null byte to the open port and reads the response. A valid Modbus device returning any non-zero first byte is logged. The malware then issues a Read Holding Registers request, the single most common Modbus operation in water treatment environments:
; Modbus TCP Read Holding Registers request frame
01 ; Unit ID (slave address — often ignored in TCP)
03 ; Function Code: Read Holding Registers
00 00 ; Starting address: register 0
00 0A ; Quantity: 10 registers
The malware then reads the ten 16-bit register values returned in the response, parsing them in pairs. For each register, it applies a heuristic to determine relevance: for a chlorine dose register, it looks for values between 1 and 999 (reasonable engineering unit range for a dosing setpoint); for a turbine speed register, it looks for values above 100. When a plausible register is found, the malware constructs a Write Single Register command (Modbus Function Code 6) targeting that register:
; Modbus FC06 Write Single Register — Chlorine_Dose attack 01 ; Unit ID 06 ; Function Code: Write Single Register XX XX ; Register address (dynamically identified) 00 64 ; Value: 100 decimal for Chlorine_Dose 00 00 ; Value: 0 for all other parameters
The value of 100 written to the chlorine dose register is an engineering-unit value — its real-world consequence depends entirely on the scaling factor defined in the PLC’s program. In many water treatment PLCs, a register value of 100 in a dosing context might represent 100% of maximum pump output or 100 mg/L concentration target — both catastrophic relative to safe drinking water standards. The fallback behavior is equally concerning: if no register meets the heuristic criteria after parsing all ten, the malware does not abandon the attack. Instead, it sends a set of hardcoded Modbus write frames with predetermined register addresses and values, essentially attempting a blind write to whatever addresses the developer considered most likely to affect plant operations. This fallback reflects partial knowledge of the target environment combined with a determination to cause damage regardless of dynamic discovery outcomes.
DNP3 and S7comm: Protocol-Accurate but Non-Functional
The DNP3 branch returns the byte sequence 05 64 0A 0C 01 02. The first two bytes, 0x05 0x64, are indeed the correct DNP3 link-layer synchronization header that precedes every valid DNP3 frame. The subsequent bytes have the right general shape of early link-layer header fields, but the sequence is critically incomplete: a valid DNP3 frame requires destination address (2 bytes), source address (2 bytes), link-layer control byte, CRC blocks (2 bytes each), and an application-layer payload containing the actual function code and object data. The six-byte sequence provided by ZionSiphon is insufficient to form any valid DNP3 application request and would be rejected or ignored by a real DNP3 device stack.
The S7comm branch returns 05 00 1C 22 1E. The first byte 0x05 corresponds to the WriteVar function code in Siemens’ S7 parameter block format — the S7 equivalent of a Modbus register write. However, the remaining bytes do not form a valid item definition. A proper S7 WriteVar parameter block requires at minimum one item with a full 11-byte variable specification structure defining transport size, data length, database number, area code, and bit address. The five-byte fragment is less than half the minimum required size and would be malformed to any S7 device. Darktrace’s assessment is that these fragments contain protocol-accurate prefixes — suggesting the author understood what a proper S7 WriteVar initiation looks like — but was either still researching the full frame structure or ran out of time before completing the implementation. Both branches are architecturally framed identically to the Modbus path; they just lack the functional payload.
USB Propagation: The Air-Gap Bridge
The persistence and OT scanning mechanisms address networks already accessible over TCP/IP. But the most operationally significant targets in the water sector — the engineering workstations directly connected to PLCs and SCADA servers at Sorek, Shafdan, or Ashdod — are almost certainly air-gapped or at minimum segmented behind firewalls that block direct internet access. ZionSiphon addresses this through a removable-media propagation mechanism that directly echoes the technique that made Stuxnet the defining cyberweapon of the ICS era.
The USB propagation function, named sdfsdfsfsdfsdfqw() — a deliberately meaningless name suggesting either anti-analysis obfuscation or that the developer treated it as throwaway code — enumerates all mounted drives using .NET’s DriveInfo.GetDrives() and filters for those with DriveType.Removable. For each removable drive found, it checks for the presence of its own copy using the svchost.exe filename. If the file is not present, it copies the payload to the drive root and sets both Hidden and System file attributes. The System attribute, in addition to Hidden, means the file is invisible to dir commands without the /A:SH flags and requires explicit attribute-aware enumeration to detect.
The shortcut creation mechanism, CreateUSBShortcut(), then iterates through all visible files in the removable drive root — documents, images, or any other user data — and for each one creates a Windows Shell Link (.lnk) file. The LNK file’s TargetPath property is set to point to the hidden svchost.exe payload, while the IconLocation is set to shell32.dll, 4 — the standard Windows generic document icon that would appear indistinguishable from a real document shortcut. The original file is then hidden. The result: a user browsing the USB drive in Windows Explorer sees what appears to be their original files (they are now LNK shortcuts visually identical to the originals). Clicking any one of them silently executes the malware payload via WScript.Shell before optionally opening the original target file to avoid suspicion.
; WScript.Shell shortcut construction (pseudocode)
Set oShell = CreateObject("WScript.Shell")
Set oShortcut = oShell.CreateShortcut(drive + "\\" + filename + ".lnk")
oShortcut.TargetPath = drive + "\\" + "svchost.exe" ; hidden payload
oShortcut.IconLocation = "shell32.dll, 4" ; generic file icon
oShortcut.Save()
SetAttributes(originalFile, Hidden)
This technique is classified under MITRE ATT&CK as T1091 — Replication Through Removable Media. It is the same fundamental mechanism used by Stuxnet’s LNK exploit (CVE-2010-2568), which propagated from infected USB sticks to air-gapped Siemens S7-300 systems at Iran’s Natanz enrichment facility. ZionSiphon’s implementation does not exploit a Windows vulnerability for the LNK execution — it relies on user interaction — but the strategic logic is identical: assume the high-value OT target is network-isolated, and use physical media as the infection vector for the final hop.
The significance of this design choice cannot be overstated in the context of water infrastructure. Engineering workstations at Israeli desalination plants — the exact systems ZionSiphon’s environment fingerprinting is designed to detect — are almost certainly not reachable over the internet. Operators at facilities like Sorek or Shafdan routinely use USB drives to transfer software updates, configuration backups, and vendor patches between their IT networks and the OT-isolated plant floor. ZionSiphon is architected to exploit precisely this practice. A single infected USB drive, passed to a technician in a contractor’s office or carried from an internet-connected administrative machine to an OT workstation, bridges the air gap completely. Once on the OT-side host, Phase One config poisoning and Phase Two Modbus attacks both become available without any further network access requirements.
Capability Matrix: What Works, What Doesn’t, and What’s One Fix Away
| Capability | Function / Mechanism | Status | Notes |
|---|---|---|---|
| Privilege escalation | RunAsAdmin() / PowerShell RunAs | Functional | UAC prompt required; no silent bypass |
| Persistence via registry | s1() / HKCU Run key | Functional | Hidden svchost.exe; survives reboot |
| OT environment fingerprinting | IsDamDesalinationPlant() | Functional | 19 process names, 15+ filesystem paths |
| Country validation | IsTargetCountry() / XOR compare | Broken | XOR mismatch; always returns false |
| Self-destruct / anti-forensics | SelfDestruct() / delete.bat | Functional | Removes registry key, deletes binary |
| Config file chlorine poisoning | IncreaseChlorineLevel() (local) | Functional (if triggered) | Appends Chlorine_Dose=10, RO_Pressure=80 |
| OT subnet scanning | UZJctUZJctUZJct() | Functional | Parallel /24 sweep; 100ms timeout |
| Modbus register read/write | FC03 + FC06; dynamic + fallback | Largely Functional | Register discovery heuristic + hardcoded fallback |
| DNP3 command execution | GetCommand() DNP3 branch | Incomplete | Only link-layer header prefix; no valid frame |
| S7comm command execution | GetCommand() S7 branch | Incomplete | 5-byte WriteVar stub; too short to be valid |
| USB propagation | sdfsdfsfsdfsdfqw() + CreateUSBShortcut() | Functional | Hidden svchost.exe + LNK deception on removable drives |
Historical Precedent and Threat Landscape Context
ZionSiphon does not exist in isolation. Water infrastructure has been a recurring target in the cyber dimension of the Arab-Israeli conflict and in Iran-linked operations broadly. In February 2020, the Israeli National Cyber Directorate issued an alert about attempted intrusions into water treatment facilities; in April 2020, attackers — attributed by several Western intelligence services to Iran — compromised SCADA systems at Israeli water treatment plants and attempted to alter chlorine dosing levels. The attack was reportedly detected before any water supply impact occurred. In that incident, the method involved remote access to HMI systems accessible over the internet without adequate authentication, not a custom malware deployment — but the operational intent was identical to ZionSiphon’s payload: manipulate chlorine to harm civilians.
The most technically relevant historical comparison is Stuxnet, the 2009–2010 cyberweapon widely attributed to the United States and Israel targeting Iran’s uranium enrichment program at Natanz. Stuxnet used four separate Windows zero-day exploits, forged Siemens driver certificates, and a USB-based air-gap bridge to reach air-gapped Siemens S7-315 and S7-417 PLCs controlling Siroua IR-1 centrifuges. It manipulated frequency converter drives to cause physical centrifuge destruction while feeding falsified normal readings to operators. ZionSiphon shares Stuxnet’s USB propagation strategy and its focus on directly manipulating industrial process parameters, but operates at far lower technical sophistication — no zero-days, no signed drivers, no sensor data forgery. It is, analytically, what an early-development ICS weapon looks like before a capable threat actor completes it.
TRITON/TRISIS, discovered in 2017 at a Saudi petrochemical facility, is another relevant comparison. That malware targeted Schneider Electric Triconex Safety Instrumented Systems — the last layer of protection preventing industrial processes from causing physical damage or explosion. Like ZionSiphon, it combined IT-layer persistence mechanisms with OT-layer protocol knowledge (Triconex’s proprietary TriStation protocol). Unlike ZionSiphon, TRITON was functionally complete and deployed operationally. The common thread: nation-state or nation-state-proximate actors investing in custom OT weapons targeted at specific industrial environments in geopolitically contested regions.
The 2021 Oldsmar, Florida water treatment attack — where an attacker accessed a TeamViewer-connected HMI and increased sodium hydroxide levels to 111 times the normal amount before an operator noticed — demonstrated that water treatment systems can be manipulated remotely and that the physical consequences of chemical tampering are real and rapid. In that case, manual oversight caught the manipulation within minutes. ZionSiphon’s design assumes automated configuration file processing rather than relying on remote access, which would not necessarily trigger the same operator visibility.
Operational and Strategic Implications
The analyzed version of ZionSiphon is not currently capable of executing its intended attack. This fact should not obscure what the malware reveals about the threat actor’s capabilities and intentions. Nor should the word “unfinished” be applied carelessly — ZionSiphon is not an unfinished weapon. It is a fully armed weapon with a broken trigger. The distinction matters operationally: everything downstream of the validation gate is complete and functional. The config file tampering works. The Modbus read-discover-write cycle works. The USB propagation and LNK deception work. The self-destruct anti-forensics works. What doesn’t work is the single conditional that decides whether to fire. The Modbus implementation demonstrates genuine protocol-layer knowledge: the author correctly structured FC03 read frames, understood register addressing, built dynamic register discovery logic, and constructed valid FC06 write frames. The environment fingerprinting reflects domain research into specific Israeli water treatment vendors and their software naming conventions. The self-destruct mechanism reflects operational security awareness. The USB propagation mechanism reflects understanding of air-gap architecture in critical infrastructure.
The broken XOR validation is a single-line fix. Changing the stored comparison string from "Nqvbdk" to the correct XOR-5 encoding of "Israel" — which is "Lvwddi" — would render the country gate functional. At that point, every downstream mechanism activates. The configuration file tampering would execute immediately on any system hosting the targeted water treatment software files. The Modbus scanning and register-write logic would run against every device on the local subnet responding on port 502. The USB propagation would silently spread to any removable media inserted into the infected host.
The incomplete DNP3 and S7comm branches are a separate concern. DNP3 is the dominant protocol in North American water utility SCADA systems; S7comm is native to Siemens PLCs used across European and Middle Eastern industrial installations, including water infrastructure in Israel. An actor who completes ZionSiphon’s multi-protocol capability would have a single malware capable of attacking the control layer across the full spectrum of Western water treatment architectures, not merely Modbus-based installations. The fact that the author clearly understood what the correct S7 WriteVar prefix looks like and began implementing it suggests this completion is a matter of time and developer effort, not a fundamental capability gap.
Source: https://www.darktrace.com/blog/inside-zionsiphon-darktraces-analysis-of-ot-malware-targeting-israeli-water-systems
He is a cyber security and malware researcher. He studied Computer Science and started working as a cyber security analyst in 2006. He is actively working as an cyber security investigator. He also worked for different security companies. His everyday job includes researching about new cyber security incidents. Also he has deep level of knowledge in enterprise security implementation.
