Rubber Ducky Multipayload Barato con Adafruit Neo Trinkey
Cómo crear paso a paso un Rubber Ducky multipayload con Adafruit Neo Trinkey por menos de 10$
Dentro de la comunidad de hacking es muy conocida la página Hak5 por la cantidad de herramientas relacionadas con la ciberseguridad que posee. Dentro de su catálogo podemos encontrarnos desde herramientas para auditoría wifi, como puede ser el Wifi Pineapple, hasta dispositivos de captura de datos, como puede ser el Key Croc, que es un keylogger con herramientas que permiten realizar acciones remotas sobre el equipo conectado.
Dentro de la cetagorización de "HOTPLUG ATTACKS" nos encontramos con el USB Rubber Ducky. Este dispositivo, de conectarse a un equipo, se comporta como un teclado y manda las señales de las teclas programadas previamente (a lo que llamamos payload) como si alguien estuviera escribiendo, pero a máxima velocidad. Esto nos permite automatizar una tarea que podría llevar varios minutos en segundos, pudiendo ejecutar una gran cantidad de comandos en muy poco tiempo. Además, los teclados son dispositivos confiables por defecto por lo que el sistema operativo no suele poner ningún problema a la hora de usar este tipo de herramientas.
El principal problema que tenemos con este dispositivo es, por un lado, su precio, ya que se encuentra alrededor de los 80$ en la página oficial. Por otro lado, sólo puede tener configurado un payload al mismo tiempo, por lo que si queremos usar otro payload hay que borrar el anterior no pudiendo tener varios configurados al mismo tiempo.
La idea
Investigando por la tienda de hardware Adafruit encontré un dispositivo que me llamó mucho la atención, el Adafruit Neo Trinkey - SAMD21 USB Key with 4 NeoPixels. Este dispositivo, que vale apenas 7$, nos proporciona en una placa minúscula (12mm x 32mm) con puerto USB, 4 LEDs, 2 pads táctiles, 256KB de memoria flash, y puede programarse tanto con Arduino como con Circuit Python. Para rematar indica que puede ser usado como Keyboard/Mouse HID, por lo que podemos hacer que se comporte como un teclado.
Esta pequeña placa nos ofrece todo lo que necesitamos para programar nuestro propio Rubber Ducky multipayload. La idea es la siguiente:
- Usar los 4 LEDs para dar información visual del payload seleccionado.
- Usar uno de los pads táctiles para cambiar de payload
- Usar el otro de los pads para ejecutar el payload
De esta forma podemos interactuar de manera rápida con el dispositivo, elegir el payload que se ajuste a la situación, y ejecutarlo sin necesidad de reprogramarlo.
Manos a la obra
Lo primero que tenemos que tenemos que hacer es instalar Circuit Python en la placa. Para ello descargamos la última versión de la página página de Circuit Python:
Tras decargar el fichero, hay que conectar el Neo Trinkey al equipo y, una vez esté arrancado presionamos 2 veces el botón de reset. Esto debería hacer que apareciera el dispositivo TRINKEYBOOT como conectado (en caso de no ser así repetir, a veces no ocurre a la primera). Tras esto hay que copiar el fichero adafruit-circuitpython-neopixel_trinkey_m0-**-*.*.*.uf2
en ese dispositivo. Tras esto los leds parpadearán y aparecerá el dispositivo CIRCUITPY. Con esto lo tendremos preparado para ejecutar nuestro programa en Python.
Tras esto, lo siguiente que tenemos que hacer es descargar la libraría adafruit_ducky.mpy
. Pare ello vamos a la sección de librerías de Circuit Python y descargamos el bundle correspondiente a la versión de Circuit Python que hemos instalado:
Una vez descargado, descomprimimos el .zip
, entramos en la carpeta lib
y copiamos el fichero adafruit_ducky.mpy
dentro de nuestra placa, en CIRCUITPY/lib/
(puede que sea necesario crear esta carpeta si no existía anteriormente).
Ahora ya temos nuestro Neo Trinkey preaparado para ejecutar Python y la librería que es capaz de convertir nuestro payload en DuckyScript (así es como se llama el lenguaje de scripting con lo que se van a generar los payloads) a pulsaciones de teclado, así que ahora es hora de escribir nuestro programa en Python que orqueste todo esto.
Lo primero que tenemos que hacer es crear nuestros payloads. Para eso vamos a crear una carpeta payloads
con 3 payloads dentro, dentro de la carpeta del dispositivo CIRCUITPY
. La estructura de carpetas debe quedar de la siguiente forma:
CIRCUITPY ├── code.py ├── lib │ └── adafruit_ducky.mpy └── payloads ├── payload_bbgg.txt ├── payload_rrbb.txt └── payload_rrrr.txt
Del fichero code.py
nos olvidamos de momento, y nos centramos en los payloads. Como se puede ver en los nombres, todos tienen un sufijo precedido por _
. Este sufijo es el que va a indicar los colores de los leds cuando ese payload esté seleccionado, así que es importante que todos los payloads lo tenga, y que no se repita esa secuencia en ningún payload. En este ejemplo, sólo están disponibles los siguientes colores (puedes modificar el código si quieres otros o más colores):
- r: rojo
- g: verde
- b: azul
Detro de cada payload vamos a poner lo siguiente reemplazando color_code
por el patrón de color elegido en el nombre del fichero:
STRING Hello World <color_code>
Ahora ya sólo queda programar nuestro script en Python. El script que ejecuta Circuit Python al iniciarse es el fichero code.py
, así que ahí es donde tenemos que introducir nuestro código (los comentarios son meramente explicativos, recomiendo quitarlos ya que después de instalar Circuit Python apenas quedan 48KB de espacio libre para nuestro programa y los payloads):
import time import os import usb_hid from adafruit_hid.keyboard import Keyboard from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS import adafruit_ducky import touchio import board import neopixel # Specifies payloads folder and color mappings payloads_folder = 'payloads' colors_mappings = { 'r': 0xFF0000, 'g': 0x00FF00, 'b': 0x0000FF } # Inits touchpads and LEDs touch1 = touchio.TouchIn(board.TOUCH1) touch2 = touchio.TouchIn(board.TOUCH2) pixels = neopixel.NeoPixel(board.NEOPIXEL, 4) # Switch of LEDs and decrease brightness pixels.fill((0x000000)) pixels.brightness = 0.05 # Sleep 1s to avoid a race condition on some systems time.sleep(1) # Inits keyboard interface (US layout) keyboard = Keyboard(usb_hid.devices) keyboard_layout = KeyboardLayoutUS(keyboard) # Blinks to indicate that is ready pixels.fill((0xFFFFFF)) time.sleep(0.1) pixels.fill((0x000000)) time.sleep(0.1) pixels.fill((0xFFFFFF)) time.sleep(0.1) pixels.fill((0x000000)) # Gets hexa colors from payload name def get_payload_color(payload_file_name): color_code = payload_file_name.split('_')[-1].split('.')[0] colors = [] for key_color_code in color_code: colors.append(colors_mappings[key_color_code]) return colors # Sets LEDs colors based on selected payload def set_leds_colors(): for led_index in range(4): led_color = payloads[selected_payload]['colors'][led_index] pixels[led_index] = led_color # Generates an array with payloads with their colors payloads_file_names = os.listdir(payloads_folder) payloads = [] for payload_file_name in payloads_file_names: payload = { 'path': payloads_folder + '/' + payload_file_name, 'colors': get_payload_color(payload_file_name) } payloads.append(payload) # Select first payload and set LEDs colors selected_payload = 0 set_leds_colors() # Needs touched times to avoid false positives touched = time.monotonic() # Indicates if adafruit ducky is running is_running = False while True: if is_running: # Run next line from payload is_running = duck.loop() continue if time.monotonic() - touched < 0.25: # False positive touch continue if touch1.value: # Select next payload and set LEDs colors selected_payload = (selected_payload + 1) % len(payloads) set_leds_colors() touched = time.monotonic() if touch2.value: # start running the selected payload duck = adafruit_ducky.Ducky( payloads[selected_payload]['path'], keyboard, keyboard_layout ) is_running = True touched = time.monotonic()
Tras esto, y si no se ha cometido ningún error en el proceso, ya tendríamos listo nuestro Rubber Ducky multipayload. Al conectarlo al ordenador deberían encenderse los LEDs en base al payload seleccionado (incialmente el primer fichero de la carpeta payloads
) y, al hacer click en el pad táctil más lejano del botón de reset, los LEDs deberían cambiar indicando el payload actual seleccionado. Una vez seleccionado el payload haciendo click en el pad táctil más cercano al botón de reset debería empezar a escribir siguiendo las instrucciones del payload.
El código del programa lo puedes encontrar en el siguiente respositorio: