Jump to content

something_evil

Members
  • Posts

    2
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

something_evil's Achievements

Newbie

Newbie (1/14)

  1. Hi, A couple of usability tweaks: Doesn't mess up caps/num/scroll state after use. After printing the login goes to sleep. Double tap scroll lock to wake up. When sleeping double tap num lock to print your selected favourite/default login. Cleaned up the code, so it doesn't require you to mess with usb_api.xxx files. Also, if your code uses lots of status led input you might want to take a look at LedInput.h (bonus: it has key double tap support - high tech shit :o ) Argh... couldn't upload the sources or zip here so uploaded it to google docs: keychain.zip
  2. Hi, First post, first teensy program so don't judge. Finally got around to implementing an idea I had for some time - a HID password manager. No buttons, no screen, no soldering required. Plug it in and use your normal keyboard to control it. Not very useful for the offensive aspect of things, but not getting pwned is important, right? It uses keyboard status leds for input: you press caps/scroll/num lock, the led turns on and teensy can act on that. The way you would use it is: Edit your login info in the source code Compile and upload it to teensy (duh) When you need to login, select the username field and plug teensy in Enter the secret key sequence (aka secret knock) Use scroll lock and num lock to navigate the login list Find the one you need and press caps lock Press login ??? Profit The secret knock is just a sequence of caps, num and scroll lock keys (see source code). Default is: caps, scroll, num lock, num lock. To make it work I had to add a couple of lines to usb_api.cpp: bool usb_keyboard_class::led_numlock_on() { return keyboard_leds & 1; } bool usb_keyboard_class::led_scrolllock_on() { return keyboard_leds & 4; } bool usb_keyboard_class::led_capslock_on() { return keyboard_leds & 2; } bool usb_keyboard_class::isReady() { return usb_configuration; } Obviously you need to add definitions to usb_keyboard_class class in usb_api.h: bool led_numlock_on(); bool led_capslock_on(); bool led_scrolllock_on(); bool isReady(); And the actual program code: /* Teensy Password Manager By: something_evil on 30 May 2010. --------- Controls: Scroll lock - up; Num lock - down; Caps lock - type the selected login info; --------- Configuration and general info: Edit the logins in setup() and don't forget to change LOGIN_COUNT constant to how many passwords you have. knockSeq - sequence of keys, that unlocks the device. Once plugged in the device will flash twice. This means you can start entering the secret sequence. Default is caps lock, scroll lock, num lock, num lock. If you mess up, just start from the beginning. LOCK_OUT_AFTER - This sets the number of times you can mess up the secret sequence. By default you have 3 tries. After that - unplug, relax, plug it in and try again. The input is a bit flaky so don't rush it. It's not a race ;) Hack away! */ /* ---- Stuff for the logins DB ---- */ struct loginEntry { char* description; char* userName; char* password; }; const int LOGIN_COUNT = 4; loginEntry logins[LOGIN_COUNT]; int currentPos = 0; // currently selected entry /* ---- Authentication stuff ---- */ byte knockSeq[] = {KEY_CAPS_LOCK, KEY_SCROLL_LOCK, KEY_NUM_LOCK, KEY_NUM_LOCK}; int knockPos = 0; byte knockFails = 0; boolean authenticated = false; boolean lockedOut = false; const int LOCK_OUT_AFTER = 3; /* ---- LED stuff ---- */ const int ledPin = 11; int ledState = LOW; long previousMillis = 0; // will store last time LED was updated long interval = 250; // interval at which to blink (milliseconds) boolean firstRun = true; void setup() { pinMode(ledPin, OUTPUT); /* ------------------- Enter your logins here ------------------- */ logins[0].description = "First site"; logins[0].userName = "Administrator"; logins[0].password = "rootpassword!@#$%^&*()_+|"; logins[1].description = "Second site"; logins[1].userName = "Username"; logins[1].password = "meh"; logins[2].description = "My gmail password"; logins[2].userName = "Loosername"; logins[2].password = "looserpassword"; logins[3].description = "other email password"; logins[3].userName = "name"; logins[3].password = "pass"; } /* Stolen (and changed a bit) from http://www.irongeek.com/i.php?page=securit...eystroke-dongle */ void PressAndRelease(int KeyCode, int ModifierCode = 0, int KeyCount = 1){ for (int KeyCounter = 0; KeyCounter < KeyCount; KeyCounter++){ Keyboard.set_modifier(ModifierCode); Keyboard.set_key1(KeyCode); Keyboard.send_now(); Keyboard.set_modifier(0); Keyboard.set_key1(0); Keyboard.send_now(); } } /* Clears the keyboard's status lights */ void ClearLights() { if (Keyboard.led_numlock_on()) PressAndRelease(KEY_NUM_LOCK); if (Keyboard.led_capslock_on()) PressAndRelease(KEY_CAPS_LOCK); if (Keyboard.led_scrolllock_on()) PressAndRelease(KEY_SCROLL_LOCK); } /* Clears the currently focused field/line */ void ClearCurrentField() { /* Key sequence: END (just to be sure), SHIFT + HOME, DEL */ PressAndRelease(KEY_END); PressAndRelease(KEY_HOME, MODIFIERKEY_SHIFT); PressAndRelease(KEY_DELETE); } /* Erases previous login description and prints current one */ void PrintCurrentDescription() { ClearCurrentField(); /* Lets print our current position in the list and the total number of logins */ Keyboard.print(currentPos + 1); Keyboard.print("/"); Keyboard.print(LOGIN_COUNT); Keyboard.print(" "); Keyboard.print(logins[currentPos].description); } /* Navigates the login info array */ void NavigateDown() { currentPos++; if (currentPos >= LOGIN_COUNT) currentPos = 0; PrintCurrentDescription(); } /* Navigates the login info array */ void NavigateUp() { currentPos--; if (currentPos < 0) currentPos = LOGIN_COUNT - 1; PrintCurrentDescription(); } /* Prints login info */ void DoLogin() { ClearCurrentField(); Keyboard.print(logins[currentPos].userName); PressAndRelease(KEY_TAB); Keyboard.print(logins[currentPos].password); } /* Authenticates the user based on 'knock' sequence */ void DoAuthentication() { byte currentKey = 0; // key pressed (caps, num or scroll lock) if (Keyboard.led_numlock_on()) { delay(100); // user input messes up without this currentKey = KEY_NUM_LOCK; PressAndRelease(KEY_NUM_LOCK); } if (Keyboard.led_scrolllock_on()) { delay(100); // user input messes up without this currentKey = KEY_SCROLL_LOCK; PressAndRelease(KEY_SCROLL_LOCK); } if (Keyboard.led_capslock_on()) { delay(100); // user input messes up without this currentKey = KEY_CAPS_LOCK; PressAndRelease(KEY_CAPS_LOCK); } if (currentKey == 0) // User didn't press any keys this loop return; if (knockSeq[knockPos] == currentKey) { // is the sequence correct ? knockPos++; // correct, now ask for next key } else { knockPos = 0; // wrong sequence, start over knockFails++; if (knockFails >= LOCK_OUT_AFTER){ lockedOut = true; // game over. Unplug, plug in and try again // Keyboard.print("Better luck next time, foo"); } } if (knockPos >= sizeof(knockSeq)){ // user correctly entered the whole sequnce authenticated = true; PrintCurrentDescription(); } } /* Blinks the LED (code from BlinkWithoutDelay example) */ void BlinkLed(){ if (millis() - previousMillis > interval) { previousMillis = millis(); // save the last time you blinked the LED // if the LED is off turn it on and vice-versa: if (ledState == LOW) ledState = HIGH; else ledState = LOW; digitalWrite(ledPin, ledState); // set the LED with the ledState of the variable: } } /* ---------------------- Main loop ---------------------- */ void loop() { if (!Keyboard.isReady()) return; // can't run until usb stuff ready if (firstRun == true){ // also, on first run wait a bit so the drivers start working delay(1500); ClearLights(); // turn off num lock, caps lock and scroll lock firstRun = false; /* Let the user know we're ready by blinking twice */ digitalWrite(ledPin, HIGH); delay(100); digitalWrite(ledPin, LOW); delay(100); digitalWrite(ledPin, HIGH); delay(100); digitalWrite(ledPin, LOW); } if (lockedOut) // just exit if the user failed to correctly enter the knock sequence return; if (!authenticated){ // not authenticated ? DoAuthentication(); // then guess the knocks delay(100); return; // can't go further until authenticated } BlinkLed(); // blinks the led so user knows it's working /* Process input */ if (Keyboard.led_numlock_on()) { delay(100); // user input messes up without this NavigateDown(); PressAndRelease(KEY_NUM_LOCK); } if (Keyboard.led_scrolllock_on()) { delay(100); // user input messes up without this NavigateUp(); PressAndRelease(KEY_SCROLL_LOCK); } if (Keyboard.led_capslock_on()) { /* If we start typing immediately wierd screwups happen - password in uppercase (user hasn't released capslock yet?). Just to be safe wait for 200 ms */ delay(200); PressAndRelease(KEY_CAPS_LOCK); DoLogin(); } delay(100); } Tested on Win7 (x64), but since it's HID it should work anywhere. It would be cool if there was a way to easily edit the login info without needing to recompile. I was thinking about having two secret knocks - one to turn on the password manager and another to turn it into a flash drive. The passwords would be in a text file. Any ideas?
×
×
  • Create New...