RoganDawes / P4wnP1

P4wnP1 is a highly customizable USB attack platform, based on a low cost Raspberry Pi Zero or Raspberry Pi Zero W.
GNU General Public License v3.0
4.02k stars 660 forks source link

Possible to use as remote keyboard? #83

Closed Fmstrat closed 7 years ago

Fmstrat commented 7 years ago

Hi,

Not really an issue per say, but I'm trying to figure out if P4wnP1 can be used in this way. I'd like to be able to plug the Pi0W into a USB port, and have it act as a keyboard. Then SSH into the Pi0W over WiFi and send commands to the computer as if they were being typed on a keyboard. So no payload, no HID backdoor, just acting as a raw keyboard for remote administration.

Is this possible, and if so, how would I go about doing it?

Thanks.

jcstill commented 7 years ago

Probably is possible. As it sits right now, your pi already is acting as such (kinda). At it's root the P4wnP1 acts just like a keyboard (as far as the host is concerned). There would probably be a way to enable (branching off backdoor) the SendKeys command all the time. However, the it doesn't send things like backspaces, ctrl, and alt. Those would need the help of the ducky payloads.

Maybe if the ducky script interpreted, compiled, and injected every "special" keystroke (alt, ctrl, backspace, etc. )?

And I say branching off backdoor because all the things needed to make this happen are already in backdoor. The scripts that would make this possible are there, but would need to be modified, and a lot of debugging. And then it would be just a keyboard. @mame82 maybe a nice addition to backdoor?

BTW why not just buy a $15 keyboard? Bc in doing this its not like it's going to be secretive. Since it is acting as a keyboard, everything you do will show on screen, and you would have no feedback on your ssh (without backdoor), so you would need to be able to see the screen.

Fmstrat commented 7 years ago

@jcstill Thanks for all the info. I will keep looking into it. And the keyboard option isn't available since this is remote administration. I'm building a system that uses a Pi3 to capture video from S-video out on a remote machine and be able to toggle the power switch, then the Pi0W to send keyboard commands. This way I have direct access to the machine as if I was sitting at it for disaster recovery.

PoSHMagiC0de commented 7 years ago

Hmm, the P4wnP1 does that now. The HID backdoor is capable of sending keystrokes (except for modifiers, he mentions he had issues with that), and duckscript.

If you are going to send a series of commands through keystrokes then putting it down as duckyscript would be the way to do since you can script out a whole sequence of strings, modifiers, and stuff. In the P4wnP1 he added some command line commands called outhid and outduck that stuff can be piped to. HID is just keystrokes to the screen. The duck one you can cat a duck script file to to do your thing. You probably could echo the commands to it to one by one if you like like.

echo "STRING \"Hello World\"" | outduck

I been doing a lot of digging in this project. Really impressive.

Fmstrat commented 7 years ago

@PoSHMagiC0de Perfect. I'll look into this, but I'm thinking that use of this: https://github.com/pelya/android-keyboard-gadget/blob/master/hid-gadget-test/jni/hid-gadget-test.c might work better. That would allow to just run hid_gadget_test /dev/hidg0 keyboard and type a letter, press enter, type a letter, press enter, etc. It supports modifiers, too. In an ideal world I'd write something to capture all keys and pass-through, but either the above mentioned outduck or the hid-gadget-test look to be my best options. Thanks!

mame82 commented 7 years ago

Let me give some insights on inner workings of an USB HID keyboard first.

An USB keyboard doesn't work like a normal keyboard. A USB keyboard is a special HID device, which in simple words sends USB messages with usage IDs. The target OS (windows in our case) uses a HID driver to interpret these messages. In order to be able to do this, the device needs to define how these HID messages have to be interpreted. This is done by defining a "HID report descriptor" defined on P4wnP1. Al of this is defined in the "USB HID usage tables v1.12" which can be found here:

http://www.usb.org/developers/hidpage/Hut1_12v2.pdf

Page 0x07 describes keyboard usage IDs.

If the HID descriptor describes that the device sends input reports from this usage page, a report containing a 0x1C would be interpreted by the OS as pressing the key Y on a keyboard with North American key layout. How this key is interpreted by the OS depends on the keyboard language setting. With an US layout, this would end up as a lower case y, with a German layout as lower case z. An upper case Y could be achieved by sending a 0xE1 along with the 0x1C in the same report, whereas the report descriptor has to define this byte as modifier. (details on page 53ff of the linke HID usage table).

In simple words: An USB keyboard sends a combination of USB IDs with HID input reports to the Host, which are interpreted a combination of character keys and modifier keys, according to the given HID device descriptor. How these keys are interpreted by the target OS depends on the language setting. This is why P4wnP1 needs to have an according language setup for the target.

If a payload should print out a Z to an US layout target the key z and the left shift modifier are sent, while key y and the left shift modifier are sent to a target with German layout to achieve the same.

Of course there exists a back channel, sending output reports back to P4wnP1, but this time the declared usage page is 0x08 instead of 0x07. This means that the data is interpreted as LED (NUM, CAPS, SCROLL) by the target. Otherwise you wouldn't see LEDs lit when CAPSLOCK is pressed on an USB keyboard.

In fact a similar technique is used, to bring up communication for the HID covert channel.

Note: The given description is simplified, as the modifier keys aren't sent as full bytes, but as single bits (8 possible modifier keys), which are interpreted by the USB driver a defined in the report descriptor.

How keystrokes are send from P4wnP1

In order to generate the correct keystrokes from P4wnP1 the HID input reports have to be generated. How this is done depends on the input data. If the input is a ASCII string a 0x5A would represent the character Z. Thus an ASCII 0x5A has to be translated to a key z USB ID (0x1D) combined with a left shift modifier USB ID for an USB keyboard layout. This again means every language supported by P4wnP1 needs a table, translating from the encoding (ASCII) of the input to USB keys and modifiers for the output. P4wnP1 ships with tables to do this for ASCII, which is one of the limitations, as ASCII is really limited. Building those tables for Unicode, on the other hand, would be an insane task (especially because most of the relevant keys for attacks are ASCII based).

DuckyScript itself has the same limitations, but it eases up sending special keys. If you want to send an return this can be done based on ASCII input, as long as a newline \n is interpreted as as RETURN and the correct USB IDs are sent. So RETURN key could be used from strings (and are supported by P4wnP1's outhid command).

But how should one represent an DELETED or BACKSPACE key in pure ASCII ? This is where a script language comes in handy. DuckyScript was chosen because it is well known, but essentially only a solution for sending special key combinations, beside raw ASCII strings, is needed.

The problem with the pure keyboard idea / feature request

The idea of @Fmstrat seems easy to implement. But the problem resides in the input data. What should be the input for the keystrokes?

1) ASCII written to the SSH shell ? Yes that's possible if outhid available in the payloads get's promoted to the shell to pipe data in and the correct target language has been chosen. In fact it is already possible with the SendKeys command of the backdoor payload (only \n couldn't be used to send a RETURN key). But this way no BACKSPACE or other special keys could be sent.

2) Fetching the scan codes generated by the hardware keyboard ?

If this could even be done (like the showkey Linux tool does), it is likely that the scan codes read could be translated to keyboard USB IDs. But not only different translation tables have to be written, the key presses have to be continuously be monitored.

Imagine a scan code sequence representing: SHIFT DOWN, X, Y, SHIFT UP, Z This has to be translated to USB: X + SHIFT MODIFIER, Y + SHIFT MODIFIER, Z + NO MODIFIER So the continuously pressed SHIFT key affects multiple reports in USB. If the target layout isn't US the translation has to be done differently, of course.

As shown this could become a complex task.

Additionally I doubt that raw scan codes could be received from input to an SSH session. AFAIK input is given terminal based (PTY), which would mean that it has to be interpreted in a whole different way.

3) Low level scan code reading from the source device?

It should be possible to read the scan codes from the source device with the real keyboard attached, but this needs some kind of software implementation on this device to grab the raw key presses. Maybe it would even be possible to grab raw USB IDs if the keyboard source is a USB keyboard.

4) Presenting a soft keyboard to the user ?

This would need some kind of graphical UI and slow down input. There are reasons for using SSH on P4wnP1 (described in another issue), so this isn't a solution, either.

Conclusion

Implementing the requested feature is a complex task, which result in having some kind of wireless keyboard (which needs to be configured to the correct layout). So I'm not going to implement this.

A more useful approach is to use the HID backdoor payload. The covert channel doesn't have to be connected (no FireStage1 needed) to send keystrokes. Long ASCII sequences could be sent with SendKeys, pre written DuckyScripts with SendDuckyScript.

In contrast to a RubberDucky, for P4wnP1 it makes sense to have simple DuckyScripts ready, which only do things like sending a BACKSPACE or a TABULATOR or an ALT + F4, ENTER or a GUI r. Those scripts could be used as short "keyboard macros" from the backdoor shell with SendDuckyScript

Fmstrat commented 7 years ago

Oh, sorry, should have recommended this be closed a while ago. I ended up building a Pi based IPMI system with keyboard and video support: https://github.com/Fmstrat/diy-ipmi