zapamtime
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| zapamtime [2025/10/31 15:22] – mbunic | zapamtime [2025/12/01 11:40] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 5: | Line 5: | ||
| http:// | http:// | ||
| - | |||
| </ | </ | ||
| - | |||
| Uz zadatak je dan i izvorni kod. \\ | Uz zadatak je dan i izvorni kod. \\ | ||
| - | Stranica ima samo Register/ | + | Stranica ima samo Register/ |
| - | 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. | + | Pregledom source koda, vidi se da postoji **Dockerfile**, u kojem je definirana **ENV flag** varijabla |
| - | Osim **Dockerfilea**, jedini drugi izvorni kod je **server.js**, | + | Osim Dockerfilea, |
| - | Pri analizi koda vidi se da je adminov username | + | Pri analizi |
| < | < | ||
| Line 23: | Line 21: | ||
| </ | </ | ||
| - | Također se vidi da stranica koristi **secret** | + | Također se vidi da stranica koristi |
| - | Također, **FLAG** | + | Također |
| - | {{ : | + | {{ zapamtime: |
| Nakon toga slijedi inicijalizacija baze podataka. \\ | Nakon toga slijedi inicijalizacija baze podataka. \\ | ||
| - | {{ : | + | {{ zapamtime: |
| - | 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 | + | 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 korisnički račun |
| Također se vidi da se administratorski korisnik postavlja s vrijednošću 1 za **isAdmin**. | Također se vidi da se administratorski korisnik postavlja s vrijednošću 1 za **isAdmin**. | ||
| Line 39: | Line 37: | ||
| Ključan dio koda je način na koji se generira token. \\ | Ključan dio koda je način na koji se generira token. \\ | ||
| - | {{ : | + | {{ zapamtime: |
| - | 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**. | + | 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**. |
| - | {{ : | + | {{ zapamtime: |
| **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. | **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. | ||
| Line 59: | Line 57: | ||
| Funkcija **uuidv5** je deterministička — za isti par **username** i **namespace** svaki put će generirati isti UUID. | 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** — | + | To znači da u generaciji administratorskog tokena (slika 3) od tri varijable — **secret**, **ADMIN_NAME** i **adminId** — poznajemo **ADMIN_NAME** (“administrator0”), možemo lokalno |
| - | poznajemo **ADMIN_NAME** (“administrator0”) | + | |
| - | Budući da su i **secret** i **BCRYPT_SALT** varijable konstante dok aplikacija radi, token administratora uvijek | + | Budući da su i **secret** i **BCRYPT_SALT** varijable konstante dok aplikacija radi, ove dvije varijable će imati istu vrijednost kada će se koristiti za generaciju tokena korisnika. |
| Ključna činjenica zadatka temelji se na ponašanju funkcije: | Ključna činjenica zadatka temelji se na ponašanju funkcije: | ||
| Line 73: | Line 70: | ||
| Zato dva unosa s istih prvih 72 znaka daju isti hash, bez obzira na razlike iza 72. znaka. | 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, | + | Pregledom **tokenString** varijable, koja se ubacuje u **bcrypt.hash** i generira administratorski token, |
| Varijabla se sastoji od tri stringa: **secret**, **ADMIN_NAME** i **adminId**. | Varijabla se sastoji od tri stringa: **secret**, **ADMIN_NAME** i **adminId**. | ||
| - | - **secret** = 22 znaka | + | < |
| - | - **ADMIN_NAME** = 14 znakova (“administrator0”) | + | secret = 22 znaka |
| - | - **adminId** = 36 znakova (UUID) | + | 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. | + | Zbrajanjem 22 + 14 + 36 dobiva se 72, što je točno broj znakova koje funkcija |
| --- | --- | ||
| Line 87: | Line 86: | ||
| Sada pogledajmo kako se generira token pri stvaranju novog korisnika, što se događa u “/ | Sada pogledajmo kako se generira token pri stvaranju novog korisnika, što se događa u “/ | ||
| - | {{ : | + | {{ zapamtime: |
| Može se vidjeti da se token za novog korisnika generira na isti način kao i administratorski token. \\ | Može se vidjeti da se token za novog korisnika generira na isti način kao i administratorski token. \\ | ||
| - | {{ : | + | {{ zapamtime: |
| Koristi se ista **secret** varijabla i ista **BCRYPT_SALT** vrijednost kao i kod generiranja administratorskog tokena. | Koristi se ista **secret** varijabla i ista **BCRYPT_SALT** vrijednost kao i kod generiranja administratorskog tokena. | ||
| Line 97: | Line 96: | ||
| Jedine dvije različite vrijednosti su **username** i **userId**. | Jedine dvije različite vrijednosti su **username** i **userId**. | ||
| - | Na **userId** nemamo utjecaj, ali **username** možemo kontrolirati. | + | Na vrijednost |
| + | |||
| + | Budući da je **secret** duljine 22, a **bcrypt.hash** uzima samo prvih 72 znaka, ako unesemo **username** duljine **50**, on će “izgurati” **userId** iz dijela koji **bcrypt.hash** koristi (prvih 72 znaka). | ||
| - | 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. | 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**), | Na taj način imamo potpunu kontrolu nad 50 znakova (nakon **secret**), | ||
| - | Pošto | + | Budući da 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, |
| Da bi to bilo moguće, mora vrijediti: | Da bi to bilo moguće, mora vrijediti: | ||
| Line 116: | Line 116: | ||
| --- | --- | ||
| - | Preostaje pokrenuti aplikaciju lokalno kako bismo saznali *adminId* i napravili korisnika s odgovarajućim imenom. | + | Preostaje pokrenuti aplikaciju lokalno kako bismo saznali |
| Možemo dodati liniju koda koja će ispisati **adminId**: | Možemo dodati liniju koda koja će ispisati **adminId**: | ||
| - | {{ : | + | {{ zapamtime: |
| Pokretanjem programa naredbom: | Pokretanjem programa naredbom: | ||
| Line 130: | Line 130: | ||
| vidjet ćemo **adminId**, | vidjet ćemo **adminId**, | ||
| - | {{ : | + | {{ zapamtime: |
| < | < | ||
| Line 140: | Line 140: | ||
| Analizom token middleware funkcije vidi se kako se koristi token: \\ | Analizom token middleware funkcije vidi se kako se koristi token: \\ | ||
| - | {{ : | + | {{ zapamtime: |
| Middleware dohvaća token iz kolačića, traži prvog korisnika u bazi s tim tokenom i postavlja sesiju kao tog korisnika. | 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 | + | Budući da se uzima **prvi user** u bazi, a administrator je uvijek prvi kreirani korisnik, bilo koji kasniji korisnik s istim tokenom automatski postaje administrator. |
| --- | --- | ||
| Line 168: | Line 168: | ||
| 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. \\ | 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. \\ | ||
| - | {{ : | + | {{ zapamtime: |
| - | 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. \\ | + | Međutim, |
| - | {{ : | + | {{ zapamtime: |
| Sada se može stvoriti korisnički račun koji će imati isti token kao administrator, | Sada se može stvoriti korisnički račun koji će imati isti token kao administrator, | ||
| - | {{ : | + | {{ zapamtime: |
| - | {{ : | + | {{ zapamtime: |
zapamtime.1761924168.txt.gz · Last modified: 2025/12/01 11:40 (external edit)