Area41 2024 - Ein Rückblick
Michael Schneider
Wir haben in unserem Beitrag Vorgehen zum Testen von IoT Devices Strategien zur Analyse von Geräten im Internet of Things (IoT) aufgezeigt. In diesem Beitrag setzen wir uns mit der Kommunikationsanalyse eines IoT-Geräts und seiner Um-Systeme (Apps, Server-Infrastruktur) auseinander. Wir haben dazu das Produkt Belkin WeMo Switch ausgewählt. In diesem wurden bereits Schwachstellen der Klassen Privilege Escalation (VulDB 12452, Information Disclosure (VulDB 12451 und 12453), Buffer Overflow (VulDB 12454) und Weak Authentication (VulDB 12455) gefunden und durch Belkin behoben. Mit der Kommunikationsanalyse wollen wir untersuchen, ob im Austausch zwischen App, WeMo Switch und der Belkin-Infrastruktur weitere Schwachstellen vorliegen, die es ermöglichen, eines oder mehrere Geräte aus der Ferne zu kontrollieren.
Der Belkin WeMo Switch ist eine Steckdose, die es zulässt, beliebige angeschlossene elektronische Geräte ein- und auszuschalten. Von überall. Der WeMo Switch wird dazu mit einem vorhandenen Wireless-LAN (WLAN) verbunden und über eine App (iOS oder Android) gesteuert. Wenn sich die App und der Switch im gleichen Netzwerk befinden, kommunizieren diese direkt miteinander, ansonsten wird die Infrastruktur Belkins als Schaltzentrale genutzt. Die direkte Kommunikation basiert auf dem Netzwerkprotokoll Universal Plug and Play (UPnP) und einer einfachen REST-API. Die Remote-Kommunikation findet über HTTP statt, wobei dieselbe REST-API wie bei UPnP eingesetzt wird.
In der Initialisierungsphase erstellt der WeMo Switch als Access Point (AP) ein eigenes WLAN. Die SSID des WLANs wird nach dem Namensschema WeMo.Switch.XXX
benannt. Dabei steht XXX
für die letzten drei Stellen der Seriennummer. Der Access Point (AP) ist zusätzlich auch DHCP-Server und verwendet IP-Adressen aus dem Bereich 10.22.22.0/24
. Zur Verwaltung des Geräts wird ein Webserver auf Port tcp/49152 eingesetzt. Die WeMo App nutzt diesen Dienst, um die Zugangsdaten des WLANs an den WeMo Switch zu übermitteln. Dabei werden die Zugangsdaten als XML-Request im folgenden Format versendet:
POST /upnp/control/WiFiSetup1 HTTP/1.1 Content-Type: text/xml; charset="utf-8" SOAPACTION: "urn:Belkin:service:WiFiSetup:1#ConnectHomeNetwork" Content-Length: 444 HOST: 10.22.22.1:49152 User-Agent: CyberGarage-HTTP/1.0 <?xml version="1.0" encoding="utf-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <s:Body> <u:ConnectHomeNetwork xmlns:u="urn:Belkin:service:WiFiSetup:1"> <ssid>WeMoTest</ssid> <auth>WPA2PSK</auth> <password>edTQ/hzPJ7MpPeL/qBA5gseNRZWdNdPR5dUu9v8Br40=2d1a</password> <encrypt>TKIP</encrypt> <channel>7</channel> </u:ConnectHomeNetwork> </s:Body> </s:Envelope>
Das Passwort wird dabei in kodierter Form übertragen. Die letzten vier Stellen, im Falle des Beispiels 2d1a
, sind Hex-Werte und geben die gesamte Zeichenlänge des Passwort-Strings, der Wert 2d
entspricht 45 Zeichen, sowie die tatsächliche Länge des Passworts beispielsweise ergibt der Wert 1a
26 Zeichen. Welche Kodierung für den Passwort-String verwendet wird, konnte im Rahmen der Analyse nicht identifiziert werden. Der WeMo Switch verwendet diese Zugangsdaten, um sich mit dem WLAN zu verbinden und mit den Servern Belkins zu kommunizieren.
Anschliessend wird der Remote-Access eingerichtet. Die App sendet einen Request an den WeMo Switch, dabei wird die App über eine DeviceId eindeutig identifiziert. Unter iOS wird der UniqueDeviceIdentifier (UDID) und auf Android-basierenden Geräte die International Mobile Equipment Identity (IMEI) als DeviceId verwendet.
POST /upnp/control/remoteaccess1 HTTP/1.1 Content-Type: text/xml; charset="utf-8" SOAPACTION: "urn:Belkin:service:remoteaccess:1#RemoteAccess" Content-Length: 603 HOST: 10.22.22.1:49152 User-Agent: CyberGarage-HTTP/1.0 <?xml version="1.0" encoding="utf-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <s:Body> <u:RemoteAccess xmlns:u="urn:Belkin:service:remoteaccess:1"> <DeviceId>9jiusa7pp00n3uzdbwfv2ulat5yy34x26ou1wgo2</DeviceId> <dst>0</dst> <HomeId></HomeId> <DeviceName>TestDevice23</DeviceName> <MacAddr></MacAddr> <pluginprivateKey></pluginprivateKey> <smartprivateKey></smartprivateKey> <smartUniqueId></smartUniqueId> <numSmartDev></numSmartDev> </u:RemoteAccess> </s:Body> </s:Envelope>
Die Antwort des WeMo Switches enthält die HomeId
und zwei Schlüssel pluginprivateKey
sowie smartprivateKey
. Diese Schlüssel werden vermutlich im weiteren Kommunikationsverlauf zur Signierung und Verschlüsselung eingesetzt. Die HomeId
besteht aus sieben Zahlen und wird möglicherweise mit der SSID oder der MAC-Adresse des WLAN-Access-Points verknüpft. In unserem Testnetzwerk wurden zwei Geräte unabhängig voneinander im gleichen Netzwerk eingerichtet und beide verwendeten dieselbe HomeId
.
HTTP/1.1 200 OK CONTENT-LENGTH: 632 CONTENT-TYPE: text/xml; charset="utf-8" DATE: Fri, 24 Jul 2015 11:12:08 GMT EXT: SERVER: Linux/2.6.21, UPnP/1.0, Portable SDK for UPnP devices/1.6.18 X-User-Agent: redsonic <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <s:Body> <u:RemoteAccessResponse xmlns:u="urn:Belkin:service:remoteaccess:1"> <homeId>0000000</homeId> <pluginprivateKey>xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</pluginprivateKey> <smartprivateKey>yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy</smartprivateKey> <resultCode>PLGN_200</resultCode> <description>Successful</description> <statusCode>S</statusCode> <smartUniqueId>9jiusa7pp00n3uzdbwfv2ulat5yy34x26ou1wgo2</smartUniqueId> <numSmartDev>1</numSmartDev> </u:RemoteAccessResponse> </s:Body> </s:Envelope>
Die Kommunikation zwischen der WeMo App und der Infrastruktur Belkins lässt sich in die Bereiche Registrierung, Ein- und Ausschalten sowie Firmware Update aufteilen.
Bei allen Anfragen zur Registrierung verwendet die App einen Basic Access Authentication Header, der nach folgendem Schema aufgebaut wird:
Authorization: SDU 9jiusa7pp00n3uzdbwfv2ulat5yy34x26ou1wgo2:gclbqUYLczNi+cJf+MJ5W/cmCeo=:1440403670@
Im Patent US9021139 B1 wird der Aufbau des Headers so beschrieben, dass der SDU String aus DeviceId
, Signature
und einer Ablaufzeit ExpirationTime
zusammengesetzt wird. Das Feld Signature
könnte gemäss des Patents wie folgt generiert werden: Signature=Base64(HMAC-SHA1(PrivateKey, StringToSign))
. Dabei wird als Schlüssel vermutlich einer der beiden Schlüssel aus der Initial-Registrierung verwendet.
Bei der ersten Anfrage der Schnittstelle api.xbcs.net wird eine Liste der registrierten Geräte unter einer bestimmten HomeId
abgefragt. Dabei ist die DeviceId
, die zur Authentisierung eingesetzt wird, mit der HomeId
verknüpft. In unseren Tests war es nicht möglich, mit einer DeviceId
auf fremde HomeId
zuzugreifen. Diese Anfragen wurden vom Server mit einer Fehlermeldung geblockt. Bei einem erfolgreichen Aufruf gibt der Server eine Liste der registrierten Geräte pro HomeId
zurück.
HTTP/1.1 200 OK asyncServiceInvoke: false Content-Type: application/xml;charset=ISO-8859-1 Date: Mon, 24 Aug 2015 08:05:51 GMT Server: Apache-Coyote/1.1 X-Powered-By: Servlet/3.0; JBossAS-6 Content-Length: 1242 Connection: keep-alive <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <devices xmlns:modelns="http://datamodel.components.cs.belkin.com/" success="S" fail="F" partial_success="P"> <statusCode>S</statusCode> <resultCode> <code>PLGN_200</code> <description>Successful</description> </resultCode> <message>Device list retrieved successfully</message> <home> <homeId>0000000</homeId> <description>this is first plugin initialization</description> <firmwareId>0</firmwareId> </home> <device> <pluginId>1111111</pluginId> <macAddress>00005E005300</macAddress> <serialNumber>22222222222Z00</serialNumber> <uniqueId>uuid:Socket-1_0-22222222222Z00</uniqueId> <modelCode>Socket</modelCode> <productType>Socket</productType> <status>3</status> <notificationType>0</notificationType> <firmwareVersion>WeMo_WW_2.00.2176.PVT</firmwareVersion> <hwVersion>v1</hwVersion> <fwUpgradeStatus>4</fwUpgradeStatus> <signalStrength>29</signalStrength> <friendlyName>WeMo Switch 5</friendlyName> <dbVersion>0</dbVersion> <customizedState>1</customizedState> <attributeLists action="GetAttributes"> <attribute> <name>hardResetTS</name> <value>1438939404278</value> </attribute> </attributeLists> </device> <groupSSIDs> <ssid>WeMoTest</ssid> </groupSSIDs> <groupArpMacs> <arpMac>00005E005301</arpMac> </groupArpMacs> </devices>
Die Liste enthält weitere, bisher unbekannte Merkmale eines Geräts, unter anderem die PluginId
(wird zum Teil auch als RecipientId
verwendet), die macAddress
sowie die Firmware-Version des WeMo Switches. Diese Merkmale werden dann für weitere Aktionen, wie das Ein- und Ausschalten des WeMo-Switches, benötigt. Zusätzlich werden auch die SSID des WLANs und die MAC-Adresse des Access-Points bei Belkin gespeichert.
Der Befehl zum Ein-/Ausschalten des Geräts wird an den Host api.xbcs.net gesendet. Um diese Nachricht zu senden, ist eine Authentisierung über den Basic Access Authentication Header notwendig. Der WeMo Switch wird dabei über die Felder PluginId
respektive die RecipientId
und die macAddress
angesprochen. Der Status der Geräte wird dabei über die Werte 0
oder 1
gesteuert.
POST /apis/http/plugin/message HTTP/1.1 Host: api.xbcs.net:8443 <redacted by scip AG> <plugins> <plugin> <recipientId>1111111</recipientId> <macAddress>00005E005300</macAddress> <content> <![CDATA[ <pluginSetDeviceStatus> <plugin> <pluginId>1111111</pluginId> <macAddress>00005E005300</macAddress> <status>1</status> <friendlyName></friendlyName> <eventDuration>(null)</eventDuration> <cookedTime>(null)</cookedTime> </plugin> </pluginSetDeviceStatus> ]]> </content> </plugin> </plugins>
Die WeMo App kann auch dazu genutzt werden, um die Firmware des WeMo Switches zu aktualisieren. Als Antwort auf die initiale Anfrage, die wiederum den Basic Access Authentication Header enthält, erhält die App einen Link zu einer Seite, welche die erhältlichen Firmware-Versionen auflistet. Der Zugriff auf die Firmware erfolgt über eine unverschlüsselte Verbindung, obwohl der Server auch per HTTPS erreichbar wäre.
HTTP/1.1 200 OK asyncServiceInvoke: false Content-Type: application/json;charset=ISO-8859-1 Date: Thu, 10 Sep 2015 12:35:43 GMT Server: Apache-Coyote/1.1 X-Powered-By: Servlet/3.0; JBossAS-6 Content-Length: 133 Connection: keep-alive {"fwUpgradeInfo":{"firmwareId":0,"description":"Default firmware file","fwUpgradeURL":"http:\/\/fw.xbcs.net\/wemo\/NewFirmware.txt"}}
Das Firmware-Binary selbst ist mittels GPG verschlüsselt und wird auf dem WeMo Switch selbst extrahiert. Die Verwendung von GPG zur Verteilung der Firmware ist grundsätzlich eine gute Idee, nur hat Belkin bei der Implementierung einen folgenschweren Fehler gemacht. Der Security Researcher Mike Davis von IOActive entdeckte 2013, dass Belkin den GPG Signing Key in das WeMo Firmware-Image integrierte. Ein Angreifer konnte diesen Key extrahieren, eine eigene Firmware damit signieren und schlussendlich auf das Gerät einspielen. Im Firmware Update von 24. Januar 2014 hatte Belkin diese Schwachstelle geschlossen.
Die Belkin Infrastruktur wird in der Amazon EC2 Cloud betrieben. Die Infrastruktur umfasst unter anderem die Systeme ota.xbcs.net, api.xbcs.net oder fw.xbcs.net. Dabei konnte der Einsatz von Red Hat Linux, Apache 2.2.15 sowie JBoss 6 identifiziert werden.
Beim Start des WeMo Switches werden Log-Daten an ein System mit der IP-Adresse 184.73.191.189 übermittelt. Die MAC-Adresse 00005E005300 des WeMo Switches wird hierbei als ID in der POST-Request verwendet. Es ist ferner keine Authentisierung notwendig und es finden keine Kontrollen des Inhalts statt. Dies bedeutet, dass beliebige Inhalte unter beliebigen MAC-Adressen an die Server Belkins übermittelt werden können. Hingegen war es nicht möglich, auf bereits übermittelten und gespeicherten Daten zuzugreifen.
PUT /ToolService/log/uploadWdLogFile/00005E005300 HTTP/1.1 Host: 184.73.191.189:8899 Content-Type: multipart/octet-stream Accept: application/xml Content-Length: 301 Expect: 100-continue [2015-08-07][08:33:35]|RT|Internet is connected [2015-08-07][08:33:39]|PLUGINREMOTEREGISTER|Plugin App Remote ReRegister [2015-08-07][08:33:37]|SIG|Connection signal strength: 55 [2015-08-07][08:33:40]|Plugin App Remote ReRegister failure| [2015-08-07][08:33:40]|Plugin App Remote ReRegister failure| HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: application/xml Content-Length: 67 Date: Fri, 07 Aug 2015 06:33:58 GMT /opt/deviceLogs2/20150807/wdLogFile_00005E005300_20150807063358.log
Als der WeMo Switch veröffentlicht wurde, ging es nicht lange und es wurden mehrere Schwachstellen gefunden. Im Bereich der Kommunikation zwischen App, WeMo Switch und der Server-Infrastruktur hat Belkin nun aus diesen Erfahrungen gelernt und die Remote-Kommunikation soweit gesichert, so dass Geräte ohne eine erfolgreiche Authentisierung nicht ferngesteuert werden können. Zudem werden die Geräte und Heimnetzwerke miteinander verknüpft und es ist nicht ohne weiteres möglich, andere Heimnetzwerke und deren Geräte durch Ausprobieren oder Durchnummerieren zu finden. Dadurch ist es für einen Angreifer nicht so leicht, Angriffe aus der Ferne auszuführen. Es bleibt zu hoffen, dass auch andere IoT-Hersteller aus diesen Erfahrungen ihre Lehren ziehen und die Produkte von Beginn an mit entsprechenden Sicherheitsfunktionen versehen.
Unsere Spezialisten kontaktieren Sie gern!
Michael Schneider
Michael Schneider
Michael Schneider
Michael Schneider
Unsere Spezialisten kontaktieren Sie gern!