mercoledì 13 gennaio 2021

Sniffaggio traffico wifi drone - 1° parte

Ordunque, primo velocissimo studio preliminare sniffando il traffico dati dalla connessione wifi dell'RC-Drone e l'apps YX Wifi.

Lo scopo è quello di estrarre dal drone qualche foto mentre vola, non di riscrivere l'apps. È possibile che il protocollo CTP sotto descritto venga usato da parecchi altri droni e sistemi di retrocamere per auto.

Procedura tipica:

  • accendere il drone; compare una nuova rete wifi ("M8_4k_aabbcc", dove aabbcc è l'identificativo in esadecimale del drone);
  • connettere il tablet/cellulare a tale wifi (aperta e senza password); quindi avviare l'apps YX Wifi; nella prima schermata si vedrà in alto a sinistra il nome della wifi, in basso a destra il tasto Start;
  • pigiare su Start e attendere la schermata nera con le icone;
  • pigiare sull'icona in alto a destra per srotolare il sottomenu in alto; pigiare quindi sull'icona a forma di due rettangoli affiancati per abilitare entrambe le videocamere;
  • sulla destra dello schermo dovrebbe comparire live-stream della videocamera frontale.
Preparazione per sniffare il traffico:
  • decidere quale interfaccia wifi utilizzare; qui di seguito userò wlp2s0b1
  • configurare il NetworkManager per ignorarla, modificando il file /etc/NetworkManager/NetworkManager.conf e aggiungendo le righe:
    [keyfile]
    unmanaged-devices=interface-name:wlp2s0b1
  • riavviare il NetworkManager:
    sudo systemctl restart NetworkManager
  • disattivare l'interfaccia:
    sudo ip link set wlp2s0b1 down
  • abilitarvi il monitoring del traffico wifi:
    sudo iwconfig wlp2s0b1 mode monitor
  • riattivare l'interfaccia:
    sudo ip link set wlp2s0b1 up
  • scegliere il canale wifi del drone (cioè 1):
    sudo iwconfig wlp2s0b1 channel 1
  • avviare Wireshark e sniffare da quell'interfaccia.

Prime scoperte:

  • il "master" della situazione è il drone; l'apps si comporta da client; nella rete il drone è 192.168.80.1, il primo client riceve l'indirizzo 192.168.80.2
  • il drone manda autonomamente la sua configurazione JSON sulla porta UDP 3889 in broadcast (notare l'UUID fittizio e il chipset di una "wifi car camera"):
    MSSDP_NOTIFY {"app_list": {"match_android_ver": ["1.0","2.0"],"match_ios_ver": ["1.0","2.0"]},"forward_support": ["0","1"],"behind_support": ["0"],"forward_record_support": ["0","1"],"behind_record_support": ["0"],"rtsp_forward_support": ["0","1"],"rtsp_behind_support": ["0"],"device_type": "1","net_type": "0","rts_type": "0","product_type": "AC521x_wifi_car_camera","support_projection":"0","firmware_version": "229.13.H0T08.JY03","products_model": "0","products_version": "2","camera_type": "1","videc_size": "1","videc_save": "2","photo_size": "3","videc_EIS": "0","match_app_type": "DVRunning 2","uuid": "xxxxxx"}
  • il client si connette alla porta TCP 3333 del drone, e questi gli comincia a rispondere nel bizzarro formato "CTP:" descritto sotto;
  • client e drone si scambiano pacchetti UDP sulla porta 3456, con un payload generalmente di 10 bytes, sembrerebbe significare un ACK di comandi inviati altrove. Dal drone di solito partono una o due sequenze hex 66 28 00 00 00 00 00 00 00 28, mentre dal client partono tutti zeri.

Il formato CTP consiste di una serie di sequenze in questo formato:

  • i quattro caratteri CTP:
  • lunghezza del comando (2 bytes, less significant first)
  • comando; per esempio: KEEP_ALIVE_INTERVAL
  • lunghezza dei parametri (4 bytes, less significant first)
  • parametri in formato JSON; per esempio: {"op":"NOTIFY","param":{"timeout":"60000"}}

Stream video:

  • il client si connette alla porta 2229 del drone per attivarne la telecamera. Il comando usato è OPEN_RT_STREAM con parametri {"op":"PUT","param":"{"format":"0","h":"720","w":"1280","fps":"15"}
  • il drone risponde prima con l'ACK UDP sopra descritto (66 28 00 00...) e quindi inizia a mandare dalla porta TCP 2229 i frame video in formato JFIF JPEG (ff d8 ff e0 00 11 "JFIF" 00 01...)
  •  ...

Stringhe comandi rilevate:

  • {"op":"GET"}
    {"op":"GET","param":{"status":"0"}}
  • {"op":"NOTIFY","errno":2,"param":{"msg":"CTP_SD_OFFLINE_MSG"}}
    {"op":"NOTIFY","errno":6,"param":{"msg":"CTP_NO_TOPIC_MSG"}}
    {"op":"NOTIFY","param":{"aff":"0"}}
    {"op":"NOTIFY","param":{"bsd":"0"}}
    {"op":"NOTIFY","param":{"bvo":"1"}}
    {"op":"NOTIFY","param":{"dat":"0"}}
    {"op":"NOTIFY","param":{"date":"20210115205742"}}
    {"op":"NOTIFY","param":{"format":"0","w":"1280","h":"720","fps":"15","rate":"8000"}}
    {"op":"NOTIFY","param":{"fre":"50"}}
    {"op":"NOTIFY","param":{"fsd":"0"}}
    {"op":"NOTIFY","param":{"fsd":"1"}}
    {"op":"NOTIFY","param":{"gap":"0"}}
    {"op":"NOTIFY","param":{"gra":"2"}}
    {"op":"NOTIFY","param":{"kvo":"1"}}   
    {"op":"NOTIFY","param":{"lag":"1"}}   
    {"op":"NOTIFY","param":{"level":"4"}}
    {"op":"NOTIFY","param":{"mic":"1"}}
    {"op":"NOTIFY","param":{"mot":"0"}}
    {"op":"NOTIFY","param":{"online":"0"}}
    {"op":"NOTIFY","param":{"par":"0"}}
    {"op":"NOTIFY","param":{"pro":"0"}}
    {"op":"NOTIFY","param":{"qua":"2"}}
    {"op":"NOTIFY","param":{"res":"1"}}
    {"op":"NOTIFY","param":{"rtb":"2"}}
    {"op":"NOTIFY","param":{"rtf":"1"}}
    {"op":"NOTIFY","param":{"ssid":"M8_4k_fffa1b","pwd":"(null)"}}
    {"op":"NOTIFY","param":{"ssid":"pwd:"}}
    {"op":"NOTIFY","param":{"status":"0"}}
    {"op":"NOTIFY","param":{"status":"1"}}
    {"op":"NOTIFY","param":{"status":"1","h":"480","w":"640","fps":"15","rate":"8000","format":"1"}}
    {"op":"NOTIFY","param":{"storage/sd2/C/":"(null)"}}
    {"op":"NOTIFY","param":{"timeout":"60000"}}   
    {"op":"NOTIFY","param":{"tvm":"0"}}
    {"op":"NOTIFY","param":{"type":"0","ver":"26"}}
    {"op":"NOTIFY","param":{"w":"640","h":"480","format":"0","fps":"15","rate":"8000"}}
    {"op":"NOTIFY","param":{"wind_velocity":"0"}}
  • {"op":"PUT"}
    {"op":"PUT","param":{"dat":"0"}}
    {"op":"PUT","param":{"DRONE_DATA":"6614808080800100000000000000000000000199"}}
    {"op":"PUT","param":{"FLIP_VALUE":"0"}}
    {"op":"PUT","param":{"format":"0","h":"720","w":"1280","fps":"15"}}

Dunque, abbiamo lato client un comando "PUT" per inviare comandi al drone (quel DRONE_DATA mi sembra un intero file di configurazione), mentre il drone invia delle "NOTIFY" (inclusa la segnalazione di errori da parte dell'app client).

Nessun commento:

Posta un commento