What is Alkemist®?
RunSafe Security’s Alkemist is a software-based transformation engine that applies memory protections directly into code, enabling that code to protect itself from memory corruption vulnerabilities without altering the functionality of the code. Alkemist Load-time Function Randomization (LFR) randomizes the memory address for each function, making reliable exploitation nearly impossible for an attacker.
Low-overhead Alkemist LFR has an imperceptible effect on program initialization and runtime performance. When using the SPEC CPU2006 test suite, Alkemist LFR adds less than a 1% overhead to most of the benchmark running times. This percentage drops even lower when Alkemist LFR is applied to long-running services/daemons.
Load-time randomization Binaries built with Alkemist LFR are randomized when loaded into main memory. This means that protected programs can be distributed just like traditional programs and can use the same checksum and signature tools too.
Easy to use No changes to build tools or processes are required. In most cases, using Alkemist LFR is as easy as prepending our helper script to the beginning of your build command or deploying one of the applications pre-hardened by RunSafe in our ESP offering.
How it Works
The figure below shows the evolution of memory layouts in programs over time. On the left is the memory layout representative of a program built in the late 90s. Each time a program was executed, or library loaded, the memory addresses of each program were the same. In the early 2000s Linux adopted Address Space Layout Randomization (ASLR). ASLR randomizes the base address of a program each time it is executed, but has an inherent weakness in that the whole program is moved as one unit. Introduction of ASLR made exploitation of memory corruption vulnerabilities more difficult, but ASLR can be defeated easily by one information leak. Alkemist LFR improves upon the ASLR concept by randomizing each function within a program.
An important aspect of Alkemist LFR is that while functions move around in memory, the functionality of the program stays identical. One way to assess functionality is to look at the call graph of a program. Let’s consider a simple program with five functions with a call graph shown in the left of the figure below. The call graph would read: Function 1 calls Function 3, Function 3 calls Function 2, Function 2 calls Function 4, and Function 4 calls Function 5. For simplicity’s sake, consider all functions to be contiguous in memory in the order shown in the figure. On the right is the same program, with the same five functions, after the program is executed and Alkemist LFR randomizes the functions in memory. You will see that while the functions are not in the same location, the call graph is the same.
By building Alkemist LFR into your software, you deprive the attacker the ability to reliably exploit your software because the code they need to execute is never in the same place twice. Additionally, any failed attempts to exploit Alkemist LFR-protected software result in the program crashing. When the software is launched again, any information an attacker could gain from the previous failed exploit attempt would not be useful because the program will have been randomized again.
As mentioned above, Alkemist LFR allows you to continue using your existing compiler and linker. We accomplish this by sitting in front of the linker, making the modifications needed, and then calling your linker. This process can be seen in the figure below. The top path through the process is what a normal build looks like, abstracting away the infinite complexities that build systems bring. Alkemist LFR has been proven to work with builds as simple as a “Hello, World” example built with GCC all the way to a complex Yocto-based build using different compilers per project. With Alkemist LFR in the mix, compilation takes a slightly different path at the linking stage, where we inject information needed to accomplish our runtime randomization.
Integration is as simple as downloading Alkemist LFR then prepending a call to our helper script when you build. Head to the Deployment Guide to see examples then and start your free trial today!