Passerby A · 2016/04/05 17:33

0 x00 profile


This paper mainly from the industrial control network necessary component PLC (programmable logic controller), expounds the realization of a new backdoor. This paper is written by BLACK HAT’s Scadacs team at Freundice Upper Berlin 2015. Internet- Facing PLCs – A New Back Orifice. I will filter out the word count part of their paper and add some specific techniques and materials for implementation to the core ideas they give.

Do not understand industrial safety buddies can go to this article to fill the basic knowledge of industrial safety entry analysis.

The following sections are some background and basic knowledge, if you have a good understanding of PLC industrial control security, you can directly jump to the attack description (0x03) section.

0 x01 introduction


In this paper, we study how attackers access deep industrial networks through public NETWORK PLC.

The method we take is to turn PLC into a gateway (this article adopts Siemens series PLC related technology and characteristics), this method is feasible in the lack of appropriate authority authentication means of PLC. Experienced attackers with access to a PLC can upload or download code to it, as long as the code is composed of MC7 bytecode, which is the native code form of PLC. We looked at PLCS in the runtime environment and found that many network services could be implemented by uploading MC7 code. In particular, we implemented it

  • An SNMP scanner for Siemens PLC
  • A fully functional SOCKS proxy written for Siemens PLC

And their implementation relies entirely on STL code compiled into MC7 bytecode. Our scanners and agents can be deployed in the PLC without interrupting the running of the original program in the PLC, which can make it difficult for operations to realize that the PLC has been infected. To illustrate and analyze deep industrial network intrusions, we developed a proof-of-concept tool, PLCinject (attached to Github project address: SCADACS/PLCinject). According to our proof-of-concept, XXXXXXXX (this section is too complex, TMD, I really can’t accurate translation main meaning is running on the PLC of malicious software will allow it to increase the original code extension, if our observation of the original code and regularly after infected with malicious code program, in the running effect of the two has a statistically significant difference, However, its impact on the production process is very small, unless the operator actively monitor the flow from the PLC malicious access, otherwise it is difficult to detect in the production process). In addition, an attacker can use our method to attack an enterprise’s business network through an industrial control network. This means that network management must be alert to two-way attacks from the front and back of the business network.

I will add the code for Schneider PLC at the end of the article.

0x02 Introduction to Industrial Control System


The figure above shows a typical corporate structure that uses automation systems. The industrial control system consists of several layers. At the top is an enterprise Resource planning (ERP) system, which holds data about currently available resources and production capacity. Manufacturing execution Systems (MES) can manage multiple plants or platforms and accept tasks from ERP systems. The systems under MES are located inside the plant and monitor, control and data acquisition (SCADA) systems control the production line. They provide data on the current state of production, and they provide means of intervention. The devices that store the logic about the production process are called programmable logic controllers (PLCS). HMI displays current progress and allows operators to interact with the production process.

This article will look at attacks against PLCS.

PLC was originally only for automation control and development, in the beginning of its development, its application scenario is extremely close, can hardly with any third party outside the industry network equipment in contact, but in recent years the rapid development of Internet, and Internet of things, the emergence of intelligent hardware, begin to have exposed to the public, industrial PLC You can find PLC devices on the public network by searching for schneider or Siemens models on Seebug and Shodan. Despite this, the current PLC security is very very poor. First of all, the PLC firmware iteration update is slow, although the manufacturer may be maintained and updated, but to the industrial control network is running on the line PLC firmware update, the cost is extremely huge, a shutdown may be the entire factory stop running. Secondly, the current PLC has some relatively low access control means, but few people will take the initiative to open, because it will reduce the efficiency and stability of PLC. Therefore, in general, if a PLC is open to the public network, we can load arbitrary code into it.

In addition to the serious problem of permission control, it is possible for an attacker to use the PLC as a gateway into the production network or even the corporate Intranet. In this article, we analyze and discuss this threat vector, and we will prove that this approach is realistic and feasible. For demonstration purposes, we develop a port scanner and a SOCKS proxy running on a PLC. The scanner and agent are written using PLC’s native programming language Statement List (STL).

PLC

hardware

PLC consists of a CPU (generally with communication modules, such as industrial Ethernet, Modbus, ProFINet and so on, and some service interfaces, such as FTP, Web, Telnet and so on), and its external additional digital and analog input and output modules together (sometimes external additional special communication modules). Siemens S7-314C-2 PN/DP was used in this paper.

The execution environment

This part if you have learned the principle of computer composition will be easier to understand, this part is mainly about the PLC code execution process, with the hidden feasibility of our attack and the communication stability of the agent is closely related.

Siemens PLC runs a real-time operating system, which initializes periodic time monitoring. Then the operating system periodically performs four steps, as shown below:

In the first step, the CPU copies the output value of the process image to output the state of the module. In the second step, the CPU reads the state of the input module and updates the input values of the process image. In the third step, the user program executes a duration of 1 millisecond in the time slice. Each time slice is divided into three parts, executed sequentially: operating system, user program and communication. The number of time slices depends on the current user program. By default, the time should be no longer than 150 milliseconds, and engineers can configure different values. If the specified time runs out, the interrupt routine is invoked, and the CPU normally returns to the beginning of the cycle and restarts the cycle time monitoring.

software

We use STEP 7 to program PLC, and I use v5.5.

Refer to this article for installation step7 V5.5CN software download, emulator installation, authorization

Note that emulators require additional installation, as described above.

Engineers can use ladder diagram (LAD), functional block diagram (FBD), Structured Control Language (SCL) and statement table (STL) to program PLC. Unlike text-based SCL and assembly-like STL, the LAD and FBD languages are graphical. PLC program is divided into organization block (OB), function block (FC), function block (FB), data block (DB), system function block (SFC), system function block (SFB) and system data block (SDB) these units. OB, FC, and FB contain the actual code, while DB stores the data structure, and SDB stores the current configuration of the PLC. Memory addresses with the prefix M are used for internal data store addressing.

programming

A PLC program consists of at least one organizational block (called OB 1), which is equivalent to the main function in a C program. It will be invoked by the operating system. There are more organizational blocks for specific purposes, such as OB 100. This block is called once at PLC startup and is usually used to initialize the system.

The syntax of various programming languages will not be described again, please refer to the relevant resources.

Network protocol

In this part, although the communication process is described in detail in the original text, I will not give too much explanation, because this article mainly focuses on the compilation of malicious code.

But still want to say one more sentence, these embedded devices are usually used to cut vxWorks and other systems, I personally think, the current industrial control system penetration attack and vulnerability mining, in the firmware analysis has not been particularly in-depth, for industrial control network communication protocol attack is the most efficient means. I took a look at some of the industrial bugs on Wooyun, but it’s still web penetration, and for industrial networks, sometimes usability is even more important than confidentiality (like the Iranian nuclear explosion).

Siemens PLC uses its own S7Comm protocol to transfer blocks. This is a remote Procedure call (RPC) protocol based on TCP/IP and TCP based ISO transport services. Package packaging is shown as follows:

The protocol provides the following functions:

  • System status table request
  • Lists the available blocks
  • Read and write data
  • Block information request
  • Upload and download block
  • Transfer blocks to the file system
  • Start, close, memory initialization
  • debugging

The transferred block is structured, consisting of a header, a data part, and a tail.

See the original article for details of the transmission process. Here are just some of the known byte structures:

The tail contains information about the parameters used to invoke the function. Not all of the header and tail bytes are known, but we have identified the necessary areas to understand their contents.

This part is mainly to explain the way of malicious code injection. In fact, step 7 can be used for code injection, and even all operations of the protocol can be basically completed by Step 7. However, if we understand the structure and function of the protocol, we can write scripts to automate attacks.

0x03 Attack Description


Siemens PLC provides a system library, which contains the function of establishing any TCP/UDP connection. An attacker can use full TCP/UDP support to scan the local production network behind a public NETWORK PLC. In fact, according to my understanding, only proFINET communication can complete the TCP/UDP request, which requires that the Siemens PLC model we use must have PN, such as S7-314C-2 PN/DP used in the original text, in addition to S7-319-3 PN/DP and so on.

Thinking summary

We first download the OB1 block of PLC, and then add a CALL instruction to CALL any function we can control. In our example, this function is called FC 666. After that, OB1 after Patche, that is, FC 666 and other blocks (there may be many blocks here, such as our own WRITTEN FC blocks, background data blocks, shared data blocks and so on), will be uploaded to PLC. The following figure shows the code injection process:

At the next execution cycle, the newly uploaded program containing the attack code will be executed without any interruption of service (I don’t think so, in RUN mode there will still be an interruption, in run-p mode it will automatically execute the next cycle without interruption). This process allows an attacker to run arbitrary malicious code on the PLC. We released a tool called PLCinject with this article that automates this process. With this technique, an attacker can perform the following attack flow:

In the first step, the attacker injects an SNMP scanner, which runs with normal code on the PLC. After completing a complete SNMP scan of the local network (step 2), the attacker can download the scan results from the PLC (step 3). The attacker now has a thumbnail of the Intranet behind the public PLC. He then overflows the SNMP scanner and injects a SOCKS proxy (step 4). This allows an attacker to reach all PLCS in the local production network through a PLC acting as a proxy. In the next two sections we will illustrate the implementation of SNMP scanners and SOCKS proxies. We won’t go into the details of each operation and system call. For detailed description of these we refer to S7-300 Instruction list S7-300 CPUs and ET 200 CPUs and Siemens. (2006) System Software for S7-300/400 System And Standard Functions Volume 1/2.

The system calls used in this article are: SFC 51 “RDSYSST”, FB 65 “TCON”, FB 63 “TSEND” ,FB 64 “TRCV”, FB 67 “TU SEND”, FB 68 “TURCV”, UDT 65 “TCON_PAR”.

See Siemens. (2006) System Software for S7-300/400 System and Standard Functions Volume 1/2 for its parameters and input/output.

SNMP SCANNER

Siemens PLC cannot be used as a TCP port scanner because the TCP connection function TCON cannot be terminated until the connection is successfully established. In addition, a maximum of eight TCP connections can be run concurrently on the Siemens S7-300. Therefore, the PLC can only be used as a TCP scanner when 8 connections fail at the same time (if 8 connections fail at the same time, then the 8 connection functions cannot be disconnected and the scan cannot continue). This restriction does not apply to stateless UDP connections. This is why we use simple Network Management Protocol (SNMP) based on UDP. SNMP V1.0 was defined in RFC 1157[23] and was developed for monitoring and controlling network devices. A large number of network devices and most Siemens Simatic PLC have default support for SNMP. Siemens PLC is very active when SNMP function is enabled. By using OID 1.3.6.1.2.1.1.1 to read the BASIC SNMP System Information (sysDesc) object, Siemens PLC will send its product type, product model, hardware, and firmware version, in the form of the following SNMP response:

#!bash
Siemens, SIMATIC S7, CPU314C-2 PN/DP, 6ES7 314-6EH04-0AB0 , HW: 4, FW: V3.3.10.
Copy the code

The system description can be used to match discovered PLCS in vulnerability and EXP libraries. PLC firmware is not often patched. There are two main reasons: on the one hand, the firmware upgrade of PLC will interrupt the production process, which will cause losses; On the other hand, PLC firmware patches can lead to some product quality problems, which is intolerable to customers. That’s why the likelihood of finding a Siemens PLC device with a known vulnerability is very high. The SNMP scanner can be decomposed into the following steps:

  • Get local IP and subnet
  • Calculate the IP address segment of the subnet
  • Establishing a UDP Connection
  • Sending an SNMP Request
  • Accepting SNMP Requests
  • Store the response in a data block
  • Stop scanning and close the UDP connection

PLC programming is completely different from normal programming on the X86 system using C language, and it is easier to understand if you have learned verilog, a programming language for hardware. Each PLC program executes periodically, so he needs to store program state in state variables after each step. We will only explain SNMP scanning steps 1 through 3 here. The following figure shows a snippet of the first step, calling the RDSYSST function.

The RDSYSST function reads the internal system state table (SSL) to obtain the PLC local IP. SSL requests are usually used for diagnostics.

Here gives Siemens official website an example: read local IP

Lines 14 and 15 will stop the function if RDSYSST is busy. The following figure shows how the program calculates the first IP address and the total number of IP addresses on the local network.

This is done by bitwise AND of the PLC’s local IP AND subnet mask, which returns the starting address of the local network (lines 24-30). Now the SNMP scanner needs to know the total IP address of the subnet. Therefore, we XOR the subnet mask with 0xFFFFFFFF (lines 35-39). The result is the total number of SUBNET IP addresses. The following figure shows how to establish a UDP connection using the STL language. First we need to call the TCON method and use our TCON_PAR_SCAN DB as the background data block for this function.

In the case of UDP, the TCON function cannot establish a connection, which can only be done under TCP because, in contrast to UDP, the connection is directional. But it’s not enough to call TCON once; the join function starts when the #connect variable rises from 0 to 1 between calls. That’s why we wrote a toggle function (lines 10-11) after the join function first appeared. This will change the value of #connect from False to True after TCON is called for the first time in a cycle. When the TCON function is called in the next cycle, the rising edge signal is detected and execution begins. The next step is to send an SNMP packet based on UDP and receive the response. This is done by calling the TUSEND and TURCV functions. After that, SNMP scanning is completed and all data is stored in data blocks that can be downloaded by attackers (Step 3).

Give an example of UDP protocol exchange

The other parameters to TCON are fine, except for the CONNECT parameter, which requires a pointer argument to a DB block modeled after UDT 65. The details of UDT 65 can be found in the manual above, but it was a pain to set up the data structure manually, so I found a tool called Open Communication Wizard_v2.3.3 for setting up the TCON connection parameters

SOCKS5 PROXY

Once the attacker has discovered all the SNMP devices, including the local PLC, the next step is to connect to them. This can be achieved by using an accessible PLC as a gateway to the Intranet. To do this, we chose to implement a SOCKs5 agent on a PLC. There are two main reasons for this. First, the SOCKS protocol is lightweight and very easy to implement. In addition, all applications can use this type of proxy. Either applications natively support SOCKS, or they can use the so-called Proxifier to add SOCKS support for any application. The SOcks5 protocol was defined in RFC 1928[24]. An error-free TCP connection to a target via a proxy requires the following steps:

  • The client connects to the SOCKS server over TCP and sends a list of authentication methods it supports.
  • The server replies with a selected authentication method.
  • Select the appropriate subprotocol based on the authentication method selected.
  • The client sends a connection request with the destination IP.
  • The server establishes a connection and replies. All subsequent packets are tunnelled between the client and the destination.
  • The client closed the TCP connection. Procedure

Our implementation provides the necessary functionality to minimize, and it does not support authentication, so we skipped step 3. We also don’t support error handling. Only IPV4 addresses can be connected. Once the client connects, we expect this information to go through the following steps:

  • The authentication method provided by the client can be any information, such as 0x05 0x05(1 byte)(n bytes).
  • Server select authentication method: 0x05 0x00 (No authentication)
  • Client wants to connect to target: 0x05 0x01 0x00 0x01(4 bytes)(2 bytes)
  • Server verifies connection: 0x05 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  • The client and target can now communicate through a connection to the server.

As mentioned earlier, the PLC program is executed periodically. This is why we use a simple state machine to handle the SOCKS protocol. Therefore, we numbered each state and used a jump table to execute the corresponding code block. The diagram below:

State transitions are achieved by incrementing state codes stored in a block of data. Each state and its actions are described as follows:

Bind listener: The first time the program is started, it needs to bind and listen on SOCKS port 1080, which is done in passive mode through the system call TCON. We remain in this state until someone connects to this port. Negotiation: We wait for the client to send any messages. This is done through the TRCV function, which requires the EN_R argument to execute. See below:

Authentication: After the first message, we send a reply indicating that the client is unauthenticated. For this purpose, we use the TSEND system call. In contrast to TRCV, this function is edgewise controlled, which means that the REQ argument must change from False to True between successive calls in order to activate sending. As shown in the figure below, we switch flags and call TSEND twice on the rising edge of REQ.

Connection request: We then expect the client to send a connection setting message containing the destination IP and port number, which will be stored for the next state. Connection: We use TCON to establish a connection to the target.

Connection validation: When a connection to the target has been established, we send authentication information to the client.

Proxy: Now we just need to open the connection tunnel between the client and the target. All data received from the client using TRCV is stored in a buffer, and the TSEND function retrieves the data from it and sends it to the client. The same principle applies in the opposite direction, but we must consider that sending messages may take several cycles, so a second buffer is used to ensure that no messages are mixed or lost. TRCV error flags are used as a signal of disconnection. When this signal occurs, we send the last received data and then jump to the next state.

Reset: In this state, we use TDISCON to close all connections and reset all flag bits to their original state.

0 x04 discussion


The maximum transfer rate of this agent is about 40KB /s. If the SOCKS proxy runs alone on a PLC, the rate can be as high as 730KB/s. All network devices are directly connected to PLC through 100Mbit/s Ethernet. Finally, we tested the attack cycle described in the lab. In addition to regular communication, we verify that the DOS vulnerability CVE-2015-2177 can be exploited by implementing socks tunnel using the TSOCKS library. Successfully executed through socks tunnel using code.

Our attack has certain limits. To ensure that the PLC is always available to respond to requests, the main program execution time needs to be monitored, and the main program is terminated when the execution time is too long. The SNMP scanner or agent code we upload, together with the original program, should not exceed the maximum total execution time of 150ms. Injecting a scanner or agent is unlikely to trigger a timeout because the additional execution time at agent runtime is 1.35ms, which is much less than 150ms. In addition, timeouts can be avoided by resetting the time counter after the injector has finished executing, using the system call RE_TRIGR. The simplest way to protect against the attacks mentioned above is to keep PLC offline or use VPN instead of public network access. If this is not possible, Siemens PLC level 3 protection should be activated. This makes PLC read based on password and write protected. An attacker without the correct password cannot modify the PLC program. According to our research, this function is rarely used in practice. Another application protection mechanism is the use of firewalls to filter out suspicious packets, such as malicious access trying to reprogram a PLC.

Implementation of 0x05 on Schneider devices


Consult the Schneider UNITY PRO manual for the following technical details:

Schneider devices rely on the TCP_OPEN library for TCP communication, but this library has significant limitations. The TCP_OPEN library is not available in Unity Pro by default. The TCP OPEN library needs to be ordered with the order number TLXCDTCP50M. It can only be used after installation, and Unity Premium only supports this library. I also found that the TSX ETY 1100WS and TSX ETY 5103 are probably the only libraries that provide TCP_OPEN.

That said, there are probably very, very, very few Schneider devices in the real world that can complete TCP communication. This is also a limitation of this type of attack, which will be discussed in the conclusion.

Here are just a few of the functions that may be used. For API calls, refer to the Unity Pro manual in the EF/EFB/DFB library > TCP Open Library > Advanced section.

  • FCT_ACCEPT accepts connection requests
  • FCT_BIND binds the data channel number to the IP address and port
  • FCT_CLOSE Deletes a data channel
  • FCT_CONNECT Establishes a connection
  • FCT_LISTEN configures channels to wait for connections
  • FCT_RECEIVE retrieves available data in a data channel
  • FCT_SEND Sends data to a specified data channel
  • FCT_SOCKET Creates a new data channel

0 x06 summary


This article idea is novel, but is not very trivial, or everybody can think of, although simple idea, but after programming implementation, I personally found pit point is really too much, originally a week to finish this paper emersion, but in the end and found that dim sum is unable to do the sense of foot, after all, I as a web dog, The time frame for studying automation is too young.

Later, I personally think that the limitation of this attack method is very large. According to my investigation, PN CPU of Siemens is relatively large, but CPU of other manufacturers basically does not have complete TCP/UDP communication function, such as Schneider mentioned in the previous part.

The following is a few of my own writing in the text of the small demo, put in a project, although the implementation is incomplete and the problem is very big, but still put out for beginners to touch, but also want to let the master point out. I hope we can communicate together.

S7_pro1.zip

Use the zip archive directly in Step7 to restore it, no need to decompress.

Email ronnyschiatto#gmail.com for any questions or postures