6

The Google plasma globe affair of 2012

 1 year ago
source link: https://lcamtuf.coredump.cx/plasma_globe/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

The Google plasma globe affair of 2012

The Google plasma globe affair of 2012

So, the cat's out of the bag. A recent series of promotional videos published by Google showcased several aspects of the company's security program. In episode #3, Daniel Fabian talks about the redteaming efforts - and in particular, about an exercise he and I ran together in 2012:

The centerpriece of that exercise was a USB-powered plasma globe. At the time, the dangers of USB devices were already well-understood, but most of the public discourse revolved around the threat posed by malicious payloads stored on pendrives, or by chargers surreptitiously downloading files off your phone.

We wanted to try another attack: a seemingly benign USB gadget that registered with the computer as a keyboard - and then, when you least expected it, typed in a malicious payload right under your nose, ideally quickly enough for you to not even notice.

The keyboard attack was interesting for a couple of reasons. First, keyboards are meant to be plug-and-play and don't require the installation of drivers or clicking through any warnings. Just as importantly, at least at the time, such accessories weren't closely watched by any enterprise security tools.

The first challenge, of course, was designing the hardware; I wanted to build something that would appear entirely innocuous yet cool enough for the user who receives it (under a flimsy pretense!) to plug it in and leave it plugged in for a while.

After untold hours of browsing for cheap USB trinkets, I settled on five plasma globes sourced from eBay. The modifications involved sneaking in a barebone surface-mount ATmega32U4 chip near the termination point of the USB cable. We used the LUFA USB library for interfacing with the host.

Beyond concealing the chip, there wasn't a whole lot going on. I actually had to replace the original USB cord, as the factory one contained nothing but two power wires. I also needed an MLCC capacitor on the power supply lines, a crystal oscillator for precise bus timing, and two small ceramic caps for the xtal to oscillate. Oh - I made some decals on my trusty vinyl cutter (possibly Roland Stika SV-8). You can see the end result here:

plasma_globe.jpg

The software side proved more complicated. We wanted the evil globe to be platform-agnostic and work equally well on Linux, on Macs, and on Windows. The company supported all three platforms, and we didn't want to cheat by choosing our targets based on insider knowledge of what OS they might be working on day-to-day.

We stumbled into the first issue pretty much right away: as it turns out, if you connect a non-Apple keyboard to a Mac, you are presented with a rather conspicuous wizard that needs to be clicked through, something along the lines of:

macos.jpg

The solution proved to be simple: we "borrowed" the USB vendor and product ID sent by an Apple-made keyboard taken from a coworker's desk. Looking at the prototype plasma globe sitting in my "old projects" box, it seems that we picked 05ac:024f.

The other challenge was delivering our payload quickly enough for the attack to be inconspicuous. The USB HID keyboard protocol is rather antiquated: instead of having the device push notifications as needed, it relies on the host notionally polling the keyboard at 125 Hz. This meant that a hypothetical 100-character payload would take almost a second to deliver - enough for the victim to see that something is amiss.

The first step was to modify the standard USB keyboard descriptor to request the maximum polling speed (1 kHz) from the host. Another critical optimization boiled down to realizing that the response packet allows up to six keycodes to be reported at once (details here). This might have seemed like a straightforward 6x speed gain, but not so: on MacOS, the keystrokes were dequeued not in the order they appeared in the packet, but from the numerically lowest scancode to the highest. This mind-boggling quirk forced us to tweak the payload to make it locally keystroke-ordering-agnostic in as many places as possible. In the end, we still managed to get the delivery time down to around 100 ms - a mere flash on the screen - but it took quite a bit of work.

Several other problems needed to be solved. For starters, we had to write a "polyglot" stage 1 payload that worked equally well for cmd.exe and bash. IIRC, on Windows, the payload involved creating and then executing a .js file in the background (essentially cmd /c cd %tmp%&type con:>f.js&start f.js); the JS then used ActiveXObject("MSXML2.XMLHTTP") to download the second stage and called eval(...) on the result. The unix version was simpler, executing curl via nohup to fetch additional scripts.

Beyond that, we also needed extra keystrokes to get from whatever the user might have been doing to shell - and then go back when done. On Windows, we'd send WinKey+R, and use Alt+O to delete the payload targeted at other platforms before delivering the Windows bits. On Ubuntu, we used Ctrl+Alt+T, followed by stty -echo and read -d... to sink the non-unix stuff. On MacOS, the sequence was more complicated: Cmd+Space followed by "term" and Cmd+O. All this needed to happen without messing up whatever the user was working. Then there was a weird GNOME animation on Linux initiated by sending Cmd+W to close the terminal window on MacOS... anyway, a pretty fun exercise to choreograph that one perfect sequence of keystrokes for all three OSes.

(Perhaps there was a way for the keyboard to fingerprint the host OS through some implementation quirk of the HID protocol, but our "project schedule" didn't allow for this research.)

Additional failsafes needed to be added in case the user's screen was locked; the downside of pretending to be a keyboard is that you don't know what's going on on the screen, and you don't want to leave bits of your payload sitting there in plain view in a login field - so there was that last Esc keypress to clean things up.

The final hurdle was knowing when to stop: the plasma globe was designed to wait about 5-10 minutes after being plugged in before doing anything, as to not arise suspicion. But if the user wandered off and locked their screen, we wouldn't succeed on the first try. We wanted to retry after 30 minutes and then every hour or so - but it was also important to not try more times than absolutely necessary.

Luckily, there is a simple back channel to talk to the keyboard once you have a shell on the machine: the OS can instruct the keyboard to toggle its standard LEDs (Num Lock, Scroll Lock, Caps Lock). So, our secret protocol involved the host toggling Scroll Lock five times within one second. On Linux, it was as simple as xset led named 'Scroll Lock'; on Windows, you had ActiveXObject("WScript.Shell").SendKeys("{scrolllock}"). Either way, upon the receipt of this confirmation code, the plasma globe would set a bit in its EEPROM and go dormant forever... well, OK - until reflashed.

It worked; the Google video tells the rest of the story (even though it gets some small details wrong). As for potential mitigations, see https://github.com/google/ukip.

You can contact me at [email protected] or follow me on Twitter. And be sure to check out my latest book!

Your lucky number is: 21579775


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK