Length extension attack

Hashevi koji koriste Merkle-Damgård konstrukciju (npr. MD5, SHA1 i SHA2) imaju sljedeće svojstvo: ako nam je poznat hash(M1) gdje je M1 neka proizvoljna poruka i znamo duljinu poruke M1, možemo izračunati hash(M1+M2) gdje je M2 neka druga proizvoljna poruka čak ako ne znamo sadržaj poruke M1.

To je moguće zato što Merkle-Damgård konstrukcija pri hashiranju dijeli sadržaj u blokove. Zato je moguće iz hasha rekonstruirati interno stanje hash funkcije i jednostavno nadodati sadržaj M2 (i nadopunu) kao sljedeći blok.

To svojstvo može predstavljati ranjivost, ako se taj hash koristi kao MAC.

Zamislimo aplikaciju koja poslužuje datoteke koje korisnik zatraži, ali kako bi autentificirao korisnika prvo validira MAC. MAC kod bi se mogao izračunati na sljedeći način: MD5(tajna_vrijednost + ime_datoteke)

Ako je napadaču poznat jedan takav MAC, npr. MD5(tajna_vrijednost + datoteka1) i ako zna (ili može pogoditi) koliko je dug string tajna + datoteka1, tada može generirati validnu MAC vrijednost MD5(tajna_vrijednost + datoteka1 + proizvoljni_sufiks), primjerice može generirati vrijednost MD5(tajna_vrijednost + datoteka123). To može učiniti iako mu tajna_vrijednost nije poznata!

Jedan od alata kojim se može izvesti ovakav napad je hash_extender [1].

PRIMJER - Zadatak s Hacknite platforme - Digitalni potpis

Stjepan je osmislio inovativan način autentifikacije. Umjesto lozinke, korisnici moraju učitati digitalno 
potpisanu datoteku koja dokazuje njihov identitet. Je li autentifikacija implementirana na siguran način?

Dostupna Vam je python skripta za generiranje datoteka i digitalno potpisana datoteka niskoprivilegiranog 
korisnika, ali ne i tajna lozinka koja se koristi za digitalno potpisivanje.

Hint: length extension attack

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

Flag je u formatu CTF2023[brojevi].

Proučimo skriptu gen_signed_dokument.py

import sys
import hashlib
 
secret = ""
 
if len(sys.argv[1]) == 32:
    secret = sys.argv[1]
else:
    sys.exit(1)
 
 
data = ""
fullname = sys.argv[2]
data+=fullname
 
if len(sys.argv)==4:
    data+="\ncan_read_flag"
 
signature = hashlib.md5((secret+data).encode("ascii")).hexdigest()
test_dokument = open("test_dokument.txt","w")
test_dokument.write(signature)
test_dokument.write("\n")
test_dokument.write(data)

Iz koda vidimo da se MAC generira algoritmom MD5(secret+data), nije nam poznat secret, ali iz koda možemo saznati da on mora bit dug 32 znaka. Podaci za koje se generira MAC su ime korisnika i opcionalno tekst can_read_flag

Također nam je dostupan dokument niskoprivilegiranog korisnika test_dokument.txt. Na prvoj liniji se nalazi MAC, a na drugoj korisničko ime. Kada učitamo dokument, dobijemo poruku da trenutno nemamo nikakve privilegije u sustavu.

Kada pokušamo jednostavno dodati tekst can_read_flag na kraj dokumenta dobijemo poruku Ne može!

To se dogodilo zato što je u tom dokumentu valjani MAC za tekst

testni_korisnik

a ne za

testni_korisnik
can_read_flag

Možemo zaključiti da trebamo generirati dokument koji ima u sebi ime korisnika, tekst can_read_flag i validni MAC. Budući da ne znamo tajnu vrijednost, ne možemo jednostavno izračunati valjani MAC, a, budući da je tajna duga 32 znaka, ne možemo ju ni pogoditi. Međutim, imamo valjani MAC za tekst testni_korisnik, a poznata nam je i duljina tajne, pa možemo izvesti napad produljenjem.
Koristimo alat hash_extender

./hash_extender --data=testni_korisnik --signature=0cad728d48584e1650aaf9e978690111 --append="
	can_read_flag" --out-data-format=fancy --secret 32

U argument –data postavljamo podatak testni_korisnik zato što za taj niz znakova imamo validni MAC, u argument signature stavljamo MAC iz testne datoteke , u argument append dodajemo tekst koji želimo nadodati na kraj datoteke (paziti da se treba dodati i newline!) te kao veličinu tajne stavljamo 32 (što smo iščitali iz koda).

Kao ispis programa dobili smo novogenerirani validni MAC te hexdump novog dokumenta. Osim teksta can_read_flag dodana je i nadopuna (engl. padding). Alat je generirao novi MAC i za md5 i za md4 algoritam, u ovom slučaju nas zanima samo md5.

S hex editorom kao što su HxD ili xxd tako možemo konstruirati novu datoteku s validnim MAC-om kao prvom linijom. Slika prikazuje hexdump finalne datoteke.

Kad učitamo datoteku dobijemo flag.

Izvori

[1] https://github.com/iagox86/hash_extender