Security fundamentals for embedded software
Recently, new terms like Stuxnet and Duqu have entered our lexicon. Embedded systems including those that do supervisory control and data acquisition (SCADA) are under relentless security attacks.
Many embedded software developers feel that embedded systems security should be handled at the systems-engineering level or by the hardware that surrounds their software. And indeed many things can be done at those levels, including:
• Secure network communication protocols.
• Data encryption.
• Authentication of data sources.
• Hardware-assisted control-flow monitoring.
David Kalinsky is a teacher of intensive short courses on embedded systems and software development for professional engineers. One of his popular courses is "Introduction to Software Security for Embedded." His courses are presented regularly in open-class format at technical training providers in international locations such as Munich, Singapore, Stockholm, and Tel-Aviv, as well as in his "home market" of the USA. See www.kalinskyassociates.com.
Dave Kalinsky will teach these classes at ESC/DESIGN West in March, 2012:
ESC-101: Software Design for Multicore Systems—2012 EDITION
8:00 AM to 12:00 PM, March 26
ESC-402: Is Static Code Analysis Ready for Real-time?
3:15 PM–4:15 PM, March 29
Clearly then, system-level and hardware defenses are not enough. Most security attacks are known to exploit vulnerabilities within application software. Vulnerabilities are introduced into our embedded systems during software design and development. Since system-level and hardware defenses against security attacks are far from perfect, we need to build a third line of defense by dealing with vulnerabilities in our application software.
While our software line of defense will surely be less than perfect, we need to work on that line of defense with the immediate objective of reducing the size of the "attack windows" that exist in our software. The very first step in doing this is to try to think like an attacker. Ask how an attacker could exploit your system and your software in order to penetrate it. You might call this a threat analysis. Use the results to describe what your software should not do. You might call those abuse cases. Use them to plan how to make your software better resist, tolerate or recover from attacks.
Don't forget that our attackers have a big advantage when it comes to embedded systems: Most embedded software has severe execution time constraints, often a mixture of hard real-time and soft real-time tasks. This coaxes us to design application software that is "lean and mean," by reducing to a minimum intensive run-time limit checking and reasonableness checking (for example, invariant assertions) in order to meet timing requirements. Our attackers have no such execution time constraints: They are perfectly happy to spend perhaps weeks or months researching, preparing, and running their attacks--possibly trying the same attack millions of times in the hope that one of those times it might succeed, or possibly trying a different attack each day until one hits an open "attack window."
How can attackers attack via our own software?
Quite often embedded software developers dismiss the issue of embedded software security, saying: "Hey, our device will never connect to the Internet or to any other external communication link. So we're immune to attack." Unfortunately, this is naïve and untrue. I'd like to present a counterexample:
Many embedded devices use analog-to-digital-converters (ADCs) for data acquisition. These ADCs may be sampled on a regular timed basis, and the data samples stored by application software in an array. Application software later processes the array of data. But an attacker could view this in a totally different way: "What if I fed the ADC with electrical signals that, when sampled, would be exactly the hexadecimal representation of executable code of a nasty program I could write?" In that way, the attacker could inject some of his software into your computer. No network or Internet needed.
Seems like a lot of work to build an "ADC Code Injector" device just for this purpose. But the attacker might not be just a high-school kid. He might be a big industrial espionage lab, or a large, well-funded team working at the national laboratory of a foreign government.
malloca()). If his luck is good, he could cause an array overflow, possibly by toying with the hardware timer that controls the ADC data sampling. A typical normal stack layout is shown in Figure 1.
If the attacker plans the corruption just right, the overflow will reach the location on the stack where the current return address was stored. This can be used to insert into this stack location a pointer to his own code. As a result, when "Return Address" is used by your code, control will pass to the attacker's code. Suddenly his code is executing on your processor, instead of your code.
This is called a stack smashing attack. Please note that it was done in this example without an Internet connection, and without a connection to any external communication line.
Of course, it could have been helpful for our attacker to have the source code for your embedded software--as a disgruntled ex-employee might. But I think a patient and resourceful attacker team could develop this kind of attack even without your source code.
Can you think of an easier way for an attacker to develop an attack on your current project?