Shortly after Rubén’s vulnerability announcement concerning their Modicon Quantum line of controllers, Schneider Electric released updated firmware for their various controller’s Ethernet cards, as well as an advisory (I sarcastically love the combination of “we take security very seriously” and “hard-coded backdoor credentials”). The partial fixes are incorporated into version 5.01 of their firmware for our NOE 771 01 module, which was shown in Basecamp.
The fix is rather sad. It disables the Telnet and WindRiver debug service issues, but leaves backdoor accounts and an FTP server enabled. The WindRiver debug port is fairly well-known (Dillon Beresford wrote up some nifty documentation on automating WDB agent attacks, including showing how to remotely alter how a controller boots by using the service to overwrite the bootline). The WindRiver Telnet service is quite a bit less-known.
The telnet service is really a C interpreter. Fermi National Labs has a nifty intro to it here. Because Schneider left debugging symbols in the Quantum line of controllers, it’s incredibly easy to use the C shell: you get function names. You can type commands like ‘strlen(“foo”)’ and the shell will return 3. On systems which lack debugging symbols, you’re left having to reverse engineer the firmware to find the function location, and then calling the function by using the pointer. For example, suppose that the strlen() function was found to begin at offset 0x0016fc18 in the disassembly:
value = 3 = 0x3
It’s pretty interesting because the command line is totally type-free C. You can treat any spot in memory as a function without having to cast it. Even if your target lacks debugging symbols, that’s okay: you can do assignments on the command-line to make your life easier and make your code cleaner. This works for both function names and your own declared variables:
-> foolen = 0x0016fc18(“foo”)
foolen = 0xa0c6b8: value = 3 = 0x3
foolen = 0xa0c6b8: value = 3 = 0x3
-> d 0xa0c6b8
00a0c6b0: 0000 0003 eeee eeee * ……*
You can use the Telnet console for a lot more evil things, too, of course. vxWorks includes a full bsd sockets library, meaning that you can write a C program to run as a port scanner from the telnet console. Kinda cool. The syntax is quite clunky on the Schneider…while the device has debugging symbols, you lack the ability to use C data structures by name. You have to do things the old-fashioned and painful way: make a socket structure in memory by malloc()’ing bytes, filling in the socket structure by hand, and then calling the C connect() function.
The upgraded firmware does remove the Telnet service. In my opinion, it’s not even worth upgrading the firmware yet though. While it does lower your risk ever-so-slightly, all that it really succeeds in doing is providing a false sense of security. An attacker that spends 20 minutes with the controller will learn that the firmware may be downgraded using the still-present FTP server and backdoors. The firmware image is simply a file that can be overwritten using FTP access. It also doesn’t fix the issues that our Metasploit module exploits, which just uses these two issues to grab user accounts for the system’s other services.
There are plenty of nice projects surrounding vxWorks now, including a vxWorks rootkit complete with a portscanner and other fun network penetrating tools. The HP rootkit was hand-coded in ARM assembler, but a port to PowerPC would be trivial. Schneider would be such an easy target because of their inclusion of debugging symbols with the firmware image. Very little reverse-engineering is needed to find the functions for changing a Quantum into a weapon.
Image by fireflythegreat