Projekt: Mit ProbeRequests den Postboten erkennen
Wenn Du auf deinem Smartphone mehrere WiFi-Netze konfiguriert hast (Zuhause, Arbeit, Freunde, Cafes, …) und das Haus verlässt, fragt das Gerät ständig ob diese Netzwerke in der Umgebung erreichbar sind. Ist dies der Fall, verbindet es sich. Meistens ist man aber unterwegs und weit weg von Zuhause - dann fragt es trotzdem munter weiter. Und das für alle Einträge. Warst Du also im letzten Urlaub im Hotel-WLAN, dann fragt es auch in der Fußgängerzone in Deutschland weiter nach diesem Netz. Diese Anfragen nennt man Probe Requests. Das gleiche passiert, wenn der DHL-Zusteller mit seinem Handheld vor Deiner Haustür steht. Diese Geräte haben auch WLAN und fragen ständig nach diesem. So können wir diese erkennen. Cool, oder?
Was wäre nun also, wenn der DHL-Mitarbeiter auf dem Weg zur Haustür ist und wir schon bescheid wissen. Bevor er klingelt! Dafür lauschen wir mit einem Raspberry Pi nach Probe-Requests von Geräten in der Nähe. Ruft also jemand nach seinem DHL-Netzwerk, ist dies höchstwahrscheinlich nicht der Nachbar. Wir wissen also, dass sich der Postbote nähert und können handeln.
Mit diesen Daten kann man eine Menge Quatsch anstellen. Personen tracken, Bewegungsprofile erstellen und vieles mehr. Bitte halte Dich an die lokalen Gesetze für das Speichern und Auswerten von personenbezogenen Daten. Ich bin kein Anwalt und kann Dir nicht sagen ob das Vorgehen legal ist. Immerhin werden die Daten einfach unverschlüsselt umher gesendet. In den USA ist es tägliche Praxis, dass Unternehmen diese Daten nutzen und analysieren (zum Beispiel um Bewegungsprofile in Ladengeschäften zu erstellen).
Was Du brauchst?
- Eine Node-RED-Installation
- Einen Raspberry Pi mit WiFi (intern oder per USB)
Video
Befehle
Bevor Du irgendetwas machst, sollte das System auf dem aktuellsten Stand sein:
sudo apt-get update
sudo apt-get upgrade
sudo rpi-update
Da mehrere Pakete auf GitHub liegen, brauchen wir git auf dem System um diese zu laden.
sudo apt-get install git
Dann starten wir mit ein paar Abhängigkeiten, welche wir später brauchen.
git clone https://github.com/drkjam/netaddr
cd netaddr
sudo python setup.py install
cd ..
git clone https://github.com/secdev/scapy.git
cd scapy
sudo python setup.py install
cd ..
Nun geht es weiter mit Probemon und Aircrack-NG (zweiteres braucht man nicht unbedingt, ist aber ein cooles Tool).
git clone https://github.com/nikharris0/probemon.git
sudo apt-get install aircrack-ng
ifconfig
sudo ifconfig wlan0 down
sudo airmon-ng start wlan0
Neue Treiber für das Interface bauen
Da ich das interne WiFi-Modul vom Raspberry Pi nutzen wollte, musste ich mit nexmon einen neuen Treiber bauen, da der Standard-Treiber kein Monitoring-Mode unterstützt. Klingt erstmal einfach, erfordert aber einen ganzen Haufen an einzelnen Schritten.
Hier habe ich die Befehle aus dem Video dokumentiert. Am besten gehst Du aber bitte nach der Anleitung im Wiki vor.
Diese Befehl sind für den Kernel 4.14 und einen Raspberry Pi 3 (NICHT 3B+)
sudo su
apt install raspberrypi-kernel-headers git libgmp3-dev gawk qpdf bison flex make
git clone https://github.com/seemoo-lab/nexmon.git
cd nexmon
file /usr/lib/arm-linux-gnueabihf/libisl.so.10
cd buildtools/isl-0.10
./configure
make
make install
ln -s /usr/local/lib/libisl.so /usr/lib/arm-linux-gnueabihf/libisl.so.10
cd ../..
source setup_env.sh
make
cd patches/bcm43430a1/7_45_41_46/nexmon/
wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update
apt-get install bc libncurses5-dev
rpi-source
make
make backup-firmware
make install-firmware
cd utilities/nexutil/
make
make install
modinfo brcmfmac
mv /lib/modules/4.14.92-v7+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko /lib/modules/4.14.92-v7+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko.orig
cp /home/pi/python/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/brcmfmac_4.14.y-nexmon/brcmfmac.ko /lib/modules/4.14.92-v7+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko
depmod -a
reboot
sudo su
Weiter im Text
Als nächstes wird ein Monitoring-Device erstellt, welches dann für den Empfang von Probe-Requests genutzt werden kann. Angeblich kann man sogar den Monitoring Mode und das normale WiFi interface parallel nutzen. Habe ich aber nicht getestet, da mein Raspberry Pi im Keller am Kabel hängt.
iw phy `iw dev wlan0 info | gawk '/wiphy/ {printf "phy" $2}'` interface add mon0 type monitor
ifconfig mon0 up
exit
cd ~/python
Jetzt noch tcpdump installieren und damit testen ob alles läuft.
sudo apt-get install tcpdump
ifconfig
sudo tcpdump -i mon0
sudo tcpdump -i mon0 -e -s 256 type mgt subtype probe-req
sudo python probemon.py -i mon0 --mac-info --ssid --log
Jetzt noch die Abhängigkeiten für meine Variante (per MQTT) installieren und das Probemon austauschen:
sudo pip install paho-mqtt
cd ..
rm -rf probemon
git clone https://github.com/klein0r/probemon.git
Danach kann das Ganze getestet werden. Bitte MQTT-Broker, User und Passwort anpassen.
sudo python probemon.py -i mon0 --mac-info --ssid --log --mqtt-broker 192.168.44.11 --mqtt-user raspberry --mqtt-password xxx --mqtt-topic /SmartHome/Interface/WiFi/ProbeRequest
Wenn alles läuft, kümmere ich mich noch um den Autostart. Dafür wird eine neue Datei angelegt.
chmod +x probemon.py
sudo vi /lib/systemd/system/probemon.service
Diese bekommt diesen Inhalt (theoretisch wäre es schöner, das Ganze vorher aus dem Home-Verzeichnis vom pi-Benutzer an eine andere Stelle zu verschieben. Aber so geht es auch.)
Bitte –log als Parameter entfernen. Ausgaben auf stdout brauchen wir nicht
[Unit]
Description=Probemon MQTT Service
[Service]
ExecStart=/home/pi/python/probemon/probemon.py -i mon0 --mac-info --ssid --mqtt-broker 192.168.44.11 --mqtt-user raspberry --mqtt-password xxx --mqtt-topic /SmartHome/Interface/WiFi/ProbeRequest
StandardOutput=null
[Install]
WantedBy=multi-user.target
Alias=probemon.service
Dann noch den neuen Service aktivieren und starten.
sudo systemctl enable probemon.service
sudo systemctl start probemon.service
Fertig. Nun solltest Du regelmäßig Nachrichten per MQTT mit allen Daten bekommen.
Node-RED
In Node-RED habe ich einen Flow gebaut, welcher auf dem konfigurierten Topic schaut ob neue Nachrichten reinkommen. Dann wird geprüft, nach welcher SSID gefragt wird. Kommt darin DHL, DPD, GLS oder UPS vor, sende ich mir eine Push-Notification.
Hier mein Beispiel-Flow:
[{"id":"fee8da92.ffe228","type":"subflow","name":"An FHEM","info":"","in":[{"x":320,"y":140,"wires":[{"id":"7d4eb671.f86aa8"}]}],"out":[]},{"id":"7d4eb671.f86aa8","type":"mqtt out","z":"fee8da92.ffe228","name":"An FHEM","topic":"/Service/fhem/cmnd","qos":"","retain":"","broker":"afa97030.18184","x":460,"y":140,"wires":[]},{"id":"9ac0b213.4b60d","type":"tab","label":"WiFiProbes","disabled":false,"info":""},{"id":"af7ec61a.250718","type":"mqtt in","z":"9ac0b213.4b60d","name":"","topic":"/SmartHome/Interface/WiFi/ProbeRequest","qos":"2","broker":"afa97030.18184","x":180,"y":140,"wires":[["e20cd860.836888"]]},{"id":"e20cd860.836888","type":"json","z":"9ac0b213.4b60d","name":"","property":"payload","action":"","pretty":false,"x":440,"y":140,"wires":[["8df8bce5.be216"]]},{"id":"8df8bce5.be216","type":"switch","z":"9ac0b213.4b60d","name":"Welcher Dienst","property":"payload.ssid","propertyType":"msg","rules":[{"t":"cont","v":"DHL","vt":"str"},{"t":"cont","v":"UPS","vt":"str"},{"t":"cont","v":"DPD","vt":"str"},{"t":"cont","v":"GLS","vt":"str"},{"t":"else"}],"checkall":"false","repair":false,"outputs":5,"x":610,"y":140,"wires":[["275d4978.731266"],["2a31156a.f23f5a"],["86fc14c5.edc9c8"],["77d835b5.45b92c"],[]]},{"id":"275d4978.731266","type":"trigger","z":"9ac0b213.4b60d","op1":"DHL","op2":"false","op1type":"str","op2type":"bool","duration":"60","extend":true,"units":"s","reset":"","bytopic":"all","name":"DHL","x":800,"y":80,"wires":[["2ef92fab.3ea27"]]},{"id":"2a31156a.f23f5a","type":"trigger","z":"9ac0b213.4b60d","op1":"UPS","op2":"false","op1type":"str","op2type":"bool","duration":"60","extend":true,"units":"s","reset":"","bytopic":"all","name":"UPS","x":800,"y":120,"wires":[["2ef92fab.3ea27"]]},{"id":"86fc14c5.edc9c8","type":"trigger","z":"9ac0b213.4b60d","op1":"DPD","op2":"false","op1type":"str","op2type":"bool","duration":"60","extend":true,"units":"s","reset":"","bytopic":"all","name":"DPD","x":800,"y":160,"wires":[["2ef92fab.3ea27"]]},{"id":"77d835b5.45b92c","type":"trigger","z":"9ac0b213.4b60d","op1":"GLS","op2":"false","op1type":"str","op2type":"bool","duration":"60","extend":true,"units":"s","reset":"","bytopic":"all","name":"GLS","x":800,"y":200,"wires":[["2ef92fab.3ea27"]]},{"id":"2ef92fab.3ea27","type":"switch","z":"9ac0b213.4b60d","name":"Neuer Dienst","property":"payload","propertyType":"msg","rules":[{"t":"false"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":980,"y":140,"wires":[[],["8b5e750b.842698"]]},{"id":"bf1000dc.99902","type":"subflow:fee8da92.ffe228","z":"9ac0b213.4b60d","x":1320,"y":160,"wires":[]},{"id":"8b5e750b.842698","type":"function","z":"9ac0b213.4b60d","name":"FHEM-CMD","func":"msg.payload = \"msg push @rr_Matthias |Paketdienst| \" + msg.payload + \" ist jetzt da!\"\nreturn msg;","outputs":1,"noerr":0,"x":1170,"y":160,"wires":[["bf1000dc.99902"]]},{"id":"afa97030.18184","type":"mqtt-broker","z":"","name":"","broker":"mqtt","port":"1883","clientid":"nodered","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"/Service/nodered/status","willQos":"0","willPayload":"crashed","birthTopic":"/Service/nodered/status","birthQos":"0","birthPayload":"started"}]