By Isiah Jones, Director & Principal ICS Cyber Security Engineering & Brian Foster, Senior ICS Cyber Security Engineer
Within the industrial control systems (ICS), automation, operational technology (OT), cyber-physical systems (CPS), industrial internet of things (IIoT) and instrumentation communities many of the devices with some form of computing and logical capabilities rely on 5 primary programming languages specific to programmable logic controllers (PLCs) that are defined in IEC 61131-3 as Sequential Function Chart (SFC), Ladder Diagram aka Ladder Logic (LD), Function Block Diagram (FBD), Instruction List (IL) and Structure Text (ST). In the IT community OWASP, NIST, SANS, CMMI, ISC2 and EC-Council, among others, have already created secure coding and secure development guidelines, best practices, testing tools and tips for higher level languages such as C, C++, Java, Python, JSON, HTML, XML, SQL and others. Some could argue that Structure Text includes several of these high-level languages. However, there has not been much focus by international standards organizations or industry experts on implementing security within the other 4 primary PLC focused languages in ICS. As a result, we wanted to share some of our recommendations for each of the IEC 61131-3 PLC languages in a 5-part blog series and aggregated white paper. This series will include a list of recommended practices and tips for each language that we believe should eventually become an accepted best practices guide or even long-term an international standard within the automation and control systems communities. This will continue to create innovative ways to decrease the effectiveness of attacks targeting ICS protocols, devices, applications, other assets, and operations by decreasing the potential consequences and impacts that are unique to ICS.
Sequential Function Chart (SFC)
Sequential Function Chart is a graphical representation of logical steps executed in order. The path of processing these steps is determined by the development of transitions between steps. Logic can progress in a straight line from one step to the next or diverge based on any number of conditions into different paths, parallel paths, or jump around to different parts of the chart. SFC is best used for programming state machines. State machines are chunks of logical code which can be in one state or another, never one state and another. Each step or parallel step of a SFC program is a state.
SFC is an easy logic language to learn and use, however that comes at a computational overhead cost. Compared to some of the other common Logic Languages SFC requires more processing resources to execute. For this reason, it is not found in all PLC platforms, particularly those from older generations of equipment. Still, it is a commonly used language in much of the world. It is also often used on paper to convey the operation of a PLC (which may be programmed in another language) to interested parties.
Within SFC we believe the following recommended practices would improve the secure design and usage of SFC within ICS devices by adding security, safety and resilience supportive concepts within the SFC code for all devices and operations that operate using SFC. These recommended practices are in no particular order and this is not an all-inclusive list.
- In loops and transitions, you could include logic that checks for unsafe states based on inputs and outputs before allowing the next action in your charts to execute.
- When doing parallels in SFC insert actions, transitions and other logic points to verify logical requirements to ensure changes to registers, tags, set points, query scripts etcetera do not actually execute if an attacker sends commands via vulnerabilities in protocols like DNP3 and Modbus for example.
- Build recover logic. This is basically a routine that gets called in the event that the logic hangs or the controller crashes. It can do various things, from simple restarts to isolating bad code and running the logic around it, through dropping a backup copy of logic onto the controller then rebooting it. Not all PLCs support this functionality, but most mainstream ones do.
- Comment everything with detailed comments. Not only does this help with troubleshooting and future code development, it makes code that is not commented stand out. The bad guys may not comment the bad code at all, or they may do a really poor job (language barriers or in a hurry). In a well-commented program, commented bits stick out.
- Create Jumps to safe process shutdown charts that leverage actions and transitions to flag and evaluate unsafe inputs and outputs or invalid data results from queries. This forces the SFC flows to execute safe logic when unsafe conditions occur within code logic.
- Use the Enclosing element to create groups of logic checking charts that can be used to create a reusable logic checking the library of prebuilt charts that should be inserted into all code during system design, integration, FAT, SAT, Commissioning and tested during any logic changes in production.
- Leverage timers and authorization checks within action and transition elements to track and log changes to charts by data inputs, outputs from devices, tasks, and human users. This enables an extra layer of security in the charts for key critical logic decision points to be protected from being changed to unsafe or unexpected states by malicious or accidental insiders or correct processes and data from other devices.
- Develop meaningful chart scope and variable nomenclature that does not easily give away specific details about locations, logic, and purpose of devices to outsiders but is easily known and remembered by internal personnel for ease of consistent operations. This ensures that in the event of compromise external attackers will have to spend additional time understanding the chart variables to determine which parts of the charts to target to create true consequences and impacts both without being detected and or that cause sabotage states or undesirable conditions.
- Test, demo, simulate, run and validate all charts for SFC rule violations, logic errors and design flaws or hanging elements etcetera prior to deployment into production on all projects.
- Keep operational PLCs in run mode. This prohibits changes to the logic. It is often only changeable with physical access to the PLC. While this cannot prevent flaws in the code from being exploited it will stop the changing of the code by anyone who does not have physical access to the PLC.
We know there are many more possible best practices and recommendations that experienced individuals within the community can come up with. We wanted to be part of increasing the conversation for the creation of some formalized and well documented best practices guidelines for each of the 5 IEC 61131-3 PLC languages. Part 2 of this series will focus on Ladder Diagram also known as Ladder Logic. We encourage our global multisector community of automation and control systems creators, installers, integrators, regulators, international standards organizations, testing labs, safety and risk assessors, penetration testers and end users to think of and enforce the implementation of more recommended practices to increase our level of due diligence in our attempts to improve the assurance levels of infrastructures the public depends on for daily life.