User Tools

Site Tools


zapamtime

This is an old revision of the document!


Zadatak s Hacknite platforme - Zapamti me

Naši kolačići koriste najnovije sigurnosne tehnologije

http://chal.platforma.hacknite.hr:14003

Uz zadatak je dan i izvorni kod.

Stranica ima samo Register/Login i stranicu kojoj se pristupa nakon što se ulogira s korisnikom, a koja ispisuje samo pozdrav.

Pregledom source koda vidi se da postoji *Dockerfile* u kojem je definirana ENV flag varijabla, ali nema ništa što na prvi pogled pokazuje ranjivost.

Osim *Dockerfilea*, jedini drugi izvorni kod je server.js, u kojem se nalazi sav kod koji pokreće stranicu.

Pri analizi koda vidi se da je adminov username “administrator0”:

const ADMIN_NAME = 'administrator0';

Također se vidi da stranica koristi *secret* varijablu koja je sastavljena od 22 nasumična bajta, generirana pomoću *crypto.randomBytes* modula, što znači da bi trebala biti sigurna.

Također, *FLAG* je definiran kao varijabla.

 Slika 1 – administrator username i secret varijabla

Nakon toga slijedi inicijalizacija baze podataka.

 Slika 2 – inicijalizacija baze podataka

U inicijalizaciji baze podataka vidi se da svaki korisnik ima ID, username, password, token, *isAdmin* varijablu (koja je po defaultu 0) te vrijeme kada je korisnik stvoren.

Također se vidi da se administratorski korisnik postavlja s vrijednošću 1 za *isAdmin*.

Ključan dio koda je način na koji se generira token.

 Slika 3 – generiranje admin tokena

Token se generira kao string koji se sastoji od *secret* varijable, *usernamea* i *ID-a* korisnika, a zatim se ubacuje u *bcrypt.hash* funkciju, koristeći i *BCRYPT_SALT*.

 Slika 4 – BCRYPT_SALT varijabla

*BCRYPT_SALT* varijabla se generira u *initializeAuth* funkciji koja se poziva samo jednom pri pokretanju servera. To znači da će ta varijabla biti ista tijekom cijelog životnog vijeka aplikacije.

Nadalje, u administratorskom tokenu nalazi se i *adminId*, koji se generira pomoću sljedećih linija koda:

17. linija koda:
const UUID_NAMESPACE = '1b671a64-40d5-491e-99b0-da01ff1f3341';

54. linija koda:
const adminId = uuidv5(ADMIN_NAME, UUID_NAMESPACE);

Funkcija *uuidv5* je deterministička — za isti par *username* i *namespace* svaki put će generirati isti UUID.

To znači da u generaciji administratorskog tokena (slika 3) od tri varijable — *secret*, *ADMIN_NAME* i *adminId* — poznajemo *ADMIN_NAME* (“administrator0”) i možemo lokalno rekreirati isti *adminId* kao onaj koji koristi aplikacija.

Budući da su i *secret* i *BCRYPT_SALT* varijable konstante dok aplikacija radi, token administratora uvijek se računa na isti način.

Ključna činjenica zadatka temelji se na ponašanju funkcije:

bcrypt.hash

Naime, *bcrypt.hash* uzima samo prvih 72 znaka danih kao ulaz i iz njih generira sažetak, dok sve znakove nakon 72. odbacuje. Zato dva unosa s istih prvih 72 znaka daju isti hash, bez obzira na razlike iza 72. znaka.

Pregledom *tokenString* varijable, koja se ubacuje u *bcrypt.hash* i generira administratorski token, vidi se njezina duljina.

Varijabla se sastoji od tri stringa: *secret*, *ADMIN_NAME* i *adminId*.

- *secret* = 22 znaka - *ADMIN_NAME* = 14 znakova (“administrator0”) - *adminId* = 36 znakova (UUID)

Zbrajanjem 22 + 14 + 36 dobiva se 72, što je točno broj znakova koje *bcrypt.hash* uzima u obzir.

Sada pogledajmo kako se generira token pri stvaranju novog korisnika, što se događa u “/register” endpointu.

 Slika 5 – registracija novog korisnika

Može se vidjeti da se token za novog korisnika generira na isti način kao i administratorski token.

 Slika 6 – token novog korisnika

Koristi se ista *secret* varijabla i ista *BCRYPT_SALT* vrijednost kao i kod generiranja administratorskog tokena.

Jedine dvije različite vrijednosti su *username* i *userId*.

Na *userId* nemamo utjecaj, ali *username* možemo kontrolirati.

Budući da je *secret* duljine 22, a *bcrypt.hash* uzima samo prvih 72 znaka, ako unesemo *username* duljine 50, on će “istisnuti” *userId* iz dijela koji *bcrypt.hash* koristi. To znači da *userId* uopće neće ući u generiranje korisničkog tokena.

Na taj način imamo potpunu kontrolu nad 50 znakova (nakon *secret*), koji će sudjelovati u generiranju tokena.

Pošto su *secret* i *BCRYPT_SALT* isti pri generiranju oba tokena (admin i user), ako uspijemo manipulirati tih 50 znakova da budu isti kao kod administratora, dobit ćemo identičan token.

Da bi to bilo moguće, mora vrijediti:

naš_username = admin_username + adminId

Vrijednosti *admin_username* i *adminId* su poznate ili se mogu rekonstruirati.

Preostaje pokrenuti aplikaciju lokalno kako bismo saznali *adminId* i napravili korisnika s odgovarajućim imenom.

Možemo dodati liniju koda koja će ispisati *adminId*:

 Slika 7 – ispis adminId-a

Pokretanjem programa naredbom:

node server.js

vidjet ćemo *adminId*, koji će biti isti kao i na produkcijskom serveru.

 Slika 8 – adminId

a1653d44-7862-5db2-b60a-afce3f20ed74

Sada znamo sve potrebne informacije za generiranje istog tokena kao administrator.

Analizom *token middleware* funkcije vidi se kako se koristi token:

 Slika 9 – token middleware

Middleware dohvaća token iz kolačića, traži prvog korisnika u bazi s tim tokenom i postavlja sesiju kao tog korisnika.

Pošto se uzima prvi user u bazi, a administrator je uvijek prvi kreirani korisnik, bilo koji kasniji korisnik s istim tokenom automatski postaje administrator.

Dakle, rješenje je kreirati novog korisnika s *usernameom*:

administrator0a1653d44-7862-5db2-b60a-afce3f20ed74

Možemo dodati još nekoliko znakova na kraj (koji ionako neće ući u prvih 72 znaka *bcrypt.hash* funkcije) da izbjegnemo grešku ako korisničko ime već postoji.

Dakle, svaki korisnik s *usernameom* oblika:

administrator0a1653d44-7862-5db2-b60a-afce3f20ed74<bilo_koji_znakovi>

imat će isti token kao administrator.

Pri pokušaju logina vidi se da postoji ograničenje maksimalnog broja znakova u korisničkom imenu (14 znakova), što bi onemogućilo ovu tehniku.

 Slika 10 – ograničenje broja znakova u usernameu

No to ograničenje nije implementirano na serverskoj strani, nego samo u HTML kodu (klijentskoj strani), pa se lako može zaobići — brisanjem dijela HTML-a prikazanog na slici 11. ili korištenjem *BurpSuite* alata.

 Slika 11 – brisanje ograničenja za dužinu usernamea na korisničkoj strani

Sada se može stvoriti korisnički račun koji će imati isti token kao administrator, što je prikazano na slici 12.

 Slika 12 – stvaranje korisnika s istim tokenom kao administrator

 Slika 13 – riješen zadatak

zapamtime.1761842174.txt.gz · Last modified: 2025/12/01 11:40 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki