Chances are, you own more Arm technology than any other compute architecture. I do: from my router to my smartphone, smartwatch to the entertainment system in my car.
In a relatively short amount of time, Arm has moved into every corner of the market, from low-power Internet of things (IoT) devices through edge servers right up to supercomputers. But with this comes a greater responsibility to keep these devices secure: the more ubiquitous Arm technology becomes, the more malicious actors will look to exploit Arm-powered devices.
It’s for that reason that I’ve been working alongside Arm to provide developers with in-depth knowledge of how to ensure the code they write is as secure as possible. Your device is only as strong as your weakest link and a single vulnerability could compromise an entire network. As our homes are connected via multiple IoT devices, it’s more important than ever that attackers can’t gain access to our lives through under-protected devices. Businesses, too, need to know that the IoT hardware they choose will not leave their internal networks open to attack from those looking to exploit it.
The great news for developers is that Arm has a robust set of countermeasures that software developers can use to ensure Arm hardware, Arm compilers and operating systems on Arm remain as resilient as possible to those looking to use known exploits to compromise device security.
That resilience comes in the form of Arm exploit mitigation, and many of the techniques involved are just a couple of command-line options in a build script away. For just a small amount of effort, device manufacturers can put Arm exploit mitigations to good use and help protect the billions of new devices entering the field.
Deploying Arm exploit mitigation techniques
I initially built the Azeria Labs blog around providing security researchers with resources to get started with low-level (binary-level) research on IoT devices in order to identify vulnerabilities. Over time, I realized that vulnerabilities in IoT devices are not the only problem: The lack of security features enabled in modern IoT devices remains a big issue.
Given how accessible and important these mitigations are, you might think that these defences would be widely enabled, but sadly that’s far from the truth. Even popular, major-brand consumer and IoT devices often don’t implement basic and widely known Arm exploit mitigations that have existed for many years.
In 2018, Cisco’s Talos cybersecurity division identified 20 vulnerabilities in a leading manufacturer’s smart home hub. Any one of these vulnerabilities could have given a hacker control over the devices connected to the hub, from home cameras to smart locks, thermostats to home alarm systems.
It’s for this reason that I’ve been working with Arm to educate developers in how Arm exploit mitigation works, what they protect against, how they can be enabled on Arm devices and the importance of combining them. More on that later—first, let’s look at what a vulnerability is, and how a malicious actor might exploit it.
Vulnerabilities take many forms. Many are based on unsafe functions that have been known to be vulnerable for quite some time. One example is the C function strcpy(). This function copies a string from one location in memory to another. However, it has a vulnerability: if the string provided by an attacker is larger than the destination buffer it’s being copied to, then boom—a buffer overflow occurs, and the attacker can take over the program flow. Strcpy() was one of the 20 vulnerabilities identified in the smart home hub I mentioned above.
Memory corruption: A key tool in a hacker’s inventory
Buffer overflows belong to a family of software defects called memory corruption vulnerabilities, and they’re nothing new: the Morris Worm back in 1988 is one of the earliest examples of a memory buffer being exploited. Sadly, memory corruptions haven’t gone away in the 30+ years since. The recent WannaCry global ransomware attacks, for example, were due to a memory-corruption vulnerability in SMB, the protocol used to share files and devices on a network.
Hackers use memory-corruption vulnerabilities to build exploits that can be used to take control of the vulnerable device. Having gained entry, the hacker can elevate their privileges and gain full control of the device. They can extract sensitive data, install ransomware, install persistent spyware on the device, pivot and attack a connected company network or enrol the device in a global botnet to attack other sites, as happened during the Mirai denial-of-service (DDoS) attacks that attacked Dyn in 2016, briefly taking Amazon, PayPal, Netflix and Twitter offline.
Eliminating vulnerabilities: Hard, but not impossible
It’s tempting to say that the solution to these problems is for developers to just take more care to never write vulnerable code. Unfortunately, this is easier said than done due to old codebases and third-party components consisting of millions of lines of code.
And mistakes can still happen if a developer replaces an unsafe function with a safer version but implements that fix incorrectly. For example, if strcpy is replaced with the safer strlcpy function—which keeps track of the destination buffer’s size via a size parameter—yet that parameter can be specified incorrectly. A single mistake can bring the whole house of cards back down.
While eliminating all memory corruption vulnerabilities from software is undoubtedly hard, all hope is not lost. There are tools and techniques that make it much harder for attackers to exploit these vulnerabilities.
Arm exploit mitigations make the hack harder
Arm exploit mitigations are implemented at the compiler, processor, and operating system level, and although they don’t eliminate the vulnerability itself, they can drastically increase the difficulty of exploiting many categories of software vulnerabilities.
For example, the “address space layout randomization” (ASLR) mitigation randomizes the position of key code and data in a device’s memory in order to make the addresses of components that an attacker might use to build an exploit less predictable.
In isolation, each mitigation only makes exploitation a little harder. When combined, the overall difficulty of exploitation of memory-corruption vulnerabilities dramatically increases, forcing attackers to be far more creative or find more bugs to successfully exploit the vulnerabilities they find.
In some cases, combining them is a must: Arm’s “Execute Never” (XN) exploit mitigation, for example, prevents the most trivial exploitation techniques hackers have been using for decades by enabling memory regions to be tagged as not containing executable code.
It’s widely used, but, unfortunately, hackers have since come up with techniques to reliably bypass it. However, by combining it with other Arm exploit mitigations it can still be a useful tool against attacks.
Over to you, developers
Developers can’t all be self-taught security experts, and we shouldn’t expect them to be. It’s important to consider the time and budget constraints many developers face to remain competitive. The problem is that many companies focus on functionality, treating the implementation of security features as a development afterthought.
Over the years I’ve spoken to many developers who are unaware of the existence and purpose of Arm exploit mitigation techniques or haven’t considered the significant risks their devices stand to expose corporate networks and households to—and the resulting fallout for their companies should their new device be exploited into becoming part of next year’s biggest botnet. Others are concerned about the potential performance impact.
Many mitigation techniques incur a negligible overhead. There are always outliers, of course: the mitigations in one of the Spectre patches had quite severe performance costs. But most security features are optimized to limit performance impact and drastically raise the bar for buffer-overflow and related exploit categories. Examples include ASLR and the return address signing in Arm’s Pointer Authentication which has an overhead of less than 0.5 percent.
For developers unsure of how and what Arm exploit mitigations they can and should enable, a good place to start is PSA Certified. It’s a framework created by Arm (and based on the Platform Security Architecture) that guides developers through the complex world of security design, identifying threats to a system, recommending and describing which countermeasures to implement, and independently evaluating the implementation. For example, it specifies that software security measures must isolate the security firmware and private information from the rest of the application.
While the focus of my business at Azeria Labs is consulting and providing reverse engineering and security-related training to tech companies and governments, I regularly volunteer to give workshops to developers who want to learn about vulnerabilities and Arm exploit mitigations.
I’m also aware that there are many who can’t attend my workshops. My upcoming book series will provide both security researchers and developers with an in-depth understanding of Arm assembly internals for binary analysis, vulnerability analysis, and Arm exploit mitigations.