Attacking multicore CPUs
Get exploited on time
The world of multi-core cpus we have just entered is facing a serious threat.
A security researcher at Cambridge disclosed a new class of vulnerabilities that takes advantage of concurrency to bypass security protections such as antivirus software
The attack is based on the assumption that the software that interacts with the kernel can be used without interference. The researcher, Robert Watson, showed that a careful written exploit can attack in the little timeframe when this happens, and literally change the "words" that they are exchanging.
Even if some of these dark aspects of concurrency were already known, Watson proved that real attacks can be developed, and showed that developers have to fix their code. Fast.
Watson presented his work at WOOT07, USENIX Workshop on Offense Technology, the results of his research entitled "Exploiting Concurrency Vulnerabilities in System Call Wrappers".
During the talk he showed how concurrency can be used to bypass security protections applied by so-called syscall wrappers.
A system call, briefly called syscall, is a basic function in the kernel that is called by a program. For example, when you open a file it's highly probable that the software you are using called the
open() syscall to open it.
A sycall wrapper sits between the kernel and the program itself, and analyzes which syscalls are called and their arguments. A security wrapper might be configured to block access to some files, so in the previous example trying to
open() the file "secrets.txt", it may stop the operation and return an error to the application.
We contacted Robert to learn more...
How does the attack work?
System call wrapping is a widely-used technique for extending kernel security, found in anti-virus systems and security policy enhancement frameworks such as the GSWTK, Systrace, and CerbNG systems I examine in the paper. System call interposition allows code running in the kernel address space to "wrap" system calls, adding new security checks, replacing the values of arguments to virtualize name spaces, or to audit arguments for the purposes of logging or intrusion detection. It's a very flexible technique, and appealing to software authors because it doesn't require changing existing kernel code, and allows control at the very well-understood system call interface.
This attack targets a weakness in the system call wraper architecture, in which system call arguments are separately copied by the system call wrapper and the kernel, allowing the attacker to "race" to replace the argument values between copies.
I was able to successfully bypass security in many system call wrappers by creating unmanaged concurrency between the attacking processes and the wrapper/kernel. This was possible on both uniprocessor systems and multiprocessor systems.
The existence of some of these vulnerabilities has been known for years (Ghormley 1998, Garfinkel 2003, Watson 2003), and I approached the authors of many of these wrapper systems as early as 2002 to report the problems. The contribution of this paper is in analyzing the vulnerability class, thoroughly exploring the attack space (I identify two previously undiscussed classes of race conditions, one of which is more broadly applicable), and to explore exploit strategies, allowing us to reason about the effectiveness of this attack aproach. It turns out that the approach is very effective indeed.
The paper [PDF] provides both a detailed discussion of the general class of concurrency vulnerabilities, and more concrete discussion of these specific vulnerabilities. I'd refer readers especially to the pictures and code in the slides [PDF] associated with the talk, which should make both the attack approach and simplicity of the exploits clear. In less than 20 lines of C code, and using only standard OS calls for memory access and management, the wrapper protections were completely disabled.
Isn't it about time that we put this one to sleep?
hitler, nazi. etc.
Great work guys.
This is almost as good as comp.lang.cobol !
try ( http://www.dbforums.com/showthread.php?t=1358734 )
Cobol? you ask. Those old guys really know how to get off , off, off topic and every second thread ends up in a flame war of some sort.
The reg comment-ers have a long way to go to before they can reach such lofty heights but are definately showing promise.
P.S. To some comment-ers.
More pertinent, pithy, and downright insulting comments are possible if you RTFA first.
This is a legitimate discussion
I agree with Ken Hagan AND De Zeurkous.
I quibble with Ken Kagen only in the statement about "implementing critical security functions in userland", because we're talking about syscall wrappers here - this is kernelland.
Ken Kagen took everyone down the right road by pointing out that CALL atomically places arguments onto a privileged stack, which system calls read and act on, therefore seemingly no opportunity for exploit. (but this is actually not quite correct - see below)
What Robert Watson is mostly discussing is
a. what happens when you WEDGE something between the two?
b. Particularly when you can have concurrent processes with same access to memory where the args are?
When a userland process makes a syscall, the argument for strings/structures is merely a pointer to the string/structure in userland memory area.
While the pointer could not be changed due to the stack being used, the memory being pointed at, being in userland, certainly could.
If the execution sequence is
wrapper (reads string, accepts argument as valid, or changes them)
<WINDOW OF OPPORTUNITY>
WINDOW 1: wrapper interrupted (yields time, scheduler interrupts, etc), wrapper gets a CPU back
WINDOW 2: another process, concurrently running in another CPU, changes userland memory
SYSCALL (real one) triggered
WINDOW #1 is the single CPU window.
Window #2 is the multi CPU/multi core window.
In these windows, another process with userland access (a child process with same memory access) can replace the string/structure contents before the real SYSCALL gets triggered.
So, how do syscall wrapper application developers make sure there is no window of opportunity, particularly WINDOW #2?
As De Zeurkous says, "these problems arise from incorrect design".
The way this kind of issue is handled in a kernel is to use semaphore locking architecture, but this doesn't seem to work here, because you'd have to put semaphore structures around arbitrary userland memory used as arguments to function calls, and you'd have to trust userland apps to obey the semaphore.
A better approach would be to have the syscall wrapper application transfer data structures themselves (copy entire structures, not just pointers to structures), into protected syscall wrapper memory.
There may be even better approaches - but the point about an "incorrect design" being used to insert a wrapper between userland and kernel syscall does seem valid to me.