Car Hacking - Analyse der Mercedes Connected Vehicle API

Car Hacking

Analyse der Mercedes Connected Vehicle API

Marc Ruef
von Marc Ruef
Lesezeit: 23 Minuten

Keypoints

  • Viele moderne Fahrzeughersteller bieten eine Internetfunktionalität in ihren Fahrzeugen an
  • Mercedes stellt seit Anfang 2018 eine experimentelle API zur Verfügung
  • Über diese können, ähnlich wie bei OBD, Fahrzeugdaten und Telemetriedaten ausgelesen werden
  • Zusätzlich lässt sich die aktuelle Position des Fahrzeugs ermitteln
  • Ebenso sind gewisse aktive Eingriffe, wie zum Beispiel das Öffnen des Fahrzeugs, möglich
  • Damit gehen gewisse Risiken in Bezug auf Privatpshäre und Sicherheit einher

Früher sprach man vom Computer im Auto. Heute muss man stattdessen vom Computer mit vier Rädern sprechen. Verschiedene Hersteller bieten eine Kommunikation mit ihren Fahrzeugen über das Internet an. Dieser Artikel bespricht die Möglichkeiten, die Mercedes im Rahmen der jüngst als experimentell veröffentlichten Connected Vehicle API zur Verfügung stellt.

Connected Vehicle API

Mercedes bietet verschiedene APIs an. Dazu gehören in erster Linie datenbasierte Anbindungen, mit denen Verkäufer einen Car Configurator oder Bilder zu Fahrzeugen zur Verfügung stellen können.

Seit Januar 2018 wird jedoch zudem die als experimentell gekennzeichnete Connected Vehicle API angeboten. Hierbei handelt es sich um eine Zugriffsmöglichkeit über die Sonderausstattung Remote Online (11U), mit der mittels REST auf Statusinformationen und Telemetriedaten entsprechend vernetzter Fahrzeuge zurückgegriffen werden kann. Unter anderem verwendet auch die offizielle Mercedes me App diese Schnittstelle (teilweise in leicht abgeänderter und erweiterter Form).

Viele der Funktionen sind kostenpflichtig und müssen über eine gewisse Laufzeit als Mercedes me connect Dienst aktiviert werden. Eine Nutzung erfordert zudem zuerst eine Freigabe auf der Seite me.secure.mercedes-benz.com. Die Möglichkeiten der API sind gegenwärtig zaghaft umgesetzt und dementsprechend begrenzt. Es zeichnet sich aber ab, dass ein Mehr an Eingriffen in zukünftigen Versionen und Fahrzeugmodellen möglich sein werden.

Übersicht in der Mercedes me App

Kommunikationswege der Mercedes API


Authentisierung

Die Authentisierung der APIs von Mercedes erfolgt über OAuth 2.0. Hierbei handelt es sich um ein in RFC 6749 standardisiertes Verfahren, das mittlerweile von verschiedenen API-Implementierungen herangezogen wird. Die Authentisierung wird dabei traditionell mittels initialem Authorization-Header umgesetzt. Dafür muss die Client ID (Benutzername) und das Client Secret (Passwort) in einer HTTP POST-Anfrage mitgeschickt werden:

curl --request POST \
  --url https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/token \
  --header 'Authorization: Basic <YOUR_CLIENT_ID>:<YOUR_CLIENT_SECRET>' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data 'grant_type=authorization_code&code=d0c8b2d3-367e-466b-80b5-45b66172219c&redirect_uri=https%3A%2F%2Ftest.scip.ch'

Der Server schickt daraufhin das individuelle access_token zurück:

{
  "access_token":"1f8647f3-5f86-4b5e-8687-982fd620ef78",
  "token_type":"Bearer",
  "expires_in":3600,
  "refresh_token":"79850753-16ad-48cf-aae7-7e17a4d4882d",
  "scope":"mb:vehicle:status:general mb:user:pool:reader"
}

Nach diesem Austausch kann über diesen in authentisierter Form durch den Header authorization mittels HTTP GET-Anfragen auf den API-Endpunkt zugegriffen werden:

curl --request GET \
  --url https://<API_URL> \
  --header 'authorization: Bearer e253fdd3-67f1-4dcc-bcd6-9f9c9278fe6f'

Ein Erneuern des Access-Token ist regelmässig erforderlich. Hierzu wird zu Beginn sein Ablaufdatum im Feld expires_in in Sekunden ausgewiesen. Um eine Erneuerung vornehmen zu können, muss das refresh_token herangezogen werden. Dadurch soll der Missbrauch durch Dritte, zum Beispiel nach erfolgreicher Sniffing- oder Bruteforce-Attacke, eingeschränkt werden.

Fahrzeug ansteuern

Zu Beginn der Initialisierung einer Kommunikation muss das Fahrzeug – dieses kann vorgängig nur durch einen autorisierten Mercedes-Händler registriert und aktiviert werden – angesteuert werden. Dies geschieht über vehicles:

curl -X GET \
  https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles \
  -H 'Authorization: Bearer YOUR_ACESS_TOKEN' \
  -H 'Content-Type: application/json'

Dadurch werden die dem Benutzerkonto zugewiesenen Fahrzeuge zurückgeliefert. Dies geschieht anhand einer id, dem registrierten Autokennzeichen licenseplate und der VIN (Vehicle Identification Number) finorvin:

[
    {
        "id": "YOUR_VEHICLE_ID",
        "licenseplate": "ZH-XXXX",
        "finorvin": "WDD***********123"
    }
]

Dadurch wird es nun möglich, weitere Zugriffe auf das eindeutig identifizierbare Fahrzeug durchzuführen. Es können nämlich mehrere Fahrzeuge einem einzelnen Konto zugewiesen werden (zum Beispiel zwecks Verwaltung eines Wagenparks). Das Ansteuern innerhalb der API findet in erster Linie über die id statt.

Daten auslesen

Da nun die id des Fahrzeugs bekannt ist, kann dieses nun direkt angesteuert und in einem ersten Schritt Daten ausgelesen werden. Hierzu muss die id entsprechend als Parameter mitgeschickt werden:

curl -X GET \
  https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles/YOUR_VEHICLE_ID \
  -H 'Authorization: Bearer YOUR_ACESS_TOKEN' \
  -H 'Content-Type: application/json'

In der Antwort finden sich nun die grundlegenden Daten des Fahrzeugs. Dazu gehört die im Verkauf genutzte Bezeichnung salesdesignation, das Jahr modelyear, die Farbe colorname und der Motorentyp fueltype:

{
    "id": "YOUR_VEHICLE_ID",
    "licenseplate": "ZH-****",
    "salesdesignation": "***",
    "finorvin": "WDD***********123",
    "nickname": "Hans Muster",
    "modelyear": "2018",
    "colorname": "polarweiss",
    "fueltype": "Benzin",
    "powerhp": "612",
    "powerkw": "450",
    "numberofdoors": "5",
    "numberofseats": "5"
}

Hierbei handelt es sich um einen Zugriff mit reinen Leserechten. Es ist darüber nicht möglich, Modifikationen an der Dokumentation (z.B. Anpassen des Modelljahrs) oder Charakteristik des Fahrzeugs (z.B. Aufheben der PS-Limitierung) vorzunehmen.

Dedizierte Telemetrie-Daten auslesen

In einem weiteren Schritt besteht nun die Möglichkeit, sämtliche Telemetriedaten auszulesen. Hierzu können die einzelnen Elemente wie Reifen tires, Hodometer odometer oder Tankfüllung fuel herangezogen werden:

curl -X GET \
  https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles/YOUR_VEHICLE_ID/fuel \
  -H 'Authorization: Bearer YOUR_ACESS_TOKEN' \
  -H 'Content-Type: application/json'

Die Antwort enthält dann die entsprechenden Informationen, wobei im Feld value der Nennwert und in unit die genutzte Einheit enthalten ist. Im folgenden Beispiel beträgt die Tankfüllung 40%:

{
    "fuellevelpercent": {
        "value": 40,
        "retrievalstatus": "VALID",
        "timestamp": 1512747873,
        "unit": "PERCENT"
    }
}

Dieses Verhalten kennt man von den Möglichkeiten, die durch ODB (On-Board-Diagnose) gewährt wird. Durch den physischen Anschluss eines entsprechenden Geräts können die gleichen Fahrzeugdiagnosedaten ausgelesen werden.

Mercedes bietet bei nicht vernetzten Autos, zum Beispiel älteren Baujahrs, den Mercedes me Adapter samt Mercedes me Adapter App an, um die gleiche Funktionalität nachrüsten zu können.

Sämtliche Daten auslesen

Die offizielle API verzichtet darauf, einen weiteren Befehl zu dokumentieren. Denn mit dynamic können sämtliche Informationen, samt zusätzliche Daten, mit einer einzelnen Anfrage eingeholt werden:

curl -X GET \
  https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles/YOUR_VEHICLE_ID/dynamic \
  -H 'Authorization: Bearer YOUR_ACESS_TOKEN' \
  -H 'Content-Type: application/json'

Dies wird zum Beispiel rigoros durch die offizielle Mercedes me App auf den Smartphones beim Öffnen der App genutzt. Dadurch können die Daten für die Anzeige aufbereitet werden:

{
    "dynamic":{
        "readingLampFrontRight":{
            "value":false,
            "status":"VALID"
        },
        "precondSeatFrontRight":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "preWarningBrakeLiningWear":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "remoteEngine":{
            "value":"OFF",
            "status":"INVALID"
        },
        "vehicleHealthStatus":{
            "value":0,
            "status":"VALID"
        },
        "smartCharging":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "drivenTimeStart":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "fuelLidClosed":{
            "value":true,
            "status":"VALID"
        },
        "tankReserveLamp":{
            "value":false,
            "status":"VALID"
        },
        "socprofile":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "maxrange":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "batteryState":{
            "value":0,
            "status":"VALID"
        },
        "liquidRangeSkipIndication":{
            "value":false,
            "status":"VALID"
        },
        "tirepressureRearRight":{
            "value":273,
            "status":"VALID"
        },
        "tireMarkerRearLeft":{
            "value":false,
            "status":"VALID"
        },
        "languageHU":{
            "value":0,
            "status":"VALID"
        },
        "batteryCutOffSwitch":{
            "value":null,
            "status":"NOT_RECEIVED"
        },
        "lastecall":{
            "value":null,
            "status":"NOT_RECEIVED"
        },
        "distanceElectricalStart":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "departureTimeMode":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "parkbrakestatus":{
            "value":true,
            "status":"VALID"
        },
        "gasTankLevel":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "precondNowError":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "rangeelectric":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "tireMarkerRearRight":{
            "value":false,
            "status":"VALID"
        },
        "windowstatusrearright":{
            "value":"CLOSED",
            "status":"VALID"
        },
        "serviceintervaldays":{
            "value":345,
            "status":"VALID"
        },
        "engineCoolantTemperature":{
            "value":null,
            "status":"NOT_RECEIVED"
        },
        "windowstatusrearleft":{
            "value":"CLOSED",
            "status":"VALID"
        },
        "electricalRangeSkipIndication":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "endofchargetime":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "kmatrixver":{
            "value":"2015/05/-/2.0/diag",
            "status":"VALID"
        },
        "windowsClosed":{
            "value":"CLOSED",
            "status":"VALID"
        },
        "auxheattimeselection":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "odo":{
            "value":772,
            "status":"VALID"
        },
        "warninglowbattery":{
            "value":false,
            "status":"VALID"
        },
        "icA13":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "tirewarninglamp":{
            "value":"INACTIVE",
            "status":"VALID"
        },
        "icA14":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "precondDuration":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "electricconsumptionreset":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "precondatdeparture":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "temperatureUnitHU":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "engineOilTemperature":{
            "value":null,
            "status":"NOT_RECEIVED"
        },
        "trunkLocked":{
            "value":true,
            "status":"VALID"
        },
        "averageSpeedReset":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "ecoscoreconst":{
            "value":87,
            "status":"VALID"
        },
        "engineLimpHomeMode":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "trunkClosed":{
            "value":true,
            "status":"VALID"
        },
        "supplybatteryvoltage":{
            "value":14.6,
            "status":"VALID"
        },
        "doorsClosed":{
            "value":true,
            "status":"VALID"
        },
        "electricChargingStatus":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "ecoscoretotal":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "rearLeftDoorClosed":{
            "value":true,
            "status":"VALID"
        },
        "warningbrakeliningwear":{
            "value":false,
            "status":"VALID"
        },
        "distanceZEStart":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "tirepressscope":{
            "value":"TIRE_PRESSURE_CONTROL",
            "status":"VALID"
        },
        "interiorLightsFront":{
            "value":false,
            "status":"VALID"
        },
        "tirewarningsrdk":{
            "value":"NO_WARNING",
            "status":"VALID"
        },
        "rangeliquid":{
            "value":142,
            "status":"VALID"
        },
        "precondNow":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "chargingPower":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "drivenTimeReset":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "auxheattime1":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "lightswitchposition":{
            "value":"AUTO",
            "status":"VALID"
        },
        "averageSpeedStart":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "auxheattime2":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "auxheattime3":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "gasconsumptionstart":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "interiorLightsRear":{
            "value":false,
            "status":"VALID"
        },
        "gasTankRange":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "ecoscorefreewhl":{
            "value":100,
            "status":"VALID"
        },
        "rearRightDoorLocked":{
            "value":true,
            "status":"VALID"
        },
        "distanceStart":{
            "value":24.5,
            "status":"VALID"
        },
        "soc":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "departureProfile":{
            "value":"NONE",
            "status":"VALID"
        },
        "gasconsumptionreset":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "distanceReset":{
            "value":771.7,
            "status":"VALID"
        },
        "windowstatusfrontleft":{
            "value":"CLOSED",
            "status":"VALID"
        },
        "tankCapOpenLamp":{
            "value":null,
            "status":"NOT_RECEIVED"
        },
        "speedUnitFromIC":{
            "value":null,
            "status":"NOT_RECEIVED"
        },
        "frontLeftDoorLocked":{
            "value":true,
            "status":"VALID"
        },
        "tirepressureRearLeft":{
            "value":273,
            "status":"VALID"
        },
        "locked":{
            "value":true,
            "status":"VALID"
        },
        "timeFormatHU":{
            "value":true,
            "status":"VALID"
        },
        "liquidconsumptionstart":{
            "value":6.4,
            "status":"VALID"
        },
        "maintenance1Ar":{
            "value":"AAAAAAAAAAA=",
            "status":"VALID"
        },
        "departuretimesoc":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "distanceZEReset":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "tirewarningsprw":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "serviceWarning":{
            "value":null,
            "status":"NOT_RECEIVED"
        },
        "precondSeatFrontLeft":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "tireMarkerFrontRight":{
            "value":false,
            "status":"VALID"
        },
        "drivenTimeZEReset":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "serviceintervaldistance":{
            "value":null,
            "status":"INVALID"
        },
        "readingLampFrontLeft":{
            "value":false,
            "status":"VALID"
        },
        "precondActive":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "ecoscorebonusrange":{
            "value":5.8,
            "status":"VALID"
        },
        "sunroofEvent":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "rearLeftDoorLocked":{
            "value":true,
            "status":"VALID"
        },
        "liquidconsumptionreset":{
            "value":7.8,
            "status":"VALID"
        },
        "warningbrakefluid":{
            "value":false,
            "status":"VALID"
        },
        "departureTimeUtc":{
            "value":null,
            "status":"VALID"
        },
        "precondimmediate":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "windowstatusfrontright":{
            "value":"CLOSED",
            "status":"VALID"
        },
        "maintenance2Ar":{
            "value":"AAAAAAAAAAA=",
            "status":"VALID"
        },
        "electricconsumptionstart":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "collisionAlarmTimestamp":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "trackingStateHU":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "warningenginelight":{
            "value":false,
            "status":"VALID"
        },
        "ignitionstate":{
            "value":"LOCK",
            "status":"VALID"
        },
        "precondSeatRearLeft":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "frontRightDoorClosed":{
            "value":true,
            "status":"VALID"
        },
        "rooftopstatus":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "currentSpeedFromIC":{
            "value":null,
            "status":"NOT_RECEIVED"
        },
        "warningwashwater":{
            "value":false,
            "status":"VALID"
        },
        "sunroofstatus":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "tirepressureFrontRight":{
            "value":278,
            "status":"VALID"
        },
        "precondSeatRearRight":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "auxheatwarnings":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "tirepressureFrontLeft":{
            "value":280,
            "status":"VALID"
        },
        "auxheatruntime":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "chargingactive":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "rearRightDoorClosed":{
            "value":true,
            "status":"VALID"
        },
        "warningcoolantlevellow":{
            "value":false,
            "status":"VALID"
        },
        "frontRightDoorLocked":{
            "value":true,
            "status":"VALID"
        },
        "drivenTimeZEStart":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "ecoscoreaccel":{
            "value":91,
            "status":"VALID"
        },
        "departuretime":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "tanklevelpercent":{
            "value":15,
            "status":"VALID"
        },
        "frontLeftDoorClosed":{
            "value":true,
            "status":"VALID"
        },
        "auxheatstatus":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "precondError":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "vtime":{
            "value":1520324215,
            "status":"VALID"
        },
        "collisionAlarmHappened":{
            "value":null,
            "status":"NOT_AVAILABLE"
        },
        "tireMarkerFrontLeft":{
            "value":false,
            "status":"VALID"
        },
        "preconditionActive":{
            "value":false,
            "status":"INVALID"
        },
        "tireWarningRollup":{
            "value":false,
            "status":"VALID"
        },
        "distanceElectricalReset":{
            "value":null,
            "status":"NOT_AVAILABLE"
        }
    },
    "aggregated":{
        "lastJourney":{
            "vin":"WDD***********123",
            "duration":2018,
            "distance":24,
            "started":1520322165,
            "averageSpeed":43.0
        }
    }
}

Fahrzeugortung

Es wird ebenso die kostenpflichtige Möglichkeit gewährt, eine Geolokalisierung des Fahrzeugs vorzunehmen. Dies wird über location erreicht:

curl -X GET \
  https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles/YOUR_VEHICLE_ID/location \
  -H 'Authorization: Bearer YOUR_ACESS_TOKEN' \
  -H 'Content-Type: application/json'

Als Antwort wird Höhengrad longitude und Breitengrad latitude (dies entspricht eigentlich nicht der in EPSG:4326 standardisierten Reihenfolge) mitgeschickt. Ebenso ist das Feld heading enthalten, welche die Ausrichtung des Fahrzeugs in Grad ausweist. Norden entspricht 0.0 und Süden dementsprechend 180.0. Dies ist besonders bei der Identifikation der Fahrtrichtung von Relevanz.

{
    "heading":258.0,
    "longitude":8.491945,
    "latitude":47.385757999999996
}

Die Mercedes me App nutzt diese Informationen, um die Lokation des Fahrzeugs auf einer dynamischen Karte anzuzeigen. Dies ist ein nützliches Feature, um zum Beispiel seinen Parkplatz wiederfinden zu können.

Zudem wird das Aktivieren von Geofencing (zur Zeit nur über die Webseite) möglich. Dadurch kann bei Verlassen eines vordefinierten Bereichs eine Alarmierung erfolgen.

Das Kommunizieren der aktuellen Position erfolgt jeweils automatisch durch das Fahrzeug selbst. Eine Abfrage über die entsprechende API bzw. App ist für das Fahrzeug nicht nachvollziehbar. Es wird zum Beispiel kein Warnhinweis an den Fahrer geschickt.

Anzeige der Lokation in der Mercedes me App

Aktionen auslösen

Es besteht die Möglichkeit, dass in eng begrenztem Rahmen, aktive Aktionen ausgelöst werden können. Vornehmlich ist dies das Öffnen und Schliessen des Fahrzeugs. Hierfür werden die Türen doors mit dem Befehl unlock für Öffnen oder lock für Schliessen angesteuert. Das Auslösen von Aktionen erfolgt über HTTP POST-Anfragen.

curl -X POST \
  https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles/YOUR_VEHICLE_ID/doors \
  -H 'Authorization: Bearer YOUR_ACESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"command" : "LOCK"}'

Bis das asynchrone Kommando das Auto erreicht, von diesem Ausgeführt und bestätigt wird, dauert es einige Sekunden. Während dieser Zeit wird zuerst der Status INITIATED (Phase 1) und danach der Status PENDING (Phase 2) zurückgegeben:

{
    "status":"PENDING",
    "errors":null,
    "data":null
}

Falls die Aktion erfolgreich ausgeführt werden konnte (Phase 3), dann werden noch einmal sämtliche Telemetriedaten wie bei der Anfrage mit dynamic übermittelt. Der Unterschied besteht aber darin, dass die Rückantwort sowohl status als auch etwaige errors der ausgeführten Aktion enthält (gekürzt):

{
    "status":"SUCCESS",
    "errors":null,
    "data":{
        "readingLampFrontRight":{
            "value":false,
            "status":"VALID"
        },
        (...)

Der Benutzer wird über die Türöffnung auf verschiedenen Kanälen informiert. Einerseits erhält er eine Push-Notification auf dem Smartphone via Mercedes me App. Andererseits erhält er eine Benachrichtigung per Email an die registrierte Mailadresse. In diesem Schreiben wird über den aktuellen Zustand der Türöffnung informiert:

The Mercedes me connect door locking function unlocked the vehicle on 08.03.2018 at 14:12:32. 

The last known status of the vehicle doors was:
No doors open.

The current status of the doors can be viewed in the Mercedes me connect App or by visiting the website at  https://connect.mercedes.me.

Desweiteren bieten die Modelle ab E-Klasse seit 2016 einen Remote Parking Pilot. Über diesen wird es möglich, das Auto automatisch ein- und auszuparkieren. Dies ist besonders bei engen und unwegsamen Parkplätzen von Nutzen.

Angriffsmöglichkeiten

Vernetzte Fahrzeuge, vor allem mit Always-On Funktionalität, werden zu Recht seit ihrer Markteinführung mit skeptischen Blicken beäugt. Die erweiterte Funktionalität führt ein Mehr an Angriffsmöglichkeiten ein.

App: DoS, Sniffing, Replay und Injection

Die vernetzte Mercedes me App auf dem Smartphone kommuniziert mit den Server-Systemen bei Mercedes. Diese Kommunikation findet über HTTPS statt. Ein Aufbrechen dieser Kommunikation ist, so haben wir im Rahmen der hier vorgetragenen Analyse illustriert, möglich. Es macht den Anschein, als würde im Rahmen der Authentisierung ein Key Pinning stattfinden. Dieser Schritt konnte nicht ohne weiteres mitgelesen werden. Ist die Kommunikation jedoch authentisiert, kann mit einem üblichen Webproxy der Datenaustausch aufgebrochen, mitgelesen und manipuliert werden.

Entsprechend bieten sich destruktive Angriffe über Flooding oder Redirects an, um die Kommunikation zu unterbinden. Im Rahmen des Auslesens von Fahrzeug- und Telemetriedaten wäre dies im alltäglichen Gebrauch höchstens ärgerlich. Falls aber jemand die App nutzt, um das Fahrzeug nachträglich abzuschliessen, wäre damit eine Schliessung zu verhindern (Denial of Service). Dies könnte wiederum einen Diebstahl erleichtern bzw. ermöglichen.

Wurde einmal eine Authentisierung erfolgreich durchgeführt und diese oder eine nachträgliche Kommunikation mitgelesen, kann der Angreifer sie nach belieben weiterführen. Durch das Nachbilden der Access-Token kann eine Replay-Attacke durchgesetzt werden. Mindestens so lange, bis eine Erneuerung der Authentisierung erforderlich wird. Gegenwärtig sieht die API eine Re-Authentisierung nach 60 Minuten vor.

Fahrzeug: Erweiterte Angriffsfläche und Privatsphäre

Die mit dem Internet verbundenen Fahrzeuge kommen naturbedingt mit einer erweiterten Angriffsfläche daher. Sie sind ständig erreichbar, müssen Anfragen verarbeiten und auf diese reagieren können. Es ist absehbar, dass Programmier- und Logikfehler dazu führen können, eine Schwachstelle ausnutzen zu können.

Die vernetzten Fahrzeuge müssen als mobile Computer im Sinn des Internet of Things (IoT) behandelt werden. Sie werden, mindestens in naher Zukunft, mit den gleichen Problemen zu kämpfen haben, wie wir es von Webcams und Medizinalgeräten her kennen.

Im Unterschied sieht sich die Autoindustrie aber zusätzlichen Auflagen bezüglich Safety verbunden, was sich ebenfalls positiv auf die Security der entsprechenden Fahrzeuge auswirken wird. Es ist damit zu rechnen, dass Hersteller über einen verhältnismässig langen Zeitraum Sicherheitspatches und Updates zur Verfügung stellen werden. Was jedoch passiert, sobald ein Fahrzeug bzw. dessen Computerelektronik als End-of-Life (EOL) gilt, muss die Zukunft zuerst noch zeigen. Es bleibt zu hoffen, dass die Gesetzgebung faire Auflagen sowohl für Käufer als auch für Hersteller durchsetzen wird.

Generell führt das Prinzip von Always-On ein Verlust der Privatsphäre mit sich. Der Autohersteller weiss zu jedem Zeitpunkt, wo sich das Fahrzeug befindet. Er kann auf die Statusinformationen zugreifen. Und sogar bei Bedarf Funktionen deaktivieren. Letzteres vermag zum Beispiel aus Sicherheitsgründen stattfinden, da sich ein verbautes Teil als risikoreich herausgestellt hat. Es kann aber auch passieren, weil man plötzlich gewisse Funktionen nicht mehr unterstützen will. Mit dem automatischen Einspielen jeder neuer Firmware-Version geht das Risiko einher, dass eine Verschlimmbesserung des Fahrzeugs durchgesetzt werden könnte. Vor allem bei vollautomaisierten Updates kann dies zu unliebsamen Überraschungen führen.

Ausblick Research

Das Thema Car Hacking ist und bleibt für uns als Unternehmen interessant. Unsere Forschungsabteilung Titanium beschäftigt sich mit diversen Aspekten des vielschichtigen Themas.

Die sicherheitstechnische Analyse der Sensoren und Logik büsst keine Brisanz ein. Die Zunahme der Funktionalität führt zu mehr Angriffsfläche, die sich im Rahmen verschiedener Szenarien zum eigenen Vorteil nutzen lässt. Neben OBD wurden in den letzten Jahren genau die hier beschriebenen Online-Dienste interessant. In diesem Bereich gibt es viele Punkte, die noch nicht oder nicht ausreichend untersucht wurden.

Unter anderem werden wir im Rahmen unserer Forschung im Bereich Künstliche Intelligenz ebenso die technischen, psychologischen und soziologischen Aspekte der integrierten Sprachassistenten sowie der Anbindung über Amazon Alexa untersuchen.

Fazit

Alle grossen Autohersteller bieten mittlerweile die Vernetzung ihrer Fahrzeuge an. Mercedes nutzt die Mercedes me App, um Fahrzeug- und Telemetriedaten auslesen zu können. Vereinzelt sind aktive Aktionen, wie das Öffnen der Schliessmechanik möglich. Dies wird über Standardtechnologien wie HTTP, REST, OAuth und JSON realisiert.

Mit den erweiterten Möglichkeiten gehen zusätzliche Risiken einher. Einerseits kann die App bzw. die App-Kommunikation angegriffen werden. Andererseits wird das vernetzte Auto um seine Angriffsfläche, teilweise sogar permanent, erweitert.

Die gegenwärtig eingeschränkten Möglichkeiten der API verhindern schlimmste Konsequenzen. Es ist aber absehbar, dass zukünftig immer mehr Funktionalität über diese Vernetzung genutzt werden kann. Diese Entwicklung muss skeptisch beobachtet und höchste Anforderungen an die Sicherheit der Fahrzeuge gestellt werden. Hier muss sich der Gesetzgeber im Sinn von Safety und Security einsetzen, um sowohl für Konsumenten als auch für Hersteller eine faire und nachhaltige Lösung etablieren zu können.

Über den Autor

Marc Ruef

Marc Ruef ist seit Ende der 1990er Jahre im Cybersecurity-Bereich aktiv. Er hat vor allem im deutschsprachigen Raum aufgrund der Vielzahl durch ihn veröffentlichten Fachpublikationen und Bücher – dazu gehört besonders Die Kunst des Penetration Testing – Bekanntheit erlangt. Er ist Dozent an verschiedenen Fakultäten, darunter ETH, HWZ, HSLU und IKF. (ORCID 0000-0002-1328-6357)

Links

Sie wollen eine KI evaluieren oder entwickeln?

Unsere Spezialisten kontaktieren Sie gern!

×
Konkrete Kritik an CVSS4

Konkrete Kritik an CVSS4

Marc Ruef

scip Cybersecurity Forecast

scip Cybersecurity Forecast

Marc Ruef

Voice Authentisierung

Voice Authentisierung

Marc Ruef

Bug-Bounty

Bug-Bounty

Marc Ruef

Sie wollen mehr?

Weitere Artikel im Archiv

Sie brauchen Unterstützung bei einem solchen Projekt?

Unsere Spezialisten kontaktieren Sie gern!

Sie wollen mehr?

Weitere Artikel im Archiv