Video Screencast Help
Symantec to Separate Into Two Focused, Industry-Leading Technology Companies. Learn more.
Security Response

Detecting PLC Infections

Created: 08 Oct 2010 21:16:56 GMT • Updated: 23 Jan 2014 18:24:36 GMT • Translations available: 日本語
Nicolas Falliere's picture
+3 3 Votes
Login to vote

In this blog, I’m going to provide extra details about the PLC infection process and how an operator can determine if their PLC is infected.   

First, recall that Stuxnet’s end-goal is the infection of particular types of Simatic PLCs. In order to achieve this goal, a Simatic DLL is replaced and acts as a proxy between the Programming Environment and the PLC devices. That DLL is able to do the following:

  • monitor communication between the PLC and the Programming Environment
  • infect PLCs
  • mask potential PLC infections

A sequence consists of malicious blocks as well as infection stubs for already existing PLC blocks; Stuxnet contains two types of sequences.

Sequences A & B

The first type consists of two sequences, A and B. Each contain about 20 blocks, and specifically target PLC 315-2 by having specific system data blocks. See the Dossier for more information. These sequences are meant to monitor Profibus frames, and in turn can craft and inject frames on the Profibus network.

This sequence is composed of the following:

  • static blocks
    • DB888 through DB891
    • FC1865 through FC1868, FC1870, FC1871, FC1873, FC1874, FC1876 through 1880
    • A malicious DP_RECV block
  • dynamic blocks
    • FC1869 (copy of original DP_RECV)
  • infected blocks
    • OB1, OB35

Fig. 1: Flowchart of sequences A/B

In order to quickly determine if a PLC is infected by sequences A or B, launch the Simatic manager in a clean environment and examine blocks OB1 and OB35. The infected OB1 starts with the following instructions, meant to start the infection sequence and potentially short-circuit OB1 execution on specific conditions:

UC    FC1865
POP
L     DW#16#DEADF007
==D
BEC
L     DW#16#0
L     DW#16#0

The infected OB35 starts with the following instructions, meant to short-circuit OB35 on specific conditions:

UC    FC1874
POP
L     DW#16#DEADF007
==D
BEC
L     DW#16#0
L     DW#16#0

Sequence C

Although present in both variants of Stuxnet, analysis shows that this sequence should not be written onto a PLC because of an exception generated in a critical code location.

Either the code was not completed or it was partially commented out, such that the bulk of the original code remains and is no longer called. It targets PLCs of type 417. It is meant to read and write I/O (Input/Output) information to the memory-mapped I/O areas of the PLC, as well as the peripheral I/O.

This sequence is composed of the following:

  • static blocks
    • DB8062, DB8063
    • FC6055 through FC6084
    • OB80 (if not exist)
  • dynamic blocks
    • DB8061
    • DB8064 through DB8070
  • infected blocks
    • OB1
    • SDB0, SDB4 (modified)

Fig. 2: Flowchart of sequence C

Contrary to sequences A and B, whose infection is controlled by a separate thread, the infection here is triggered when a block of type OB, DB, FC, or FB is written to the PLC through the ‘s7blk_write()’ API call.

It seems DB8061 could be generated based on the existing SDB7, which Stuxnet expects to find on the targeted PLC. However details are unclear, as the code appears unfinished or partially removed. Incidentally, this could explain the use of OB80, the timing error handler. The use of sequence C may not have given expected results and thus was disabled. If this hypothesis is true, why it’s been left in the code is unknown.

SDB0 is expected to contain records. The block is parsed and a static 10-byte long record is inserted in the block. However, contrary to what happens with sequences A and B, no specific values are searched in the block. Moreover, record 13 of SDB0 can be modified.

The creation timestamp of SDB0 is incremented, and this timestamp is replicated to a specific location in SDB4, for consistency. Sequence C is written and Stuxnet also makes sure an OB80 exists, or else creates an empty one.

Now, technical explanation aside, notice that very few fingerprinting checks seem to happen here, which is worrisome. Contrary to sequences A and B, which heavily check SDB blocks in search of specific constants, sequence C could be written with very few checks except to ensure that SDB0, SDB4, and SDB7 must exist. However, as stated earlier, it seems that the code that manages this sequence has been disabled.

In a worst-case scenario, if a PLC were to be infected with sequence C, the OB1 block would start with the following instruction:

UC    FC6083

Detection and remediation for Windows components of Stuxnet are reliable and have been in place for several months now. However, detecting and cleaning an infected PLC requires additional steps. First, the Stuxnet Windows binaries must be removed before one can examine their PLCs for the key elements of the Stuxnet payload:

  • Sequences A and B target only the PLC of type 315-2. For this type, OB1 and OB35 are infected.
  • Sequence C targets the PLC of type 417. For this type, OB1 is infected; however, this sequence appears to be disabled.