A brief guide to programmable logic controllers. Searching for vulnerabilities in industrial PLC devices

Many users believe that controllers installed in buildings and factories are protected better than home gadgets. They are wrong. Today, I will show you how to hack programmable logic controllers using a Linux-based computer. A Linx-150 automation server will be used as an example. You can use this method as a hacking guide for other similar pieces of equipment.

Time moves on, and integration is rapidly developing. Just a few years back, KNX was a de facto standard in automation of data terminal equipment (i.e. switches, sensors, detectors, etc.). Today, KNX is used not only at the field level, but at the automation level as well.

There are many useful articles dedicated to the reverse engineering of IoT devices and IP cameras. In my humble opinion, there is no difference between the above appliances and industrial control systems (ICS) from the reverse engineering perspective except for the price and potential attack consequences. It is one thing to throw a surprise sound-and-light show in somebody’s home, but it is an entirely different thing to do so in an airport.

WARNING

This is a purely research article intended for cybersecurity experts. Neither the Editorial Board nor the author can be held liable for any possible damages inflicted using information provided in it.

Meet Loytec Linx-150, the device we are going to hack today. The Hacker is thankful to Dmitri Viktorov of Sensormatica, St. Petersburg, Russia, who has provided the device for testing.


Where should I start? It might seem trivial, but first of all, I’ll visit the official website to get some basic information about the device. The first surprise: this is a discontinued model.

However, searching through the site, I found the page shown below. It contains various manuals, datasheets, and most importantly, software.


A file whose name includes the word “firmware” has attracted my attention. Bingo! It contains embedded software for a number of devices.


To the vendor’s credit, even though Linx-150 has been long discontinued, a fairly recent firmware is available. At the time of the writing, the latest version was 6.4.10 (dated May 24, 2019). In other words, the device is not available for sale anymore but actively supported, which implies that it is still widely used.

To check my suggestion, let’s visit Shodan, Zoomeye, and Censys to see how many Linx-150 and other Loytec devices can be accessed online. After all, what is the point in hacking an obsolete controller that nobody uses anymore?

Below are a few screenshots indicating that plenty of Loytec devices are still in active use:




While taking screenshots, I found another device with the same default logon credentials.


In the meantime, the firmware archive has been downloaded. We need the file linx_at91_6_4_10_20190524_0940.dl.

Perhaps, your first reaction is: what is this .dl file and how to deal with it? Binwalk will help us to uncover what is inside. To unpack the contents, use the -e key.

$ binwalk -e linx_at91_6_4_6_20190213_1030.dl

Upon unpacking, it turns out that the mysterious .dl is just an archive with .deb packages.


Initially, I had dealt with the firmware version 6.4.6, but by the time of the writing, version 6.4.10 has already been released; so, I am going to address the features bugs present in both versions. Especially taking that version 6.4.10 is still very far from perfection.

The only difference between versions 6.4.6 and 6.4.10 is the key file linx-at91-primary_6.4.10_arm.opk.

Archive contents for versions 6.4.6 and 6.4.10

Archive contents for versions 6.4.6 and 6.4.10

I assume that your bookmarks include links to Vulners and CVE Detail (if not, fix this ASAP!). These resources will assist in our research. As you can see, both firmware versions include plenty of outdated packages.


These are just a few examples. On the one hand, we can stop our study at this point. On the other hand, why not dig deeper?

How to figure out what binaries require our attention in the first hand? Of course, I could say that this requires years of experience, intuition, and daily spiritual practices, but in fact, the clue is in plain sight: we have two firmware versions (6.4.6 and 6.4.10), and the only difference between them is the file linx-at91-primary_xxx. Another clue will be addressed later, when it comes to the web interface and SSH.

Let’s apply binwalk to these files and see what happens.


I guess you have already recognized the familiar folders and understood that the device operates on Linux. First, let’s search for lines that contain the words private and password. Yes, this sounds trivial, but we are dealing with an industrial controller; so, everything should be durable and primitive.

We enter the command shown below and review the output (see the screenshot).

$ grep -ri "private" /path/to/search


Wow! We have found two private keys: for opcua and ssl. The words password and loytec4u can be seen as well. Because I have already reviewed manuals to Linx-150, I know that loytec4u is the default login password.

What is opcua? Wikipedia claims that OPC Unified Architecture (OPC UA) is a machine-to-machine communication protocol for industrial automation developed by the OPC Foundation and differing significantly from its predecessor.

Amazing! Our private keys remain the same in different firmware versions!


I bet that the same opcua keys are used in the firmware version 6.1.2 installed on the studied Linx-150 and versions 6.4.6 and 6.4.10 downloaded from the vendor’s website. The key lighttpd is present in the versions 6.4.6 and 6.4.10. Apparently, on the device provided to me for experiments, it was removed as unnecessary.

Chances are high that the same default keys are used in other Loytec equipment. I cannot prove this but trust my intuition…

WWW

Information on lighttpd and C++ web programming is available here. Many thanks to Sailor for the link and a few exciting ideas.

If we continue searching the lines with grep looking for default password, we will see the familiar file linx_at91_primary.exe. Obviously, this file is the primary candidate for reverse engineering.

In addition, I recommend using the command hardening-check elf_file_to_check that checks the ELF for security functions. More details are available in the manual.


Here you can see that GCC flags reducing the risks of binary vulnerabilities were not applied during the compilation.

WWW

More details on GCC parameters and how can they enhance security are available on RED HAT DEVELOPER and in an overview published on GitHub by relo.

Because so far we have been using standard Linux commands, let’s see what else they can retrieve from the firmware.

$file name_file


$ readelf -l name_file



It becomes clear that the code quality is inconsistent even with the minimum security requirements; for instance, the stack has the execute attribute. It is necessary to keep in mind that such devices are installed on industrial objects, and their failure may result in significant damages.

The next place of interest is the folder /etc/init.d. Here you can see a file named S35firewall and containing firewall rules. The analysis of this file and other folders shows that there are no rules that can block a trivial brute force or DDoS attack. Neither Fail2Ban nor SSHGuard are present in all the examined firmware versions (i.e. 6.1.2, 6.4.6, and 6.4.10). In other words, there are computing resources in place, but the vendor was too lazy to use them.

Now it is time to analyze the threats related to the web interface. Because we examine an actual device, it is possible to connect to it via SSH and look what ports are open from the inside.

$ netstat -ntulp


Earlier, I had mentioned another clue that can be used to identify important binary files as candidates for reverse engineering. Let’s launch the top command and see its output.


As you can see, the process consuming the most CPU power pertains to the above-mentioned file linx_at91_primary.exe.

I open the web interface and see that the main page provides enough information for a novice hacker even without authentication.


I can see the running firmware version and the version the device can be reverted to (Fallback column), device configuration, its network settings, and other useful info. For instance, the USB port is disabled, while KNXnet/IP, BACnet/IP, SNMP, and other protocols are enabled.

INFO

In one of the chats dedicated the ICS security, I encountered an excellent expansion of the abbreviation SNMP: Security Not My Problem.

To get full access, I log in using the default password, and voila!. Now I can do whatever I want. It was established empirically that the minimum password length is… one character!

The maximum password length is 15 characters, including special characters and punctuation. Still, taking that there is no protection against brute force attacks, even a long and sophisticated password can be cracked over time.

Note that HTTP, FTP, and other insecure protocols are used for communication with this device, which does not enhance its security at all.

To identify the possible vectors for web attacks, you can use OWASP ZAP or, for instance, Burp Suite.

If an attacker gains direct access to the device, an additional attack vector becomes available. There is only one knob on it, but it has enormous powers!


Turning the knob, tweaking the settings.



Apparently, the device is supposed to be kept in a physically secure location protecting it against direct attacks.

Finally, a few words about the reverse engineering of linx_at91_primary. We have located this ELF while searching the lines for loytec4u for a reason: the vendor decided to hardcode the default credentials right in the binary file!


Using a debugger, I easily locate two functions responsible for firmware updates.


By the way, I strongly recommend to search for a ‘differential diagnosis’, i.e. use IDA Pro, Ghidra, and Radare2 at once. In many cases, one of the utilities returns better results in relation to a certain function or code section in the same binary file.

The analysis of the firmware_update_from_file function shows that no real integrity or authenticity checks are performed. Aside from this file, there are some other candidates for reverse engineering as well.


Personally, I am very interested in knxstack-xx and atmega_prog, but their analysis goes beyond the scope of this article.

I am not going to complain here about the disastrous state of industrial security. Instead, I will write a short cheat sheet; it will assist you in remote searches for bugs in unknown equipment:

  • dmesg
  • df -h
  • ps ax
  • ls -l /dev/
  • lsmod
  • uname -a
  • cat /proc/cpuinfo
  • lsof
  • lsusb

I hope you now have some understanding of the theory. Below are a few places where you can polish your practical reverse engineering and pentesting skills:

Good luck!


Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>