Teensy and Slovenian Keyboard Layout

Recently we have had a project and we had to simulate attacks with social engineering. One of the attacks was also visiting a company as an IT administrator, gaining access to the premises and inserting a Teensy USB HID into desktop computer running Windows 7 or Windows 8.

It seemed an easy job at first, but we soon ran into trouble. We installed Arduino 1.0.5 software, which was the latest version supported by Teensyduino. We can see that if we visit the http://www.pjrc.com/teensy/td_download.html web page, it says: “Teensyduino supports Arduino 0023, 1.0.3, 1.0.4 & 1.0.5”. This is exactly why we’d chosen the latest version that was supported, namely 1.0.5. After installing Arduino and Teensyduino we started testing the “Hello World!” program, which was working without a problem. We also installed Kautilya, which provides already working scripts we can copy directly into Arduino, build them and upload them to the Teensy board. In the output below we can see the Windows payloads supported by Kautilya, which we can directly use.

 

888 d8P 888 d8b 888
888 d8P 888 Y8P 888
888 d8P 888 888
888d88K 8888b. 888 888 888888 888 888 888 888 8888b.
8888888b “88b 888 888 888 888 888 888 888 “88b
888 Y88b .d888888 888 888 888 888 888 888 888 .d888888
888 Y88b 888 888 Y88b 888 Y88b. 888 888 Y88b 888 888 888
888 Y88b “Y888888 “Y88888 “Y888 888 888 “Y88888 “Y888888
888
Y8b d88P
Pwnage with Human Interface Devices “Y88P”
Version 0.4.4
|..| Written By: Nikhil “SamratAshok” Mittal |..|
|..| Twitter: @nikhil_mitt |..|
|..| Bugs & Feedback: [email protected] |..|
|..| Code: http://code.google.com/p/kautilya/ |..|
|..| Blog: http://labofapenetrationtester.blogspot.com/ |..|

Kautilya is a toolkit to ease usage of Human Interface Devices in Pen Tests.
Tested on Teensy++ and Teensy 3.0 from pjrc.com.

Choose target OS from the menu below:
1. Payloads for Windows
2. Payloads for Linux
3. Payloads for Mac OS X
0. Exit Kautilya

Kautilya> 1

Choose a payload category from the menu below:
1. Add an admin user
2. Change the default DNS server
3. Edit the hosts file
4. Add a user and Enable RDP
5. Add a user and Enable Telnet
6. Forceful Browsing
7. Download and Execute
8. Sethc and Utilman backdoor
9. Gather Information
10. Hashdump and Exfiltrate
11. Keylog and Exfiltrate
12. Sniffer
13. Wireless Rogue AP
14. Browse and Accept Java Signed Applet
15. Connect to Hotspot and Execute code
16. Code Execution using Powershell
17. Time based payload execution
18. WLAN keys dump
19. Get Target Credentials
20. Code Execution using DNS TXT queries
21. Tracking Target Connectivity
22. Speak on Target
23. HTTP backdoor
24. DNS TXT Backdoor
25. Download and Execute PowerShell Script
26. Remove Update
27. Dump LSA Secrets
 

We immediately went for the payload number 25: “Download and Execute PowerShell Script” which downloads the Powershell script from the Internet and executes it; even more, it has the power to do so over configured default proxy in Windows. After choosing the payload 25, Kautilya generates the script, which we need to copy into Arduino; after that we need to compile it and upload it to the Teensy device, which is easy enough job, so we won’t describe it here. This was all done without any problems, but the sign that something was wrong was seen as soon as we plugged the Teensy board into Windows desktop computer set aside for testing purposes. The problem was that Teensy device didn’t do what it was supposed to do; instead it was opening all kinds of windows, producing a lot of errors, which made no sense at all.

We realized that this was because we had used the English keyboard Layout, but the system’s keyboard was set to Slovenian. Slovenian keyboard layout wasn’t even supported by Teensyduino, which was rather disappointing. But since we’re in Slovenia, we needed to have support for Slovenian keyboard, otherwise we would have to abandon the Teensy attack payload. Initially we searched the web for a solution, but didn’t find any, so we decided that we would implement the support ourselves.

The documentation on the Teensy source source code is very lacking, so we had some difficulties, but we managed to solve them by greping for pieces of code in hardware/teensy/ directory. We soon figured out that we needed to implement the support for Slovenian keyboard in keylayouts.h header file, which defines all the available keyboard layouts.

We started to look at an example US keyboard layout, which started to make sense after a while. We managed to identify the names of the keys being used by the US english keyboard, which are presented on the picture below. This was the ‘hard’ part of the job, where we had to manually identify which keys are which by trial and error.

picture

But since the keys at specified buttons are different on Slovenian keyboard, we had to change them accordingly. All the hard work of identifying the key names was already done, so we just had to lookup the keys for ASCII characters from 0x20-0xF7. All the changed keys are presented below for reference.

 

 #ifdef LAYOUT_SLOVENIAN

#define SHIFT_MASK 0x40
#define ALTGR_MASK 0x0080
#define KEY_NON_US_100 63
#define KEYCODE_TYPE uint8_t
#define ASCII_20 KEY_SPACE // 32
#define ASCII_21 KEY_1 + SHIFT_MASK // 33 !
#define ASCII_22 KEY_2 + SHIFT_MASK // 34 “
#define ASCII_23 KEY_3 + SHIFT_MASK // 35 #
#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $
#define ASCII_25 KEY_5 + SHIFT_MASK // 37 %
#define ASCII_26 KEY_6 + SHIFT_MASK // 38 &
#define ASCII_27 KEY_MINUS // 39 ‘
#define ASCII_28 KEY_8 + SHIFT_MASK // 40 (
#define ASCII_29 KEY_9 + SHIFT_MASK // 41 )
#define ASCII_2A KEY_EQUAL + SHIFT_MASK // 42 *
#define ASCII_2B KEY_EQUAL // 43 +
#define ASCII_2C KEY_COMMA // 44 ,
#define ASCII_2D KEY_SLASH // 45 –
#define ASCII_2E KEY_PERIOD // 46 .
#define ASCII_2F KEY_7 + SHIFT_MASK // 47 /
#define ASCII_30 KEY_0 // 48 0
#define ASCII_31 KEY_1 // 49 1
#define ASCII_32 KEY_2 // 50 2
#define ASCII_33 KEY_3 // 51 3
#define ASCII_34 KEY_4 // 52 4
#define ASCII_35 KEY_5 // 53 5
#define ASCII_36 KEY_6 // 54 6
#define ASCII_37 KEY_7 // 55 7
#define ASCII_38 KEY_8 // 55 8
#define ASCII_39 KEY_9 // 57 9
#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 :
#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ;
#define ASCII_3C KEY_NON_US_100 // 60 <
#define ASCII_3D KEY_0 + SHIFT_MASK // 61 =
#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 >
#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ?
#define ASCII_40 KEY_V + ALTGR_MASK // 64 @
#define ASCII_41 KEY_A + SHIFT_MASK // 65 A
#define ASCII_42 KEY_B + SHIFT_MASK // 66 B
#define ASCII_43 KEY_C + SHIFT_MASK // 67 C
#define ASCII_44 KEY_D + SHIFT_MASK // 68 D
#define ASCII_45 KEY_E + SHIFT_MASK // 69 E
#define ASCII_46 KEY_F + SHIFT_MASK // 70 F
#define ASCII_47 KEY_G + SHIFT_MASK // 71 G
#define ASCII_48 KEY_H + SHIFT_MASK // 72 H
#define ASCII_49 KEY_I + SHIFT_MASK // 73 I
#define ASCII_4A KEY_J + SHIFT_MASK // 74 J
#define ASCII_4B KEY_K + SHIFT_MASK // 75 K
#define ASCII_4C KEY_L + SHIFT_MASK // 76 L
#define ASCII_4D KEY_M + SHIFT_MASK // 77 M
#define ASCII_4E KEY_N + SHIFT_MASK // 78 N
#define ASCII_4F KEY_O + SHIFT_MASK // 79 O
#define ASCII_50 KEY_P + SHIFT_MASK // 80 P
#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q
#define ASCII_52 KEY_R + SHIFT_MASK // 82 R
#define ASCII_53 KEY_S + SHIFT_MASK // 83 S
#define ASCII_54 KEY_T + SHIFT_MASK // 84 T
#define ASCII_55 KEY_U + SHIFT_MASK // 85 U
#define ASCII_56 KEY_V + SHIFT_MASK // 86 V
#define ASCII_57 KEY_W + SHIFT_MASK // 87 W
#define ASCII_58 KEY_X + SHIFT_MASK // 88 X
#define ASCII_59 KEY_Z + SHIFT_MASK // 89 Y
#define ASCII_5A KEY_Y + SHIFT_MASK // 90 Z
#define ASCII_5B KEY_F + ALTGR_MASK // 91 [
#define ASCII_5C KEY_Q + ALTGR_MASK // 92
#define ASCII_5D KEY_G + ALTGR_MASK // 93 ]
#define ASCII_5E KEY_3 + ALTGR_MASK // 94 ^
#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _
#define ASCII_60 KEY_7 + ALTGR_MASK // 96 `
#define ASCII_61 KEY_A // 97 a
#define ASCII_62 KEY_B // 98 b
#define ASCII_63 KEY_C // 99 c
#define ASCII_64 KEY_D // 100 d
#define ASCII_65 KEY_E // 101 e
#define ASCII_66 KEY_F // 102 f
#define ASCII_67 KEY_G // 103 g
#define ASCII_68 KEY_H // 104 h
#define ASCII_69 KEY_I // 105 i
#define ASCII_6A KEY_J // 106 j
#define ASCII_6B KEY_K // 107 k
#define ASCII_6C KEY_L // 108 l
#define ASCII_6D KEY_M // 109 m
#define ASCII_6E KEY_N // 110 n
#define ASCII_6F KEY_O // 111 o
#define ASCII_70 KEY_P // 112 p
#define ASCII_71 KEY_Q // 113 q
#define ASCII_72 KEY_R // 114 r
#define ASCII_73 KEY_S // 115 s
#define ASCII_74 KEY_T // 116 t
#define ASCII_75 KEY_U // 117 u
#define ASCII_76 KEY_V // 118 v
#define ASCII_77 KEY_W // 119 w
#define ASCII_78 KEY_X // 120 x
#define ASCII_79 KEY_Z // 121 y
#define ASCII_7A KEY_Y // 122 z
#define ASCII_7B KEY_B + ALTGR_MASK // 123 {
#define ASCII_7C KEY_W + ALTGR_MASK // 124 |
#define ASCII_7D KEY_N + ALTGR_MASK // 125 }
#define ASCII_7E KEY_1 + ALTGR_MASK // 126 ~
#define ASCII_7F KEY_BACKSPACE // 127

#endif // LAYOUT_SLOVENIAN

 

We also needed to change hardware/teensy/boards.txt file to add new entry for Slovenian keyboard, which should be accessible in the Tools – Keyboard Layout of the Arduino IDE. We needed to add the following to the corresponding sections.

 

 teensy3.menu.keys.en-us.build.define1=-DLAYOUT_SLOVENIAN
teensy2.menu.keys.sl-sl.build.define1=-DLAYOUT_SLOVENIAN
teensy1.menu.keys.sl-sl.build.define1=-DLAYOUT_SLOVENIAN
teensypp2.menu.keys.sl-sl.build.define1=-DLAYOUT_SLOVENIAN
teensypp1.menu.keys.sl-sl.build.define1=-DLAYOUT_SLOVENIAN

 

Now that the keys were changed, we needed to compile them into Teensyduino itself. We searched the web for any documentation on the subject, but didn’t manage to find anything useful. Then we managed to find the Makefile inside the hardware/teensy/cores/teensy3/ directory and we entered the directory and executed make command after which the compilation was successful. That was easy.

After that we restarted arduino and the Slovenian keymap was present in the toolbar.

We compiled a new example seen below, which prints all the ASCII characters into the currently active window. We compiled the example and uploaded it to the Teensy.

 

 void setup() {
    delay(2000);
    Keyboard.println(“Teensy Slovenian Keyboard Layout Test”);
    delay(100);
    Keyboard.println(“Lowercase: abcdefghijklmnopqrstuvwxyz”);
    delay(100); 
    Keyboard.println(“Uppercase: ABCDEFGHIJKLMNOPQRSTUVWXYZ”);
    delay(100);
    Keyboard.println(“Numbers: 0123456789”);
    delay(100);
    Keyboard.println(“Symbols1: !\”#$%&'()*+,-./”);
    delay(100);
    Keyboard.println(“Symbols2: :;<=>?[\\]^_`{|}~”);
}

void loop() {}

 

Before plugging it into our Windows desktop computer, we started notepad.exe, so the above characters would be printed in there. Then we inserted the Teensy into the USB and watched the magic to happen. All the keys were printed correctly with the Slovenian keyboard set which can be seen below.

picture3

After that we normally used all the ASCII characters needed to execute arbitrary commands on the target computer using Teensy. We didn’t bother ourselves with actually presenting all Slovenian characters like č, ž, š, because they were not really needed to exploit the target system.

Implementation of the Slovenian keyboard was necessary if we were to successfully meet the project goals.

Posted by Dejan Lukanon14.10.2013