Sigreturn-oriented programming

Sigreturn-oriented programming (SROP) is a computer security exploit technique that allows an attacker to execute code in presence of security measures with non-executable memory and code signing being an example.[1]

It has been presented for the first time at the 35th Security and Privacy IEEE conference where it won the best student paper award.[2]

This technique employs the same basic assumptions behind the return-oriented programming technique: an attacker controlling the call stack, for example through a stack buffer overflow, is able to influence the control flow of the program through simple instruction sequences called gadgets.

The attack works putting on the call stack a forged sigcontext structure[3] and then overwriting the return address with the location of a gadget that allows the attacker to call the sigreturn[4] system call.[5]

Often just a single gadget is needed to successfully put this attack into effect, also this gadget sometimes reside at a fixed location making this attack simple and effective, with a setup generally simpler and more portable than the one needed by the plain return-oriented programming technique.[1]

Sigreturn-oriented programming can be considered a weird machine since it allows code execution outside the original specification of the program.[1]

Background

Sigreturn-oriented programming (SROP) is a technique similar to return-oriented programming (ROP), since it employs code reuse to execute code outside the scope of the original control flow. In this sense the adversary need to be able to carry on a stack smashing attack, usually through a stack buffer overflow, to overwrite the return address contained inside the call stack.

Stack hopping exploits

If mechanism such as data execution prevention are employed it won't be possible for the attacker to just place a shellcode on the stack and make let the machine execute it by overwriting the return address. With such protections in place the machine won't execute any code present in memory areas marked as writable and non-executable henceforth the attacker will need to reuse code already present in memory.

Most programs do not contain functions that will allow the attacker to directly carry on his deeds (i.e. obtain access to a shell), but the necessary instructions are often scattered around the memory.[6]

Return-oriented programming requires these sequences of instructions called gadgets to end with a RET instruction in this way the attacker can put a sequence of addresses where these gadgets resides and as soon as a RET instruction is met the control flow will proceed to the next gadget of the list.

Signal handler mechanism

Stack content while handling a signal (linux x86/64) including sigcontext structure

This attack is made possible by how signals are handled in most POSIX-like systems. Whenever a signal is delivered, the kernel needs to context switch to the installed signal handler, to do so it saves the current execution context in a frame on the stack.[5][6] The structure pushed onto the stack is an architecture specific variant of the sigcontext structure, which holds various data comprising the content of the registers at the moment of the context switch. When the execution of the signal handler is completed, the sigreturn() system call is called.

Calling the sigreturn syscall means being able to easily set the content of registers using a single gadget that can be easily found on most systems.[1]

Differences from ROP

There are several differences that characterize a SROP exploit that makes it different from a classical return-oriented programming exploit.[7]

First of all ROP is dependent on available gadgets which can be very different in distinct binaries, thus making chains of gadget usually not portable. Although turing complete ROP compilers exists,[8] it is usually non-trivial to create a ROP chain.[7]

Address space layout randomization (ASLR) makes it hard to use gadgets without an information leakage to get the exact position in memory of these.

SROP exploits are usually portable across different binaries with minimal or no effort, and allows easily setting the content of the registers which could be non-trivial or unfeasible for ROP exploits if the needed gadgets are not present.[6] Moreover SROP requires a minimal number of gadgets, and allows constructing effective shellcodes chaining system calls, these gadgets are always present in memory, and in some cases are always at a fixed location:[7]

list of gadgets for different systems
OS ASLR Gadget Memory Map Fixed Memory Location
Linux i386 sigreturn [vdso]
Linux < 3.11 ARM sigreturn [vectors] 0xffff0000
Linux < 3.3 x86-64 syscall&return [vsyscall] 0xffffffffff600000
Linux ≥ 3.3 x86-64 syscall&return Libc
Linux x86-64 sigreturn Libc
FreeBSD 9.2 x86-64 sigreturn 0x7ffffffff000
Mac OSX x86-64 sigreturn Libc
iOS ARM sigreturn Libsystem
iOS ARM syscall & return Libsystem

Attacks

Linux

An example of the kind of gadget needed for SROP exploits can always be found in the VDSO memory area on x86 Linux systems:

__kernel_sigreturn proc near:
pop     eax
mov     eax, 77h
int     80h  ; LINUX - sys_sigreturn
nop
lea     esi, [esi+0]
__kernel_sigreturn endp

On some Linux kernel versions, ASLR can be disabled by settings limits for the stack size to unlimited[9] effectively bypassing ASLR and allowing to easily access to the gadget present in VDSO.

For Linux kernels prior to version 3.3 it is also possible to find a suitable gadget inside the vsyscall page, which contains mechanism to accelerate the access to certain system calls often used by legacy programs, and resides always at a fixed location.

Turing-completeness

It is possible to automate writing back into the content of the stack frames hence developing a turing complete language employing a simple virtual machine. An example of such an approach can be found in Bosman's paper, where a virtual machine similar to the one of the brainfuck programming language has been used. It employs a program counter PC, a memory pointer P and a temporary register used for 8-bit addition A. This means that also complex backdoors or obfuscated attacks can be devised.[1]

Defenses and mitigations

A number of techniques exists to mitigate sigret attacks, relying on address space layout randomization, canaries and cookies, or shadow stacks.

Address space layout randomization makes it harder to use suitable gadgets by making the location at which they are placed unpredictable.

Signal cookies

A mitigation for SROP called signal cookies have been proposed, it consists of a way of verifying that the sigcontext structure has not been tampered with by the means of a random cookie xored with the address of the stack location where it is to be stored. In this way the sigreturn syscall just needs to verify the cookie existence at the expected location effectively mitigating SROP with a minimal impact on performances.[1][10]

Vsyscall emulation

For what it concerns the vsyscall page in kernel versions greater than 3.3 the vsyscall page is emulated, and only the system calls can be called directly at some fixed locations, any tentative to directly execute gadgets that do not reside at the fixed location expected by the kernel will result in an exception.[11] [12]

RAP

Grsecurity is a set of patches for the Linux kernel to harden and improve system security,[13] it includes the so called Return-Address Protection (RAP) to help protect from code reuse attacks.[14]

CET

Starting in 2016 Intel is developing a Control-flow enforcement technology (CET) to help mitigate and prevent stack-hopping exploits, which works by implementing a shadow-stack held inside the RAM which will only contain return addresses, protected by the CPU's Memory management unit.[15][16]

See also

References

External links

This article is issued from Wikipedia - version of the 6/23/2016. The text is available under the Creative Commons Attribution/Share Alike but additional terms may apply for the media files.