Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book

Fałszowanie certyfikatów COVID w Wietnamie. Czyli kryptografia używana na kolanie ;)

14 grudnia 2021, 14:30 | W biegu | komentarzy 6

Ciekawym opisem podzielił się zespół badaczy, który zaprezentował słabości klucza służącego do generowania certyfikatów COVID w postaci kodów QR w Wietnamie. Wykorzystując tę podatność, można było samodzielnie utworzyć certyfikat. Sam kod takiego dokumentu zawiera dość ciekawe dane, np.: typ pojazdu, numer rejestracyjny, liczba foteli, ID obywatela czy okres ważności certyfikatu.  Przykładowy „COVID pass” wygląda następująco:

Widoczny kod QR zawiera ciąg znaków o poniższej treści:

D9LOgcTFAS1MeC3kD4J+5PmAW5C4mOrPcbwbynsY6GEuGNkpe/dwIM5cr0MS/a+LT1y9z+8sKJA9UaPZTmYJwQ==|10505|3|06/09;07/09;08/09;09/09;10/09;11/09;12/09;13/09;14/09;15/09;16/09;17/09;18/09;19/09;20/09|4_PHÒNG CẢNH SÁT GIAO THÔNG|02439424451|29G1–391.89| |Vùng 1|Nguyễn Ánh Ngọc||09:00–20:00

Do kontroli tych certyfikatów przez służby, jak w większości państw, stosowana jest specjalna aplikacja o nazwie – w tym przypadku było to: „Kiểm soát đi đường” (obecnie usunięta, powodów nie znamy). Proces wydania certyfikatu odbywa się poprzez odpowiedni urząd; dokument jest podpisywany algorytmem SHA256 RSA (RSA z długością klucza 512 bitów). Podczas kontroli wystarczy zeskanować kod smartfonem, a aplikacja potwierdzi (bądź odrzuci) jego autentyczność. Wszystko odbywa się bez użycia połączeń z jakimkolwiek serwerem, co w tym przypadku miało tę wadę, że wystarczyło wykraść (lub złamać) klucz prywatny dla jednej ze stref kraju, aby móc generować poprawne certyfikaty samodzielnie.

W aplikacji zeskanowany kod QR staje się ciągiem znaków, ale na początku „usuwana” jest sygnatura, więc w konsekwencji operujemy na ciągu:

10505|3|06/09;07/09;08/09;09/09;10/09;11/09;12/09;13/09;14/09;15/09;16/09;17/09;18/09;19/09;20/09|4_PHÒNG CẢNH SÁT GIAO THÔNG|02439424451|29G1–391.89| |Vùng 1|Nguyễn Ánh Ngọc||09:00–20:00

Bazując na opisie autora, w dalszych krokach „usuwane” są pionowe kreski, znaki specjalne, znaki diakrytyczne są zastępowane angielskimi odpowiednikami, a całość jest zamieniana na małe litery, co powoduje powstanie jeszcze krótszego ciągu:

1050530609070908090909100911091209130914091509160917091809190920094_phongcanhsatgiaothong0243942445129g139189vung1nguyenanhngoc09002000

Zostaje on poddany hashowaniu (pseudokod widoczny poniżej), po którym otrzymujemy już tylko: 682673275. Weryfikacja poprawności odbywa się jedynie w aplikacji.

Hashcode = 0

Count = 0

For char in String:

Count += 1

Hashcode += char * Count

Hashcode = (1988 * Hashcode — 1910) / 2

Na tym etapie można wskazać pierwszą wadę aplikacji – taki krótki ciąg jest podatny na ataki kolizyjne. Oczywiście w opisywanym przypadku nastąpiła weryfikacja, ale używała ona zahardkorowanych w aplikacji słabych publicznych kluczy RSA 512. Ten algorytm (z takim kluczem) można stosunkowo łatwo złamać; akurat badacz użył gotowego rozwiązania z innego opracowania tematu kluczy RSA 512. Podając klucze publiczne z aplikacji, otrzymywaliśmy klucze prywatne, które z kolei można było wykorzystać do wygenerowania kodu QR.

Kod jest napisany w Pythonie i pochodzi z 2015 roku; jego uruchomienie zajęło dwa dni. Generalnie starsze programy czy skrypty są problematyczne, czasem korzyści płynące z ich wykorzystania wydają się mniej istotne niż czas poświęcony na próby dostosowania środowiska. Dobrze jest posiadać obrazy maszyn wirtualnych starszych systemów, ale nawet to nie zawsze pomoże.

Skrypt, jak widać, korzysta z Ansible (który również napisany jest w Pythonie) i służy do łamania kluczy RSA. Testowo udało się złamać klucz o długości 100 cyfr (330 bitów) co było potwierdzeniem działania skryptu.

Klucze w aplikacji miały długość 155 cyfr (RSA 512. Stack badaczy był następujący:

We used a total of 16 EC2 instances x 36 CPUs x 60 GiB Memory for each key. Once the script is run, the only thing we would do is waiting and hoping it will not return any FATAL errors.

Operacja łamania trwała 9 godzin i zakończyła się sukcesem. Jej koszt to 250 dolarów.

Następnie, dysponując otrzymanymi wartościami, wystarczyło obliczyć właściwą wartość klucza prywatnego i wygenerować poprawne certyfikaty.

250 dolarów to około 1025 złotych, a średnie wynagrodzenie w Wietnamie wynosi 6 100 000 dongów, czyli niecałe 1090 złotych. Jest mało prawdopodobne, że przeciętny mieszkaniec tego kraju poświęci niemal cały miesięczny dochód na próby obejścia aplikacji. Natomiast dzięki temu praktycznemu opisowi mamy możliwość poznać słabe praktyki bezpieczeństwa w zakresie kryptografii.

–Michał Giza

Spodobał Ci się wpis? Podziel się nim ze znajomymi:



Komentarze

  1. Szpecimy się!

    W sytuacji takiej jak ta jestem całym sercem za słabymi kluczami!

    Odpowiedz
    • asdsad

      Rozwiń, bo nikt nie wie co masz na myśli. Nawiedzenie jakieś?

      Odpowiedz
      • Szpecimy się!

        Napisałeś „nikt nie wie co masz na myśli. Nawiedzenie jakieś?”

        Skoro wypowiadasz się o zawartości myśli WSZYSTKICH ludzi, to prędzej u ciebie jest „nawiedzenie”.

        Odpowiedz
  2. Batrek

    Czyli zamiast sprawdzonej kryptografii asymetrycznej opartej na parze kluczy priv – public ( min 2048 dlugosc klucza ) tutaj zrobili hardcoded secret o dlugosci 512…. Gdzie tu sens i logika? Jeszcze w sha256 ktore pieknie skaluje sie na GPU czy ASICach do krypto…

    Odpowiedz
  3. Wiktor

    Odnośnie ostatniego akapitu – $250 nie kosztuje pojedyncza próba obejścia aplikacji przez przeciętnego Wietnamczyka. Te $250 to koszt złamania głównego klucza do podpisywania wszystkich certyfikatów – czyli mając ten klucz można wygenerować dowolną liczę certyfikatów. A skoro tak, to prawdopodobne ceny za wystawienie lewego (choć poprawnego) certyfikatu będą znacząco niższe – mogę się założyć, że już powstała tam jakaś grupa trudniąca się tym procederem.

    Odpowiedz
  4. ___

    Podpisze petycje wymuszająca na agencjach rządowych używanie maksymalnie 512 bit rsa, aby inne służby mogły weryfikować czy ktoś nie działa na szkodę partii rządzącej ^^

    Odpowiedz

Odpowiedz