While I was at Shmoocon 2010, I was given a Phantom Keystroker. It's a neat
little USB dongle which looks like a thumbdrive that you could surreptitiously
install in the back of someone's computer. The Phantom Keystroker acts as a
keyboard/mouse USB HID (Human Interface Device) to send keystrokes, move the
mouse pointer around randomly, toggle caps lock and other things to annoy your
co-workers and loved ones. This started me thinking, what if you could make
something like this that was programmable? There are all sorts of things you
could do with it.
The Hak5 U3 USB switch blade is pretty cool, but lots of folks have autorun
turned off by default now. That said, they don't turn off the adding of a new
USB keyboard! A programmable USB key stroke dongle could replace U3 switchblades
in places where autorun from removable storage it is disabled. A USB HID device
also does not need special drivers installed on modern operating systems, much
like how a thumbdrive does not need drivers if the host supports USB mass
storage. This would allow for doing things on a terminal quickly, and without
drawing as much attention as sitting down in front of the terminal would. The
person turns their head for a minute, the pen-tester plugs in their programmable
USB key stroke dongle, and Bob's your uncle, instant pwnage. All sorts of
command could be run, but more on that later in the examples section.
The programmable key stroke dongle could be set to run by a timer. The
pen-tester programs the dongle to wait for a certain amount of time after
install before doing its thing, a time when the pen-tester suspects that a user
with extra privileges will be logged into the target workstation. If timed
right, all sorts of privilege escalation can happen. There are more options than
just a timer however. If the dongle has heat sensor or a photo resistor built in
it could be programmed to dump its key stroke/mouse payload when the heater
kicks in or the lights come on in an office. Think of the possibilities!
While at Shmoocon I saw the Hak5 crew setting up, and went by to talk to Daren
and Snubs. I mentioned the Phantom Keystroker to Darren, and how I thought it
would be great to be able to make a programmable one. Daren told me he had
something to tell me later. It seems Darren (http://www.hak5.org/) and Robin
Wood (digininja http://www.digininja.org) had been working on just such a
project. Cool, great (or devious) minds think alike! I was looking forward to
their product.
After the con, I decided to see if I could come up with a ghetto way to make a
programmable USB keystroker. I started looking around, and found programmable
promotional USB buttons used for marketing that took people to a predefined
website. Neat, but not easily reprogrammed. I then started looking into Arduino,
since my buddy Morgellon turned me on to them. But implementing a USB HID with
the standard Arduino is a bit of a pain. Then I found a related device called
the Teensy ( http://www.pjrc.com/teensy/ ) which you could program in C, or the
easier Arduino development environment, and that already supported USB HID out
of the box! Rock on, and it was only $18 to $27 depending on how you got it. I
opted for the Teensy over the Teensy++ since it was cheaper, smaller and I did
not need many I/O pins.
For those who want a more professional device with nicer packaging, Daren and
Robin have a product coming soon. I encourage you to buy theirs when it comes
out to help promote their work, and so Daren can spend more time on the Hak5
projects we so love. For those who have an electronics/DIY bent, and like to "Go
ugly early" what follows are details on how I made my programmable USB key
stroke dongle.
1. Likely types faster than you can, without errors. This is important when
physical access time to the target system is limited. 2. Works even if U3 autorun is turned off.
3. Draws less attention than sitting down in front of the terminal would. The
person turns their head for a minute, the pen-tester plugs in their programmable
USB key stroke dongle, and the box is popped as Dave Kennedy likes to say. 5. The HID can also be set to go off on a timer when you know a target will be
logged in, or by sensor when certain conditions are met. 6. You could embed a hub and a flash drive in your package so that you have
storage and the programmable USB HID all in one nice neat package. 7. Embed your device in a USB toy or peripheral (lots of spare room in a printer
or dancing USB penguin) and give it to your target as a 'gift'. Packaging that
looks like a normal thumb drive is also an option. 8. After your Trojan USB device is in place, program it to "wake up", mount
onboard storage, run a program that fakes an error to cover what it is doing
(fake BSOD for example), do its thing, then stop (leaving the target to think
"it's just one of those things").
1. Add a user to the box or the domain. 2. Run a program that sets up a back door.
3. Copy files to your thumbdrive (see example code for how to find the flash
drive by volume name) 4. Go to a website they have a cookie for, and do some sort of transaction (sort
of like CSRF, but hardware based).
I'd like to note one disadvantage of the device. The first time you plug in a
USB HID it takes a bit of time to enumerate. This seems to take a little longer
with a USB HID than a new U3 thumbdrive does. Still, I think there are many
applications for this USB keyboard/mouse device.
You know, 'A programmable USB keystroke dongle' is kind of a mouthful to say. I
needed a shorter name for this sort of device. Lots of folks build their
electronics projects in Altoids tins, so I thought about calling it MintyPwn, in
honor of LadyAda's MintyBoost. Also, since it's a USB stick, and I planned to
use DIP switched to select what keystrokes/mouse movements to send, DIPStick
sounded like a cool name. Neither of those however really seem to describe what
the device was, so I thought maybe an acronym was in order:
Programmable
HID USB
Keystroke Dongle,
or PHUKD for short.
What follows is a rough schematic
(with light sensor) and set of pictures that should be enough for
you to build your own. Please keep in mind, my soldering and rotary tool skills
are not yet up to snuff, so the packaging can be made better/smaller. Also
included is some sample code for the Arduino development environment. I plan to
add more code and pictures as the project matures. If you have any ideas for
useful payloads for the PHUKD type, please let me know.
People requested I add more photos so they know what is
soldered where, so I hope the following helps them out.
A few updated pics (added 4/1/2010):
Notice how I soldered in the photoresistor and 10kΩ resistor,
it's ugly but it works with the code below.
I used a 24 pin IC mount and soldered it on backward, that way
I could use the pin holes as sort of a mini bread board. The DIP switch I'm
using in the pic requires the use of something like a paper clip to set the
switches, but at least I won't accidently set them wrong in my pocket as easily.
I used heat shrink tubing to make the package a little neater,
and hold it all together.
A few even newer pics (added 6/3/2010):
These are two new units I've put together, one with a normal
Teensy 2.0 and an SD adapter, the other with a Teensy++ 2.0. Notice I used heat
shrink to make the shell, this works pretty well as I can start shrinking it,
cut holes for the switches as it shrinks, and then slit the whole thing so I can
take it on and off as needed.
The Teensy 2.0 unit, disassembled
The naked Teensy++. Yes, my soldering skills need work. I've added a momentary
push button for diagnostic and demo help.
Here is the other side, with the shield taken off. I really like using the
shield concept, as headers are cheap and easy to solder. Now I can repurpose the
unit anytime I like by just swapping shields made on cheap perf board.
I've also made a trojaned mouse. The way this one works is there is a USB hub,
and a microSD USB adapter soldered into the mouse along with the Teensy. I've
got this one set to run it's payload when scroll lock is toggled. The following
video should explain more:
Short presentation I did for the Bob talks at Outerz0ne 2010
on the concept
To use the library, copy the files phukdlib.h and phukdlib.cpp into <arduino
folder>\libraries\PhukdLib\, then add this include line to your sketch:
#include <phukdlib.h>
I've put a little demo sketch in the zip file under examples to help illustrate how it can be
used. Keep in mind, I've been mostly implementing for Windows so far. Linux and OS X
will take other keystrokes to accomplish the same effects. The function names
are fairly self explanatory, but just in case:
CommandAtRunBarMSWIN(char
*SomeCommand)
Opens the MS Windows run bar and executes the given command.
CommandAtRunBarGnome(char
*SomeCommand)
Opens a run bar in Gnome under Linux and executes the given
command.
ShrinkCurWinMSWIN()
Shrinks the active window to help hide it in MS Windows.
ShrinkCurWinGnome()
Shrinks the active window to help hide it in Gnome.
PressAndRelease(int KeyCode, int KeyCount)
This function simplifies the pressing and releasing of a key. You
can also specify how many times to hit the key (really useful for
tabbing to where you need to be on web sites).
ShowDiag()
Just sends diagnostic info out the keyboard interface. Things
like the reading on analog pin 0, and the state of each input.
Should work on both types of Teensy, but I've not done a lot of
testing.
DIPOptions
Not really a function, but a string you can set in your sketch
that ShowDiag will print out. I kept forgetting which DIP switch I
had set to run which function, so I use this as a reminder at
runtime.
int ledkeys(void)
I noticed when I logged into a box, the Num Lock LED would often
toggle (depending on how it was set last). I thought this would make
a great way to know when someone just logged in, since the Num lock,
Caps lock and Scroll lock events are sent to every attached keyboard
on the system. Now we can have a sort of two way communication
giving us a better idea of when a user is really sitting at the
system, and it's logged in and ready for mischief. Also, thanks to
KennyG for the CAPS lock trap idea. All we do is turn on CAPS lock,
and when we see it go off we know someone is at the keyboard to turn
it off.
ledkeys returns the setting of the "lock keys"
Num Lock = 1
CAPS Lock = 2
Scroll Lock = 4
Add them together to get combos, for example if all threm are on 7
would be the result. You can use binary operators to separate out
just the lock keys you are looking for, but I've made that a little
easier with the IsXOn functions below.
boolean IsNumbOn(void)
Returns TRUE if NUM Lock LED is on and FALSE otherwise.
boolean IsCapsOn(void)
Returns TRUE if Caps Lock LED is on and FALSE otherwise.
boolean IsScrlOn(void)
Returns TRUE if Scroll Lock LED is on and FALSE otherwise.
I'm also open to adding more functions, and taking code contributions.
The following are some simple examples of programming the PHUKD using the
Arduino environment (from before I made my PHUKD library, so look at the example
code that came with the PHUKD library if you intend to use it). More details on the language can be found at the following
two links:
When I started this project I had to delve into the Teensyduino source code to figure out how to send some
control keys. Since then, Paul has done a lot of work on the Teensyduino
documentation, especially when it comes to USB HID support. Check out these two
pages:
I'm working on a laser projector and a hexapod project that these docs will
help greatly.
Hopefully my sample code will help you figure it
out how to use this functionality as well. If you wish to change the USB Vendor and Product ID look in arduino-xxxx\hardware\teensy\cores\tensy_hid\usb_private.h If you come up with any useful keyboard commands, please send them to me as
functions that are easy to include in other's projects. Note that in the code
below, I have one DIP switch determine one function, but with an 8 position dip I
could program it so I had the choice of 256 different functions.
The following program, "phukdexample.pde", should get you
started. Just read the comments.
/*The following is Irongeek's
code to do simple keyboard/mouse functions with the Teensy,
including
something like U3 functionality that will work even if autorun is
disabled.
http://www.irongeek.com/i.php?page=security/programmable-hid-usb-keystroke-dongle
To learn more about Teensyduino see:
http://www.pjrc.com/teensy/teensyduino.html
http://www.arduino.cc/en/Reference/HomePage
Look in arduino-xxxx\hardware\teensy\cores\tensy_hid\usb_api.h
for key definitions
Edit arduino-xxxx\hardware\teensy\cores\tensy_hid\usb_private.h
to change USB Vendor and Product ID
*/
int ledPin
=
11;
int DIP_1
=
14;
int DIP_2
=
15;
int DIP_3
=
16;
int DIP_4
=
17;
int DIP_5
=
18;
int DIP_6
=
19;
int DIP_7
=
20;
int DIP_8
=
21;
int PhotoRead
=
0;
unsigned
long
LastTimerCheck =
millis();
// The setup() method runs once, when the sketch starts
void setup(){
// initialize the digital
pin as an output:
pinMode(ledPin,
OUTPUT);
pinMode(DIP_1,
INPUT_PULLUP);
// Dip
pinMode(DIP_2,
INPUT_PULLUP);
// Dip
pinMode(DIP_3,
INPUT_PULLUP);
// Dip
pinMode(DIP_4,
INPUT_PULLUP);
// Dip
pinMode(DIP_5,
INPUT_PULLUP);
// Dip
pinMode(DIP_6,
INPUT_PULLUP);
// Dip
pinMode(DIP_7,
INPUT_PULLUP);
// Dip
pinMode(DIP_8,
INPUT_PULLUP);
// Dip
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop()
{
PhotoRead =
analogRead(8);
//Timer example, millis()
returns the number of milliseconds since being plugged in. It will
roll over to 0 at about 50 days.
// This example does not
use the DIP switches, but should fire off about ever minute. if((millis()-
LastTimerCheck)>=
60000){
digitalWrite(ledPin,
HIGH);
// set the LED on
CommandAtRunBar("notepad.exe");
delay(1000);
Keyboard.print("It
has been about a minute since I executed last, current time is ");
Keyboard.print(millis());
Keyboard.print("
and I was set to go off after "
);
Keyboard.print(LastTimerCheck);
Keyboard.println("
plus 60000 milliseconds.");
LastTimerCheck =
millis(); }
//Please note: I use
negative logic here, when a pin goes to ground the code us run.
//My version of Hello
World, just opens up notepad and says I'm here. :) if(!digitalRead(DIP_1)){
digitalWrite(ledPin,
HIGH);
// set the LED on
CommandAtRunBar("notepad.exe");
delay(1000);
Keyboard.print("Adrian
Was here!!! :)"); }
//Locks the workstaion if
you are in Windows if(!digitalRead(DIP_2)){
digitalWrite(ledPin,
HIGH);
// set the LED on
Keyboard.set_modifier(MODIFIERKEY_CTRL|MODIFIERKEY_ALT);
Keyboard.set_key1(KEY_DELETE);
// use delete key
Keyboard.send_now();
// send strokes
Keyboard.set_modifier(0);
//prep release of control keys
Keyboard.set_key1(KEY_ENTER);
delay(1500);
Keyboard.send_now();
//Send the key changes
Keyboard.set_key1(0);
Keyboard.send_now(); }
//Moves the mouse around
and clicks to be annoying if(!digitalRead(DIP_3)){
digitalWrite(ledPin,
HIGH);
// set the LED on
Mouse.move(random(-100,
100),random(-100,
100));
Mouse.click(); }
//Opens a browser to
http://irongeek.com if(!digitalRead(DIP_4)){
digitalWrite(ledPin,
HIGH);
// set the LED on
CommandAtRunBar("cmd
/c start http://irongeek.com"); }
/*
This sectiont sends a command to the run bar, finds the drive
letter by its volume name (MYTHUMB in
this ecample, and case sensitive), then runs your script. Thanks
to Tim Medin for this more
elegant command line then what I had for finding the
thumbdrive by volume name.
*/ if(!digitalRead(DIP_5)){
digitalWrite(ledPin,
HIGH);
// set the LED on
CommandAtRunBar("cmd
/c for /F %i in ('WMIC logicaldisk where \"DriveType=2\" list brief
^| find \"MYTHUMB\"') do %i\\myscript.bat"); }
//Make a facebook post,
assumes the person is logged in. if(!digitalRead(DIP_6)){
digitalWrite(ledPin,
HIGH);
// set the LED on
CommandAtRunBar("cmd
/c start http://m.facebook.com");
delay(6000);
PressAndRelease(KEY_TAB,
8);
Keyboard.print("Test
from Phukd device, more info at http://www.irongeek.com/i.php?page=security/programmable-hid-usb-keystroke-dongle");
PressAndRelease(KEY_TAB,
1);
PressAndRelease(KEY_ENTER,
1); }
//Check light, do funny
stuff if(!digitalRead(DIP_7)){
digitalWrite(ledPin,
HIGH);
// set the LED on
CommandAtRunBar("notepad.exe");
delay(1000); if(
PhotoRead <
400
){
Keyboard.print("I'm
scared of the dark"); } if(
PhotoRead >=
400
&&
PhotoRead <=
900
){
Keyboard.print("The
lights are on it seems"); } if(PhotoRead
>
900){
Keyboard.print("What
the hell?!?!?! Is that a laser or a nuke flash?"); } } if(!digitalRead(DIP_8)){
digitalWrite(ledPin,
HIGH);
// set the LED on
ShowDiag(); }
digitalWrite(ledPin,
LOW);
// set the LED off
delay(6000);
//keeps commands from being
sent one after the other too fast
}
void CommandAtRunBar(char
*SomeCommand){
digitalWrite(ledPin,
HIGH);
// set the LED on
Keyboard.set_modifier(128);
//Windows key
Keyboard.set_key1(KEY_R);
// use r key
Keyboard.send_now();
// send strokes
Keyboard.set_modifier(0);
//prep release of control keys
Keyboard.set_key1(0);
//have to do this to keep it
from hitting key multiple times.
Keyboard.send_now();
//Send the key changes
delay(1500);
Keyboard.print(SomeCommand);
Keyboard.set_key1(KEY_ENTER);
Keyboard.send_now();
Keyboard.set_key1(0);
Keyboard.send_now();
}
void PressAndRelease(int
KeyCode,int
KeyCount){
int
KeyCounter=0; for(KeyCounter=0;
KeyCounter!=KeyCount;
KeyCounter++){
Keyboard.set_key1(KeyCode);
// use r key
Keyboard.send_now();
// send strokes
Keyboard.set_key1(0);
Keyboard.send_now();
// send strokes }
}
void ShowDiag(){
digitalWrite(ledPin,
HIGH); for(int
thispin=0;
thispin <23;thispin++){ if(!digitalRead(thispin)){
digitalWrite(ledPin,
HIGH);
// set the LED on
Keyboard.print(thispin);
Keyboard.println("
is low"); } else{
Keyboard.print(thispin);
Keyboard.println("
is high"); } }
Keyboard.print("analog
pin 8 is: ");
Keyboard.println(PhotoRead);
digitalWrite(ledPin,
LOW);
}
I had to make a hole in the case to fit the dip switches, and have yet to solder
things together in this package. I hate to spend money on enclosures, so I go to
the candy aisle looking for good boxes. As mentioned before, Altoids cans are an
option, but I don't like the fact that they are metal. Ice Breakers makes a type
of sour gum that comes in a rectangular plastic box with rounded edges, and it's
big enough to hold a small bread board. MudFlap of the Hacker Consortium pointed
me towards using TicTac containers, and they look like they will work well,
especially if you want to put a photoresistor in your device (transparent
plastic walls). If you are in need of a small USB A to USB Micro B connecto,
DealExtreme has a cheap solution:
The plastic casing around it is also easy to remove if you need more
flexibility.
I plan to keep updating this page as the project progresses, so please check
back again.
Get your Teensy product and programming information here, but please let them
know I sent you (Maybe I can get some free samples for my project) http://www.pjrc.com/teensy/
07/14/2010: Added a video that will show you the basics of setting up the
Teensyduino environment in Windows so you can start developing PHUKD devices.
06/28/2010: I've updated the
PHUKD Library to 0.2.
The main changes are that I've added two functions for the Gnome desktop under
Linux:
As a side note, I'll be speaking about the PHUKD project at Defcon! Thanks to
Paul for the help with the hardware, the
Kentuckian ISSA for helping to get me to Defcon, and
Tenacity Solutions for their
support on this project.
04/01/2010: I've updated my Programmable HID USB Keyboard Dongle project
page with:
Photos of a soldered, heat shrink
packaged, thumbdrive sized unit.
Code example that demonstrates timer
delays and using the light sensor.
Code for doing quick diagnostics on
the PHUKED unit to see which pins are connected and what the analog pin reads.
Added a comment about being able to
use the 8 position DIP switch to choose from 256 different options.