Good code, bad computations: A computer security vulnerability

strung together in order to build malicious programs need to end with a return command. The graduate students showed that the process of building these malicious programs from good code can be largely automated by grouping sets of instructions into “gadgets” and then abstracting much of the tedious work behind a programming language and compiler.

To understand how return-oriented programming works, imagine taking a 700-page book, picking and choosing words and phrases in no particular order, and then assembling these random chosen words and phrases into a 50-page story that has nothing to do with the original book (although every word and every phrase in the 50-page book were taken from the original 700-page one). Return-oriented programming allows you to do something similar. Here the 700 page book is the code that makes up the system being attacked — for example, the standard C-language library libc — and the story is the malicious program the attacker wishes to have executed.

We found that return-oriented programming poses a much more general vulnerability than people initially thought,” said computer science graduate student Ryan Roemer. He and Buchanan chose to study return-oriented programming for a class project after they heard Shacham outline a series of open questions in a guest lecture he gave in Savage’s computer security course last winter.

The threat posed by return-oriented programming, across all architectures and systems, has negative implications for an entire class of security mechanisms: those that seek to prevent malicious computation by preventing the execution of malicious code,” the authors write in their CCS 2008 paper. For instance, Intel and AMD have implemented security functionality into their chips (NX/XD) that prevents code from being executed from certain memory regions. Operating systems in turn use these features to prevent input data from being executed as code (for example,, Microsoft’s Data Execution Prevention feature introduced in Windows XP SP2). The new research from UC San Diego, however, highlights an entire class of exploits that would not be stopped by these security measures since no malicious code is actually executed. Instead, the stack is “hijacked” and forced to run good code in bad ways. “We have demonstrated that return-oriented exploits are practical to write, as the complexity of gadget combination is abstracted behind a programming language and compiler. Finally, we argue that this approach provides a simple bypass for the vast majority of exploitation mitigations in use today,” the computer scientists write.

The authors outline a series of approaches to combat return-oriented programming. Eliminating vulnerabilities permitting control flow manipulation remains a high priority — as it has for twenty years. Other possibilities: hardware and software support for further constraining control flow and addressing the power of the return-oriented approach itself. “Finally, if the approaches fail, we may be forced to abandon the convenient model that code is statically either good or bad, and instead focus on dynamically distinguishing whether a particular execution stream exhibits good or bad behavior,” the authors write.