Achieving native code execution on an industrial control system such as a programmable logic controller (PLC) is an end-goal relatively few advanced attackers have achieved. These complex systems have numerous in-memory protections that would have to be hurdled in order for an attacker to not only run code of their choice, but also remain undetected, according to Claroty.
Previous work has required physical access and connections to the PLC, or techniques that target engineering workstations and other links to the PLC in order to gain that level of code execution. Claroty, meanwhile, has taken those efforts a step further using a newly-discovered vulnerability that bypasses the PLC sandbox within Siemens’ Simatic S7-1200 and S7-1500 PLC CPUs to run native code in protected areas of memory.
Affected devices are vulnerable to a memory protection bypass through a specific operation. A remote unauthenticated attacker with network access to TCP port 102 could potentially write arbitrary data and code to protected memory areas or read sensitive data to launch further attacks.
This disclosure is an outcome of Siemens and Claroty’s existing partnership, which fosters not only tight cooperation between the research teams and the vendor on disclosures, but also in the security of the overall industrial ecosystem. Siemens has released an official advisory SSA-434534 that notifies its users of this vulnerability, and also released updates for various products, including S7-1500 and S7-1200, that remediate the vulnerability. Users are urged to update to the latest versions.
Siemens says it is preparing further updates for products where updates are not yet available; Siemens also provided specific mitigation measures that users can apply to reduce the risk. Siemens and Claroty wish to emphasise that users apply the S7-1200 and S7-1500 CPU updates as well as those for other affected products given the critical nature of this vulnerability.
PLC vulnerability research, from the attacker perspective, is to achieve unrestricted and undetected code execution on the PLC. This means, being able to hide code deep inside the PLC, undetected by the operating system, or any diagnostic software.
Over the years Siemens has seen many attempts to achieve such a capability on Siemens PLCs. First, Siemens had Stuxnet, which gained user-level code execution on the old Simatic S7-300 and S7-400 by manipulating the local Step 7 projects files. Next, Siemens witnessed the Rogue7 attack.
The researchers behind Rogue7 were able to create a rogue engineering station which can masquerade as the TIA portal to the PLC and inject any messages favourable to the attacker.
Claroty has levelled up this research, demonstrating a new remote attack that allows it to gain native code execution on Siemens S7 PLCs. The attack targets deep in the kernel and avoids any detection because it is able to escape the user sandbox and write a shellcode into protected memory regions.
The integrity of a PLC is crucial to operators and engineers, and an attacker’s goal would be to damage that integrity by hiding code on the controller and elevating privileges. In order to escape, or jailbreak, the native Simatic S7-1200 and S7-1500 sandboxes, Claroty used its memory protection bypass vulnerability. The vulnerability bypasses existing protections within the execution environment of the PLC, including a sandbox where engineering code would normally run. Claroty was able to use this vulnerability to escape the sandbox in order to gain direct access to memory, then write and inject shellcode to execute our attack on Siemens 1200/1500 PLCs.
Escaping the sandbox means an attacker would be able to read and write from anywhere on the PLC, and could patch an existing VM opcode in memory with malicious code to root the device.
Claroty, for example, was able to inject ARM/MIPS shellcode directly to an internal operating system structure in such a way that when the operating system uses a specific opcode, Claroty’s malicious shellcode would execute, giving remote code execution. Claroty used this technique to install a kernel-level program with some functionality that is completely hidden to the operating system.