Una nuova applicazione...parente stretta di Abetone Trail Park. Ho scoperto che adesso si possono sottomettere al PlayStore solo app con minSDK >=26...il che vuole dire che mi sono giocato circa l'80% del pubblico
lunedì 15 ottobre 2018
mercoledì 26 settembre 2018
DeAuth WiFi Clients con ESP8266
Questo e' un progettino semplice e veloce che pero' mi risolve un problema familiare.
Sono in costante battaglia con mio figlio che passa il tempo sul divano a guardare Youtube sul divano. Quando esagera (e se non bastano un paio di avvisi) gli stacco l'antenna WiFi bloccando pero' tutti gli altri client connessi
Ho scoperto che e' possibile forzare la disconnessione di un client mandando dei pacchetti di DeAutorizzazione DeAuth all'Access Point. Tale pratica peraltro sembra che sia legittima ed insita all'interno del protocollo WiFi e quindi non evitabile
In pratica si prende un comune NodeMCU con ESP 82666 e si installa il firmware esp8266_deauther
si scarica il file a questo indirizzo
https://github.com/spacehuhn/esp8266_deauther/releases/download/v2.0.5/ESP8266_Deauther_v2.0.5_DSTIKE_Deauther_v3_._DSTIKE_NodeMCU-07_v2.bin
per comodita' lo ho rinominato esp8266.bin, poi si installa il file .bin con il seguente comando
esptool.py -p /dev/ttyUSB3 write_flash -fm qio 0x0000 esp8266.bin
Sono in costante battaglia con mio figlio che passa il tempo sul divano a guardare Youtube sul divano. Quando esagera (e se non bastano un paio di avvisi) gli stacco l'antenna WiFi bloccando pero' tutti gli altri client connessi
Ho scoperto che e' possibile forzare la disconnessione di un client mandando dei pacchetti di DeAutorizzazione DeAuth all'Access Point. Tale pratica peraltro sembra che sia legittima ed insita all'interno del protocollo WiFi e quindi non evitabile
In pratica si prende un comune NodeMCU con ESP 82666 e si installa il firmware esp8266_deauther
si scarica il file a questo indirizzo
https://github.com/spacehuhn/esp8266_deauther/releases/download/v2.0.5/ESP8266_Deauther_v2.0.5_DSTIKE_Deauther_v3_._DSTIKE_NodeMCU-07_v2.bin
per comodita' lo ho rinominato esp8266.bin, poi si installa il file .bin con il seguente comando
esptool.py -p /dev/ttyUSB3 write_flash -fm qio 0x0000 esp8266.bin
ci si collega poi all'AP di nome pwned con password deauther (questi nomi possono essere modificati ricompilando il firmware da sorgenti) all'indirizzo 192.168.4.1
Si effettua la scansione degli AP visibili (Scan APS sulla prima pagina dopo il disclaimer) e si seleziona la stazione su cui si voglio deautorizzare i client (si vede il segno di spunta).
Attenzione: la risposta del 8266 e' molto molto lenta
si passa poi al tab Attack e si sceglie l'operazione da effettuare (Start/Stop)
martedì 25 settembre 2018
Captive Portal su Raspberry Pi Zero W
Un esempio di Captive Portal (ovvero un Access Point WiFi che obbliga gli utenti a visualizzare determinate pagine, sia per loggarsi per l'accesso ad internet sia per altri accedere ad un web server interno)
La Raspberry Pi Zero W, non avendo due schede di rete di default come la 3b+, non puo' essere usata per fornire accesso ad internet come router
Per prima cosa si deve installare sulla SD una Raspbian Lite . Dato l'uso in HeadLess mode e' necessario configurare la scheda via SSH, non abilitata di default tramite la porta USB OTG, non abilitata di default
Una volta formattata la scheda SD si monta la partizione boot e
1) si inserisce un file vuoto denominato ssh (senza estensione)
2) si modifica il file config.txt aggiungendo una ultima riga con scritto dtoverlay=dwc2
3) si modifica il file cmdline.txt aggiungendo modules-load=dwc2,g_ether subito dopo rootwait
Fatto cio' si inserisce la SD nella Raspberry e si collega un cavo microUSB nella porta posta piu' centralmente collegando l'altro cavo al PC (l'alimentazione e' data dallo stesso cavo e non e' necessario di collegare la seconda USB)
A questo punto da PC (Linux o Mac) si puo' entrare in shell mediante SSH con il comando
ssh pi@raspberrypi.local
password : raspberry
si passa quindi a configurare la connessione WiFi per l'aggiornamento dei pacchetti con
sudo raspi-config
opzione Netowork Options/Wifi dove si inseriscono i dati dell'Acces Point
si aggiorna il sistema e si installano i pacchetti
apt-get install hostapd dnsmasq apache2 php7.0
(questa configurazione e' stata ripresa da qui togliendo la parte malevola)
rc.local
-----------------------------------------------------------
La Raspberry Pi Zero W, non avendo due schede di rete di default come la 3b+, non puo' essere usata per fornire accesso ad internet come router
Per prima cosa si deve installare sulla SD una Raspbian Lite . Dato l'uso in HeadLess mode e' necessario configurare la scheda via SSH, non abilitata di default tramite la porta USB OTG, non abilitata di default
Una volta formattata la scheda SD si monta la partizione boot e
1) si inserisce un file vuoto denominato ssh (senza estensione)
2) si modifica il file config.txt aggiungendo una ultima riga con scritto dtoverlay=dwc2
3) si modifica il file cmdline.txt aggiungendo modules-load=dwc2,g_ether subito dopo rootwait
Fatto cio' si inserisce la SD nella Raspberry e si collega un cavo microUSB nella porta posta piu' centralmente collegando l'altro cavo al PC (l'alimentazione e' data dallo stesso cavo e non e' necessario di collegare la seconda USB)
A questo punto da PC (Linux o Mac) si puo' entrare in shell mediante SSH con il comando
ssh pi@raspberrypi.local
password : raspberry
si passa quindi a configurare la connessione WiFi per l'aggiornamento dei pacchetti con
sudo raspi-config
opzione Netowork Options/Wifi dove si inseriscono i dati dell'Acces Point
si aggiorna il sistema e si installano i pacchetti
apt-get install hostapd dnsmasq apache2 php7.0
(questa configurazione e' stata ripresa da qui togliendo la parte malevola)
rc.local
-----------------------------------------------------------
service apache2 start sleep 1 hostapd -B /etc/hostapd/hostapd.conf sleep 2 ifconfig br0 up ifconfig br0 10.1.1.1 netmask 255.255.255.0 sysctl net.ipv4.ip_forward=1 iptables --flush iptables -t nat --flush iptables -t nat -A PREROUTING -i br0 -p udp -m udp --dport 53 -j DNAT --to-destination 10.1.1.1:53 iptables -t nat -A PREROUTING -i br0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.1.1.1:80 iptables -t nat -A PREROUTING -i br0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 10.1.1.1:80 iptables -t nat -A POSTROUTING -j MASQUERADE service dnsmasq start exit 0 ----------------------------------------------------------- hostapd.conf -----------------------------------------------------------
dnsmasq.conf ------------------------------------------------------------
|
venerdì 21 settembre 2018
Leaflet JS e GeoJSon
Alcune volte mi capita di dover convertire delle tracce GPX per visualizzarle con LeafletJS.
In generale il primo lavoro e' quello di rimuovere il dato di quota tramite la app (opzione flatten)
https://wtracks.appspot.com/
per poi semplificare il percorso mediante
https://github.com/stefanocudini/gpx-simplify-optimizer
a questo punto rimane l.ultimo problema...ovvero che il formato GeoJSon usa il formato [lon,lat] mentre Leaflet usa [lat,lon]
per convertire i dati nel giusto formato e formattarli in un array javascript per poterli incollare nell'oggetto ployline di Leaflet ho scritto questo semplice codice che usa la libreria Python GeoJson (pip install geojson)
-------------------------------------------------------------------------------------------
import geojson
with open('svizzera_flat_1069nodes.geojson') as f:
data = geojson.load(f)
for feature in data['features']:
#print feature['geometry']['type']
#print feature['geometry']['coordinates']+'\n'
coo = feature['geometry']['coordinates']
for p in coo: print "["+str(p[1]) + "," + str(p[0])+"],"
In generale il primo lavoro e' quello di rimuovere il dato di quota tramite la app (opzione flatten)
https://wtracks.appspot.com/
per poi semplificare il percorso mediante
https://github.com/stefanocudini/gpx-simplify-optimizer
a questo punto rimane l.ultimo problema...ovvero che il formato GeoJSon usa il formato [lon,lat] mentre Leaflet usa [lat,lon]
per convertire i dati nel giusto formato e formattarli in un array javascript per poterli incollare nell'oggetto ployline di Leaflet ho scritto questo semplice codice che usa la libreria Python GeoJson (pip install geojson)
-------------------------------------------------------------------------------------------
import geojson
with open('svizzera_flat_1069nodes.geojson') as f:
data = geojson.load(f)
for feature in data['features']:
#print feature['geometry']['type']
#print feature['geometry']['coordinates']+'\n'
coo = feature['geometry']['coordinates']
for p in coo: print "["+str(p[1]) + "," + str(p[0])+"],"
mercoledì 12 settembre 2018
Unbox GPS Tracker K8
Mi e' stato prestato un il GPS Tracker K8 perche' non presenta segni di vita. Ho provato a smontarlo per vedere se riuscivo a trovare qualche connettore di programmazione o seriale da cui poter interagire
In generale l'interazione avviene attravero una App FindME (che chiede peraltro permessi per nulla giustificati per esempio al GPS, alla fotocamera od al microfono) oppure inviando SMS alla numero della SIM interna. Da quanto risulta dalla scheda tecnica il posizionamento avviene tramite GPS o LBS (nel secondo caso i dati sono gestiti da un server esterno per la triangolazione delle antenne). La connessione non avviene direttamente tra il telefono ed il tracker ma tramite il server remoto della ditta produttrice via rete dati
Per aprire si alzano i due coperchi (in realta' quello giusto e' quello privo dell'adesivo dell'IMEI).Il disco metallico e' la calamita che e' incollata sopra la scheda
All'interno c'e' una LiPo da 380 mAh posta al di sotto della scheda. Nell'angolo in alto a destra della foto soprastante si vede un cubetto di colore piu' chiaro. Corrisponde al microfono. Sulla sinistra sulla flat di colore marrone ci sono i due led verde e rosso
Una volta rimossa la calamita e l'adesivo si osserva la scritta XMG001-E-GPS con sottostante quella che sembra la data di produzione. La parte superiore dell'integrato e' schermata da un coperchio metallico mentre al di sotto c'e' l'alloggiamento della SIM. Sono inoltre connesse due antenne s
Alla fine non sono riuscito a trovare nessuna connesione di debug.....ci sono delle piazzole libere sul pcb ma sono minuscole e senza scritte
PS ho controllato l'IMEI e non sembra un codice valido con lo schema ufficiale (il codice di controllo non risulta valido). Fra le altre cose ho scoperto che l'IMEI dei dispositivi e' di tipo prevedibile (non e' difficile forgiare un IMEI valido) e visto che ll'IMEI e' la username per il cloud e la password di default e' 123456 non e' difficile fare scherzi a utenti che non hanno modificato la password di default
In generale l'interazione avviene attravero una App FindME (che chiede peraltro permessi per nulla giustificati per esempio al GPS, alla fotocamera od al microfono) oppure inviando SMS alla numero della SIM interna. Da quanto risulta dalla scheda tecnica il posizionamento avviene tramite GPS o LBS (nel secondo caso i dati sono gestiti da un server esterno per la triangolazione delle antenne). La connessione non avviene direttamente tra il telefono ed il tracker ma tramite il server remoto della ditta produttrice via rete dati
Per aprire si alzano i due coperchi (in realta' quello giusto e' quello privo dell'adesivo dell'IMEI).Il disco metallico e' la calamita che e' incollata sopra la scheda
All'interno c'e' una LiPo da 380 mAh posta al di sotto della scheda. Nell'angolo in alto a destra della foto soprastante si vede un cubetto di colore piu' chiaro. Corrisponde al microfono. Sulla sinistra sulla flat di colore marrone ci sono i due led verde e rosso
Una volta rimossa la calamita e l'adesivo si osserva la scritta XMG001-E-GPS con sottostante quella che sembra la data di produzione. La parte superiore dell'integrato e' schermata da un coperchio metallico mentre al di sotto c'e' l'alloggiamento della SIM. Sono inoltre connesse due antenne s
Alla fine non sono riuscito a trovare nessuna connesione di debug.....ci sono delle piazzole libere sul pcb ma sono minuscole e senza scritte
PS ho controllato l'IMEI e non sembra un codice valido con lo schema ufficiale (il codice di controllo non risulta valido). Fra le altre cose ho scoperto che l'IMEI dei dispositivi e' di tipo prevedibile (non e' difficile forgiare un IMEI valido) e visto che ll'IMEI e' la username per il cloud e la password di default e' 123456 non e' difficile fare scherzi a utenti che non hanno modificato la password di default
ESP32 Lolin Lite Captive Portal
Dopo il Wemos TTGO ho provato Lolin 32 Lite. Nonostante sia un prodotto non piu' in produzione risulta interessante
I driver per la seriale virtuale sono relativi al CH340
Da misure fatte da altre persone sembra che il consumo sia di circa 800 microA in sleep mode e di circa 50 mA in modalita' normale
Una delle caratteristiche piu' interessanti e' che si puo' alimentare tramite una LiPo tramite JST PH-2 2.0mm e c'e' montato anche un circuito di ricarica che, nel caso di collegamento USB, va a ricaricare la LiPo
Ho provato a montare lo skect ESP32 di Captive Portal (negli esempi sotto DNSServer) ma per rendere la cosa non banale ho provato ad inserire una immagine nella home. Di fatto non esiste un file system e per includere la img ho preso un file (a caso ;>), lo ho convertito in BASE 64 tramite questa pagina e poi ho incollato la conversione nello sketch come segue
------------------------------------------------------------------
#include <WiFi.h>
#include <DNSServer.h>
const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
WiFiServer server(80);
String responseHTML = ""
"<!DOCTYPE html><html><head><title>CaptivePortal</title></head><body>"
"<h1>Hello World!</h1><p>This is a captive portal example. <br>"
"<img src='data:image/jpg;base64,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'/>"
"</body></html>";
void setup() {
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
WiFi.softAP("CaptivePortal");
// if DNSServer is started with "*" for domain name, it will reply with
// provided IP to all DNS request
dnsServer.start(DNS_PORT, "*", apIP);
server.begin();
}
void loop() {
dnsServer.processNextRequest();
WiFiClient client = server.available(); // listen for incoming clients
if (client) {
String currentLine = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n') {
if (currentLine.length() == 0) {
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
client.print(responseHTML);
break;
} else {
currentLine = "";
}
} else if (c != '\r') {
currentLine += c;
}
}
}
client.stop();
}
}
---------------------------------------------------------
Il risultato e' il seguente
I driver per la seriale virtuale sono relativi al CH340
Da misure fatte da altre persone sembra che il consumo sia di circa 800 microA in sleep mode e di circa 50 mA in modalita' normale
Una delle caratteristiche piu' interessanti e' che si puo' alimentare tramite una LiPo tramite JST PH-2 2.0mm e c'e' montato anche un circuito di ricarica che, nel caso di collegamento USB, va a ricaricare la LiPo
Ho provato a montare lo skect ESP32 di Captive Portal (negli esempi sotto DNSServer) ma per rendere la cosa non banale ho provato ad inserire una immagine nella home. Di fatto non esiste un file system e per includere la img ho preso un file (a caso ;>), lo ho convertito in BASE 64 tramite questa pagina e poi ho incollato la conversione nello sketch come segue
------------------------------------------------------------------
#include <WiFi.h>
#include <DNSServer.h>
const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
WiFiServer server(80);
String responseHTML = ""
"<!DOCTYPE html><html><head><title>CaptivePortal</title></head><body>"
"<h1>Hello World!</h1><p>This is a captive portal example. <br>"
"<img src='data:image/jpg;base64,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'/>"
"</body></html>";
void setup() {
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
WiFi.softAP("CaptivePortal");
// if DNSServer is started with "*" for domain name, it will reply with
// provided IP to all DNS request
dnsServer.start(DNS_PORT, "*", apIP);
server.begin();
}
void loop() {
dnsServer.processNextRequest();
WiFiClient client = server.available(); // listen for incoming clients
if (client) {
String currentLine = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n') {
if (currentLine.length() == 0) {
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
client.print(responseHTML);
break;
} else {
currentLine = "";
}
} else if (c != '\r') {
currentLine += c;
}
}
}
client.stop();
}
}
---------------------------------------------------------
Il risultato e' il seguente
venerdì 7 settembre 2018
Wemos TTGO Wifi BT ESP32
Questa scheda di sviluppo integrata diversi aspetti interessanti: un microprocessore ESP32, WiFi, Bluetooth 4,schermo OLED SSD1306 da 0.96" ed un alloggiamento per una batteria LiPo tipo 18650 con circuito di ricarica integrato
Per aggiungere la scheda all'Arduino IDE si deve scaricare il pacchetto
https://dl.espressif.com/dl/package_esp32_index.json
inoltre potrebbero essere necessari i driver per la porta seriale via USB scaricabili da qui
https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers
Questo e' invece un semplice WiFi Scanner (unione di due esempi) che mostra i dati a display
Per aggiungere la scheda all'Arduino IDE si deve scaricare il pacchetto
https://dl.espressif.com/dl/package_esp32_index.json
inoltre potrebbero essere necessari i driver per la porta seriale via USB scaricabili da qui
https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers
Questo e' il pinout della scheda
Una cosa che mi ha fatto impazzire e' che nonostante questi settaggi abbastanza conservativi non riuscivo a fare l'upload sulla scheda (con il messaggio di errore
A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header
Il trucco e' quello di premere il pulsante di Boot al momento di fare l'upload
Le connessioni dell'ESP 32 con l'OLED sono attraverso i seguenti pin
Una cosa che mi ha fatto impazzire e' che nonostante questi settaggi abbastanza conservativi non riuscivo a fare l'upload sulla scheda (con il messaggio di errore
A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header
Il trucco e' quello di premere il pulsante di Boot al momento di fare l'upload
Le connessioni dell'ESP 32 con l'OLED sono attraverso i seguenti pin
SCL - Pin 4
SDA - Pin 5
La libreria per controllare l'OLED si puo' scaricare da qui . I programmi di esempio della libreria devono essere modificati (per esempo SSD1306SimpleDemo) cosi'
-----------------------------------------------
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`
#include "images.h"
SSD1306 display(0x3c, 5, 4);
#define DEMO_DURATION 3000
typedef void (*Demo)(void);
-----------------------------------------------
----------------------------------------------
#include "WiFi.h"
#include "SSD1306.h"
SSD1306 display(0x3c, 5, 4);
void setup()
{
pinMode(16,OUTPUT);
digitalWrite(16, LOW);
delay(50);
digitalWrite(16, HIGH);
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
Serial.println("Setup done");
}
void loop()
{
display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT);
Serial.println("scan start");
int n = WiFi.scanNetworks();
Serial.println("scan done");
if (n == 0) {
Serial.println("no networks found");
} else {
Serial.print(n);
Serial.println(" networks found");
for (int i = 0; i < n; ++i) {
// Print SSID and RSSI for each network found
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(")");
Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
display.drawString(0, (10*i),WiFi.SSID(i)+" "+WiFi.RSSI(i));
display.display();
delay(10);
}
}
Serial.println("");
delay(5000);
}
Iscriviti a:
Post (Atom)
Debugger integrato ESP32S3
Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede nell'ID USB della porta Jtag. Nel modulo...
-
In questo post viene indicato come creare uno scatterplot dinamico basato da dati ripresi da un file csv (nel dettaglio il file csv e' c...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...