This work, and slightly edited blog post, is from a new Project Basecamp researcher that prefers to remain behind the scenes. We welcome any researchers to join the Basecamp team.
One of the most interesting “products” in Project Basecamp was CoDeSys, because this runtime library is used literally by hundreds of vendors. In fact, most users probably don’t even know that their PLC is running CoDeSys libraries. The CoDeSys password mechanism was found to only be effective if you used their GUI. Of course an attacker could easily access the PLC directly via the command line or ftp with no password required. The vendor (3S) claimed:
In general, we do not offer any standard tools in CODESYS which are to protect the controller from a serious cyber attack. Should the offered password functionality suggest such a protection, this was definitely not our intention.
This is proving to be true for the protection of 3S and their OEM customers’ intellectual property.
When a vendor is using CoDeSys as his IEC61131-3 runtime, there is not a lot of room to distinguish your product from all the others using CoDeSys too. However, one way is vendor specific libraries. These are essentially CoDeSys programs with specific functions or function blocks, but with the file extension .lib. Those libraries can be imported into any normal user program.
Say a user wants to have his PLC program get a configuration file from an FTP server. The vendor may provide a library with an FTP_Client function block that can be imported and just used instead of the user having to write all the tedious socket handling.
Now as a vendor, these libraries are essentially intellectual property and should be protected as such. CoDeSys with it’s software history has loads of options to do this:
Now “encrypted internal library” sounds like what we want. Unfortunately, to import an encrypted library, you have to provide the encryption key and thus essentially provide the decryption to customers. So the way to go (and most vendors, including 3S themsel ves, choose this path) is to use an internal library and protect it with a project password:
When a password is entered there, the saved library will still be importable with the library manager, but when you try to open it directly with CoDeSys, a password prompt is shown:
When the library is copied to another computer, the prompt still shows when trying to open it and the password is still checked correctly, so that means the password has to be inside the .lib file.
Once you take a look at a file comparison of a password protected .lib and a clean one, it’s almost immediately clear, how the “encryption” works:
Small side note here: this knowledge is apparently not new. When searching the web for things like “codesys library decrypt” you will find that users in Russian PLC forums already have the knowledge to “unPassword” codesys libraries. There even is some Chinese allround software that can find the passwords for libraries and generate keys for Beckhoff’s TwinCAT software.
So just by looking at the password protected version of the library, I saw the algorithm to “decrypt” it, threw together a python script to do it and did an extensive internet search for publicly downloadable codesys libraries once the script worked. Downloaded all of them and let my python script run against all of them.
I found 489 unique codesys libraries as public downloads on the Internet. 323 (66%) of those libraries were not protected at all. So either the content was not supposed to be protected from view by the customer or the vendor did not know how to do it. This left 166 (34%) of all libraries I found to be protected by a password, so those vendors did care about their intellectual property.
Of the 166 passwords I found:
- 31 were unique
- 22 chars was the longest
- 3 chars the shortest
- 19.77% is the average password strength (measured by www.passwordstrength.com)
The passwords themselves are not that creative with “HELLO” being the bottom of the pit. I can just imagine the snickering developers, when entering their library password “rc3sexpert”. But the funniest one was when the library literally talked to me, with “youthief” as its password.
So what does all this mean?
Well, once again vendors trusted 3S in providing them with a safe and sound product and were betrayed. Now all that precious intellectual property hiding inside the “protected” libraries is basically public knowledge.
This time around, they will also not be able to claim that the password was never intended as a protection mechanism as they did last time.
This excuse will not work since they used the mechanism for their own IP in the CANopen Stack libraries, “protected” by the password “STACK3S”.
What now?
Well, this was all done using the old version of CoDeSys (V2.3.x), not the V3. But I’m not sure the library protection is any better with the new version. So go ask 3S for better protection of your intellectual proptery in upcoming versions. Also, it is always wise to really check the integrity of a third-party mechanism that you will trust your IP with…
And finally, there are quite some vendors I could not obtain all/any libraries from. e.g. Beckhoff has an army of libraries as extension for TwinCAT from “Building Automation” to “Communication” to “Motion”. All of those are downloadable but require a license key (and I did not intend to use the chinese software to get one). You can still try one of the following passwords or just find out how the encraption works by yourself.
Password List:
- 103
- 463
- 583
- 589
- 6020
- 613613
- 91513967
- ANWMODUL
- ARBOGNE
- Enercon
- EXOR_MODBUSTCPSRV
- H2OLA
- HELLO
- L-force
- LIZZY
- MDP211PLC
- MOELLER6020
- PASSWORDFORTCTWINSAFE
- PDMA1
- PLA1
- POLAR BEAR
- PRO502
- PRO503
- RAIDCNTLR
- RALF
- rc3sexpert
- schneetiger11
- STACK3S
- SYSTEMCXXXXX
- youthief
- ZAPPADERMEISTER
Image by Mike Rohde