Hacker News new | past | comments | ask | show | jobs | submit login
Gain control of a Linux System via an USB-Device due to strcpy (h-online.com)
86 points by mrud on March 8, 2011 | hide | past | favorite | 54 comments



So this is completely unsurprising and is probably one of the biggest weaknesses in Linux at the moment. The kernel is not being effectively audited, and as a result OSes such as Android end up being shipped with kernel bugs. What this means is that any app you run can bounce out into kernel space through one of these vulnerabilities and back into root userland to take over your phone (incidentally kernel bugs no doubt exist on iOS too, but we're talking about Linux here).

In 2009 there were 110 Linux kernel vulns released. Think about it - that's an average of about two a week. This is your phone, your TV, your in-car entertainment system.

Finding these bugs isn't hard. Go and download the source tree and search through for strcpy, then trace it back to the function and see where it's used. Then try the same for kfree, kmalloc and vmalloc.

You don't even have to download the code for this. Here's an strcpy search on FreeBSD: http://fxr.watson.org/fxr/search?string=strcpy

Once you have one of these functions you can chart the call path and data structures back to something a user can control. Once you have that, you're in with a good chance of getting a working exploit.

For those that are interested in learning how to write exploit code, I'd highly recommend The Shellcoder's Handbook - http://www.amazon.co.uk/Shellcoders-Handbook-Discovering-Exp...


While the effects of a bug like this will be mostly short lived on desktop systems where patch management is usually pretty good in linux, the effects on embedded systems can reverberate for years. Look around your house or office and consider how many devices like TVs, dvd players, DVRs, broadband routers, access control devices, industrial control systems and the like run linux and have a usb port. Many of these will have a broad range of usb device drivers built into the kernel (even if they're not used) and often use a network port or wireless chip by design. Very few of these will have reasonable update policies, and even fewer of them will move to a new kernel or backport a vulnerable driver. Many rely on custom drivers that would need to be tested all over again to qualify a new kernel and have busy and relatively inexperienced staff on them.

The ability to use these devices as sniffers, network backdoors and MITM attackers is very much there. Most of the time devices like this are more less invisible, very few consumers will be watching their network traffic. Worse, even when an intrusion is detected on a network and all traditional computing devices are wiped or replaced few people will think to replace their blu-ray.

Just another brick in the pervasive insecurity wall.


Look around your house or office and consider how many devices like TVs, dvd players, DVRs, broadband routers, access control devices, industrial control systems and the like run linux and have a usb port.

I have a few devices that are running a Linux kernel under the hood (TV, maybe DVR, maybe router but it has firmware updates, maybe BluRay but it also has firmware updates) but none of them have a USB port.

Many of these will have a broad range of usb device drivers built into the kernel (even if they're not used)

Are you an embedded developer? Seems strange to include unnecessary drivers on an embedded device.

Also I wonder how common something like ProPolice would be on embedded Linux devices.


Looking around my house, embedded devices with USB: Toshiba DVD, Sony Blu-ray, D-link Boxee box, Sharp TV (labeled service), Sharp Blu-ray, ASUS wireless N router, Cisco PIX firewall (built with BSD afaik), Chumby alarm clock, Samsung Android phone, LG Android phone (Android not running in host mode though, afaik), LG feature phone (probably not linux?), and a TiVo in a box in the attic.

I'm not an embedded developer. I agree these won't be built with the full range of default kernel drivers. Perhaps when I said a "broad range" I should have said something like "quite a few". Never the less, most of these devices will be built with a variety of usb storage drivers since that's the purpose of the usb port. I know for a fact that the Sony Blu-ray contains an impressive number of wireless lan drivers in addition to the storage drivers. The Chumby contains a variety including serial and wired lan. The ASUS router supports many mass storage options as well as parallel and serial printer support. The boxee box is reported to even include mouse and keyboard support as well as mass storage support, and I'd wager they left a lot more than that on.

Which isn't to say that any of these devices have this driver built in, I simply don't know. My point was more to raise the issue of what happens when a bug is discovered that affects one or more of these devices - many of which have a pretty large local attack surface. The answer is generally it stays vulnerable until you replace it, with the less similar it is to a PC the more likely that is to be true.

I wouldn't bet on many of these devices having stack smashing protection turned on. Look at how few linux distros have it turned on by default.


Note that not all buffer overflows are remotely exploitable though. Many of them only happen if you are able to run a program or in this case plug in a malicious device.


I don't write much C, mostly C++. But one of the things I swear about most when using C is the totally primitive and error-prone string handling. (I realize that C is supposed to be "primitive", but this really is a domain where the pain goes up drastically.)


C++ has pretty lousy string handling, too. std::string is a step up from char*, but why can't I do std::string(10)? Or str = nErrors + std::string(" errors"); ? Why do I have to go through the hassle of a std::stringstream just because I want to have a number in my string? Parsing stinks, where's the std::string::split() function?

Boost has a bunch of string algorithms, but that's design overkill; I don't really need to have the algorithms work on C strings because I won't be using C strings if there were an simple, useful string class like Java's, or Qt's.


I agree. Maybe I should have added that whenever I get back to C++ from Python, I also swear about the string handling... ;-)


As yet another C++ developer I have to ask, why is anyone doing a lot of string handling in C++ ?


Why using boost is overkill? You use std::XXX and the STL, do you consider these too? For the two cases you mentioned, boost comes with nice functions to solve them (lexical_cast, which uses stringstream and the boost tokenizer).

  tokenizer<> tok(s);
   for(tokenizer<>::iterator beg=tok.begin();beg!=tok.end();++beg){
       cout << *beg << "\n";
   }
It surely beats the C approach of handling pointers my hand, or the ugly interface of strtok / strtoX (X=l,d,etc). At least in C++ you can use the same function for any number type.

I see the need of C (or ASM), but with char/string manipulation it loses any battle with any other language, except probably speed.


Why is C 'supposed to be primitive?' If C was supposed to be so primitive, there wouldn't even be 'str' functions, it would just be memcpy functions and you would be responsible yourself for keeping track of null terminators.

C just needs a bolstered set of string-handling functions. Much like C++ has the Boost libraries.


Yeah, by "primitive", I meant "low level". (The strxxx functions aren't part of the language, after all. Like you say, one could write a better, more "object oriented" string library for C.)


GLib supposedly has some pretty solid C base libraries for string handling and other common tasks.

http://library.gnome.org/devel/glib/2.28/glib-String-Utility...


Quick grep on linux-2.6.37.3:

strcpy -> 2864

strncpy -> 894


how many times is strlcpy used? This bug was fixed with strlcpy:

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6...



Fortunately, Ulrich Drepper doesn't work on the kernel. Otherwise we would all have to pay money to open bug reports[1]

His preferred solution is to use the highly portable

  *((char *) mempcpy (dst, src, n)) = '\0';
make of that what you will…

[1] http://sourceware.org/bugzilla/show_bug.cgi?id=4980


strlcpy -> 1063


strncpy isn't always better. It's just as easy to misuse strncpy as it is to properly sanitize strcpy inputs.


To get Administrator access on Windows (theoretically) you could plug in a USB hub with a virtual keyboard, USB mass storage and a random unknown device. The USB mass storage would have the payload you wanted to run in the form of a driver for the unknown device and the virtual keyboard would replay the keys needed to accept the warning messages about installing unsigned drivers.


Can unprivileged users install hardware drivers on Windows? Really? (Honest question; I'm not a Windows admin).

This exploit uses a kernel-level buffer overflow during the initial device handshake, completely circumventing user privileges.


In XP, all bets are off, as the vast majority of users run with local admin rights.

For Vista and 7, I believe that the much-hated-by-numpties User Account Control should prevent this from happening, as it opens a virtual screen or something to give access to the 'OK/Cancel' dialog.

From UAC on Wikipedia: 'User Account Control asks for credentials in a Secure Desktop mode, where the entire screen is temporarily dimmed, Windows Aero disabled, and only the authorization window at full brightness, to present only the elevation user interface (UI). This is to prevent spoofing of the UI or the mouse by the application requesting elevation.'


For Vista and 7, I believe that the much-hated-by-numpties User Account Control should prevent this from happening

I think the idea was that the USB device would include a keyboard and that this would press the keys required to confirm UAC. This wouldn't work if the machine was locked, and if the user could see the screen then they'd at least notice it.


In a past thread about hardware exploits, someone suggested simply having a device that poses as a keyboard and then types out the source of a rootkit and compiles it. Or even just type the binary straight onto the disk somehow.

That my friends, is genius. Credit goes to whoever suggested it originally.


It is possible to make a pure-ASCII executable. http://mirror.href.com/thestarman/asm/eicar/eicarcom.html


I don't see how you could do this for PE files, which would be required to pull this off on x64 (since you can't run 16-bit binaries like .COMs). There are several fields in the headers that require non-ASCII values.


With PowerShell or WSH?


This link is very interesting. I thought incorrectly that it was only a random string. You should submit the link.


Fair play - I stand corrected.


That virtual keyboard trick wouldn't work in case the desktop/laptop is locked, though, that's a drawback.


The UAC runs in a context called the protected desktop. When the UAC is active things like this won't work. Your program won't be able to press "Okay" or anything.

Secondly, non-admin users can't install most drivers and autorun will ask them if they really want to run the app. Admin users can install but will also have to deal with the autorun dialog.


So you are saying that protected desktop accepts key presses only from some but not all keyboards connected to system? That does not seem quite right.

And as for UAC and protected desktop: take debugger and look at how most UAC prompts are invoked. Many of them are caused by user-space code running in address space of "offending" process, so you can patch them out.


He's talking about keypresses coming from a physical usb device - just one that doesn't have physical keys on it.


Isn't this the same exploit (or very close to atleast) as was used to hack the PS3 initially? A buffer overrun during device initialization.


Well isn't a buffer overflow used to hack EVERY video game system?


The cases I've seen are with buffer overflows in game saves, but this usually only gets you access to userland. An exploit in kernel space is usually harder to come across.


Actually that's not true. Kernels aren't infallible and while there's the 'many eyes' aspect of Open Source kernels, Linux is huge, so tracking stuff down often crosses multiple files, sometimes unrelated.

I went to a really excellent talk at the last DC4420 (http://www.dc4420.org/) on 0day in the Linux Kernel. The example provided was a double free bug that was really just a basic schoolboy error. A brief look through the source code tree found about 4 or 5 other examples in less than half an hour. Now I can write fairly obvious buffer overflow exploits, but I'm not exactly a ninja in this space by a long stretch. However, there are 253 advisories for 2.6 according to Secunia, and it's not over yet: http://secunia.com/advisories/product/2719/?task=advisories

AFAIK the 2.6 Linux kernel hasn't been fully audited for bugs, it isn't audited (at least AFAICR the Linux Kernel Auditing Project only looked at 2.2 and 2.4).

Slide 31 gives an overview of how kernel pointer overwrite bugs can be exploited here: http://jon.oberheide.org/files/source10-linuxkernel-jonoberh... - It's a fairly good slide deck in general but for the straight dope you're probably better looking through Phrack (here's a good article http://www.phrack.org/issues.html?issue=64&id=6#article).


Well so far there have only been two systems that made any effort to keep them separate, so that is true. But it's still the same base exploit.


meh... If someone has physical access to a GNU/Linux machine you'll most likely get pwned regardless.


You say that like it is a property of GNU/Linux, rather than a property of physical access.


Encrypted hard drive can make it hard to crack, even with physical posession. The advantage here was, you get to run code while they are logged in and the hard drive is happily unencrypting whatever you wish to see.

The govt desire was apparently to non-destructively crack a machine with only brief physical posession, without leaving much trace. The method in the article satisfies that.


Good think that I'm only running a Linux machine.


Busybox?


MIT/Linux


The only thing more dangerous than strcpy is strlcpy or strncpy. I can't tell you how many times I've seen:

strncpy(dst, src, sizeof(src));

And the developer thinks that the code is safer because he's using the "safer" function.


I hope you meant strlen in place of sizeof


Most people use sizeof when they are copying between static buffers on the stack. Strlen would be just as bad of an idea in this example because they're using the src buffer as the limit on the copy rather than the dst buffer which is still vulnerable to overflow. Should be:

strncpy(dst, src, sizeof(dst)-1);

Edit: bad code


or sizeof(dst), and not forgetting dst[sizeof(dst)-1]='\0';


That's why strlcpy is safer than strncpy, it makes sure that the destination string will always be zero-terminated.


I can't see how that would make it more dangerous. It's still not foolproof, but at least it isn't completely braindead like strcpy().


I am sure SELINUX will block these kind of buffer overruns. Unfortunately most people are disabling SELINUX in their machines.


SELinux relies on the kernel being intact. If you do a buffer overrun in the kernel, then SELinux isn't going to help at all.


Perhaps unfortunate, but not entirely unmotivated. SELinux has caused nothing but trouble for me. Things strangely don't work, until you remember to look for audit messages, and the documentation I've seen doesn't make it much less opaque...


This might change if selinux was better explained / had more easy to use tools. For now, most bigger software packages start with "1. disable selinux 2. run the software 3. ...". If developers can't figure it out properly, how can we expect users to do so... As an example, OO.org doesn't work on centos without manually adjusting / turning off selinux.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: