Cryptographic Failures - Ruzica74/sigurnost GitHub Wiki

Cryptographic Failures

Šta su kriptografski otkazi?


Kriptografija je tehnika koja proučava principe i metode šifrovanja podataka. Koristi za zaštitu osjetljivih informacija, kao i za osiguravanje integriteta, autentičnosti i povjerljivosti podataka. Ima ključnu ulogu u zaštiti od raznih sigurnosnih rizika i potencijalnih zloupotreba. Kriptografski otkazi odnose se na slabosti ili ranjivosti u kriptografskim sistema, algoritmima ili implementacijama koje mogu ugroziti sigurnost šifrovanih podataka.

Neki od najvećih problema koji dovode do kriptografskih otkaza su slabo upravljanje ključevima, korištenje slabih algoritama, greške u implementaciji, problemi sa generisanjem slučajnih brojeva, napadi na osnovu informacija dobijenih iz fizičke implementacije kriptografskog sistema itd.


Opis problema (Slabo upravljanje ključevima)

Kao što je već prethodno rečeno aplikacija DocumentSystem koristi JWT token da bi se vodila sesija sa korisnikom. Na Slici 1. je prikazano kako korisnik dobija token prilikom prijavljivanja na aplikaciju. Korisnik kada se prijavljuje u aplikaciju šalje korisničko ime i šifru, kada se potvrdi njegov identitet, on dobija pristup resursima aplikacije i dodjeljuje mu se token. On dalje sa tim tokenom može da korisi aplikaciju u okviru svojih prava. Svaki put kada se šalje zahtjev za određeni resurs ili vršenje akcije brisanja, dodavanja ili mijenjanja resursa prosljeđuje se token zajedno sa tim zahtjevom. Token je zaslužan za obezbjeđivanje autentifikacije i autorizacije aktivnosti. U slučaju aplikacije DocumentSystem postoji jedan server gdje su funkcionalnosti autorizacije i resursa objedinjene na jednom mjestu.

Slika 1.

Zašto je uopšte JWT token zanimljiv kada se govori o kriptografskim otkazima, jeste zato što koristi određeni simetrični ili asimetrični algoritam za potpis svog sadržaja. Izgled jednog JWT tokena se može vidjeti na Slici 2. Prvi dio je zaglavlje koje ima dva dijela obično: koji je tip tokena, u ovom slučaju JWT i koji je algoritam korišten. U aplikaciji je korišten HMAC SHA512. Taj dio je Base64Url enkodovan. Base64 je šema za enkodovanje binarnih podataka u tekstualni format koristeći ASCII znakove. Ovo enkodovanje je lako reverzibilno i ne obezbjeđuje tajnost. Često se koristi za formatiranje podataka koji se prenose. Base64Url je varijanta Base64 enkodovanja koja se može koristiti unutar URL-a, tako što se izbjegava korištenje rezervisanjih znakova kao što su '=', '+' ili '/', na taj način ne može doći do konfuzije. Kodovanje se vrši tako što se ulazni podaci razbiju u grupe po tri bajta i svaka od njih se koduje sa 4 znaka iz skupa znakova Base64. Drugi dio JWT-a je tijelo u kojem se nalaze tvrdnje, tj. neki korisni podaci uglavnom o korisniku. Ovaj dio je, takođe, Base64url enkodovan. Treći dio predstavlja potpis, koji je ovdje i najznačajniji. On se kreira tako što se enkodovano zaglavlje i tijelo potpisuju za algoritmom, koji je naveden u zaglavlju.

jwt-anatomy

Slika 2.

Svrha potpisa jeste da osigura da se poruka tokom prenosa nije mijenjala i da je izdavač tokena onaj za koga se predstavlja da jeste. Za potpisivanje mogu da se koriste simetrični ili asimetrični algoritmi. Asimetrični algoritmi su dizajnirani tako da koriste jedan ključ (privatni) za kriptovanje, a drugi (javni) za dekriptovanje podataka. Na taj način, ako npr. Bob hoće da koristi asimetrični algoritam za komunikaciju generisaće par ključev, javni i privatni, zatim će poslati samo javni ključ Alice. Na taj način Alice će moći da izvrši provjeru vjerodostojnosti potpisa, koji je napravljen sa privatnim ključem.

RSA je asimetrični algoritam koji se koristi za enkripciju i digitalno potpisivanje, koji koristi JWT kada je potreban veći stepen sigurnosti. Pogodan je zato što sa njim klijent može samo da verifikuje ili dekriptuje poruku, ali ne može na napravi novu kao u slučaju simetričnih algoritama. Na Slici 3. je prikazano objašnjeno funkcionisanje asimetričnog RSA algoritama.

how-does-an-rsa-work

Slika 3.

Simetrični algoritmi su oni algoritmi koji za enkripciju i dekripciju podataka koriste jedan ključ ili se na osnovu jednog ključa kalkulacijama može dobiti drugi ključ. Na Slici 4. prikazana je šema kako funkcioniše enkripcija i dekripcija sa simetričnim algoritmom. Ključ se naziva tajnim ili dijeljenim ključem. Sigurnost kriptografskog sistema bazira se na tajnosti ključa, a ne na tajnosti algoritma, s toga je jako bitno da se vodi računa o tome gdje se smješta ključ i koji ključ se u suštini koristi. Kod ovakvih algoritama dužina ključa je najbitnija komponenta i što je veći ključ to je šifrovana poruka sigurnija.

symmetric-encryption

Slika 4.

Simetrični algoritmi koji se koriste unutar JWT tokena su uglavnom HMAC SHA256 ili HMAC SHA512. HMAC (Hash-based Message Authentication Code) kreira kod za autentifikaciju koristeći heš funkciju u kombinaciji sa tajnim ključem. Haš algoritmi su kriptografske funkcije koje uzimaju ulazne podatke različitih veličina i od njih proizvode izlazni string fiksne dužine. SHA256 i SHA512 spadaju u grupu SHA-2 hešing algoritama, a brojevi u njihovim imenima govore koju dužinu ima izlaz iz funkcije. Ove funkcije nisu reverzibilne. U procesu HMAC enkodovanja tajni ključ se miješa sa porukom, zatim se rezultat hešira sa heš funkcijom, nakon toga se opet dobijena heš vrijednost miješa sa ključem i po drugi put se sve hešira. Izlaz heša na kraju će biti 512 bitova, jer se u aplikaciji koristi SHA512.

Na Slici 5. je prikazana autentifikacija korisnika prilikom logovanja i ako je uspješan ishod poziva se funkcija, prikazana na Slici 6, koja služi za generisanje JWT tokena.

Slika 5.

Slika 6.

Tajni ključ koji se koristi za potpisivanje JWT tokena se nalazi u datoteci aplication.properties, te je prikazan na Slici 7. Tajnost ključa je jedna od najznačajnihih stvaki za pravilno funkcionisanje JWT tokena. Iako se taj ključ skladišti na adekvatan način, postoji opet opasnost u slučaju da se koristi ključ koji se lako može provaliti pogađanjem ili brut-force metodom. Brute-force metoda se služi pokušajem i greškom da dođe do određenog tajnog ključa, a primjenjuje se i za otkirvanje šifara ili login kredencijala. U ovom slučaju brut-force metodu ili pogađanje ključa čini mogućim ako programer zaboravi da promijeni podrazumijevani ili placeholder ključ. Često prilikom razvoja aplikacije dešava se da se kopiraju isječci koda koji se nađu online, među kojima budu i hardkodovani ključevi dati kao primjer. Koristeći listu dobro poznatih ključeva, koji se nalazi na sledećoj stranici https://github.com/wallarm/jwt-secrets/blob/master/jwt.secrets.list, može biti trivijalno zadobijanje tajnog ključa. Na Slici 8. je prikazan isječak iz liste dobro poznatih ključeva, među kojima se nalazi i ključ koji je korišten u aplikaciji.

Slika 7.

Slika 8.

Da bi napadač saznao da se ključ zaista nalazi u listi dobro poznatih ključeva, brut-force napad može da izvrši u komandnoj liniji uz pomoć hashcat-a. Ovaj alat dolazi već instaliran u Kali distribuciji Linux-a, a može se i manualno instalirati. Za ovo je potrebno samo da napadač ima validno potpisan JWT token i listu ključeva. Nakon toga se pokreće komanda prikazana na Slici 9.

Slika 9.

Hashcat će zatim potpisivati zaglavlje i tijelo tokena sa svakim ključem u listi i porediti ga sa postojećim potpisom dobijenim od servera. Ako se ijedan ključ poklapa dobiće se ispis u formatu prikazanom na Slici 10. Sve ovo se izvršava veoma brzo na lokalnoj mašini i nema nikakvih poziva ka serveru. Nakon otkrivanja tajnog ključa, napadač može da generiše validan potpis za bilo koje zaglavlje i tijelo.

Slika 10.

Posljedice problema

Kada se kreira token, serveri uobičajeno ne čuvaju informacije o JWT tokenima koje izdaju. Tako da je svaki token entitet za sebe. Kao posljedica ovoga server ne zna koje informacije se originalno nalaze u tokenu niti koji je originalni potpis. Ukoliko napadač dođe u posjed ključa kojim se potpisuje JWT token, ništa ga ne sprječava da kreira sam tokene sa bilo kojim vrijednostima u zaglavlju i tijelu tokena i zatim potpiše taj token sa validnim potpisom koristeći tajni ključ. Kolike izmjene može da napravi napadač unutar tokena koji šalje zavisi i od toga kako aplikacija provjerava token, tj. da li uopšte provjerava navedene informacije o korisniku koji vrši akcije tokenom. Informacije koje se nalaze u tokenu koji izdaje DocumentSystem aplikacija su korisničko ime, vrijeme isticanja tokena, rola i id korisnika, što je prikazano na Slici 6. Na Slici 11. je prikazana funkcija doFilterInternal koja se koristi za validiranje tokena pri svakom zahtjevu poslanom ka serveru. Nakon što se provjeri potpis i validnost tokena, preuzimaju se informacije o korisniku iz tokena, među kojima je i rola korisnika. Pored toga što napadač može da se prijavi onda na aplikaciju sa validnim tokenom, on može i potencijalno da izvrši eskalaciju privilegija te dodijeli sebi administratorska prava. Ovakva vrsta napada već spada u pokvarenu kontrolu pristupa, ali često jedan napad se ne može samo kvalifikovati u samo jednu vrstu problema već se prepliće više vrsta napada.

Slika 11.

Rješenja problema

Korištenje sigurnih kriptografskih algoritama i tehnika, ne znači da je posao oko sigurnosti i zaštite gotov i da se nikakav napad ne može uspješno izvršiti. Ako se ne vodi računa o tome kakvi ključevi se koriste i kako se oni skladište i dijele u slučaju da je to potrebno, može opet doći do probijanja sistema. Implementacija ima veliki uticaj na to koji stepen sigurnosti će se postići. Rješenje navedenog problema se može postići tako što će se promijeniti tajni kljuć, tako da se ne nalazi na listi dobro poznatih ključeva. Poželjno je da ključ bude što veće dužine i da se sastoji od stringa slučajno odabranih karaktera. Potrebno je voditi računa da se isprave sve postavke sistema, koje su se koristile u toku razvoja aplikacije, a koje bi potencijalno mogle da ugroze sistem. Prevencija se u dobrom slučaju se vrši potpunim razumijevanjem kako funkcioniše JWT mehanizam i koje sve sigurnosne implikacije ima.