User Tools

Site Tools


aes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
aes [2023/11/20 10:10] zrinkaaes [2025/12/01 11:40] (current) – external edit 127.0.0.1
Line 35: Line 35:
  
 **2) CBC (Cipher Block Chaining)** **2) CBC (Cipher Block Chaining)**
-  * Svaki blok jasnog teksta se XOR-a sa skrivenim tekstom prošlo kruga enkripcije+  * Svaki blok jasnog teksta se XOR-a sa skrivenim tekstom prošlog kruga enkripcije
   * Potreban je inicijalizacijski vektor IV koji se mora izabrati nasumično   * Potreban je inicijalizacijski vektor IV koji se mora izabrati nasumično
   * IV se šalje zajedno sa skrivenim tekstom    * IV se šalje zajedno sa skrivenim tekstom 
Line 58: Line 58:
   *način autentifikacijskog kriptiranja koji je primjenjiv samo za simetrične blok algoritme s veličinom bloka od 128 bitova   *način autentifikacijskog kriptiranja koji je primjenjiv samo za simetrične blok algoritme s veličinom bloka od 128 bitova
   * samo za autentifikaciju – koristi [[mac|MAC]]   * samo za autentifikaciju – koristi [[mac|MAC]]
-  * ulaz: jasni tekst, IV, povezani autentifikacijski podaci (Associated Data, AD ), duljina povezanih podataka i duljina kriptiranog teksta+  * ulaz: jasni tekst, IV, povezani autentifikacijski podaci (Associated Data, AD), duljina povezanih podataka i duljina kriptiranog teksta
   * izlaz: autentifikacijska značka (Auth Tag)   * izlaz: autentifikacijska značka (Auth Tag)
 {{ ::gcm.png?nolink&500 | GCM shema}} {{ ::gcm.png?nolink&500 | GCM shema}}
Line 65: Line 65:
 Generalno se ne preporučuje koristiti način kriptiranja ECB. Inicijalizacijski se vektor ne smije ponavljati i mora biti generiran slučajno, a ne smije se ponavljati ni simetrični ključ. Generalno se ne preporučuje koristiti način kriptiranja ECB. Inicijalizacijski se vektor ne smije ponavljati i mora biti generiran slučajno, a ne smije se ponavljati ni simetrični ključ.
  
-__PRIMJER__ -**Zadatak s Hacknite platforme - Encryption service** +__PRIMJER__ -**Zadatak s Hacknite platforme - AES kriptirana poruka** 
 <file> <file>
-Markov san bio je napraviti program koji će šifrirati nizove znakova. Spajanjem na  +Ivan je na faksu učio o modernim kriptografskim algoritmimaToliko je očaran AES algoritmom da je odlučio 
-chal.platforma.hacknite.hr:10001  +samostalno napraviti program za šifriranje svojih najtajnijih informacijaPokušaj dešifrirati ciphertext 
-možeš isprobati njegov program. Dan ti je kod njegovog programa te šifrirani tekstMožeš li  +kako bi provjerio je li Ivanov program zaista siguran.
-pogoditi što je to Marko zapravo napisao?+
  
-Tekst za šifriranje je:  +ciphertext (u zasebnoj datoteci)
-f44e2a4b2efd98c8b3d1b97c6da4649749ebb799d3c4a7c24bdfe3b36e0a35c6da15b0479f9912c0+991262a3123d702aaa296e36e4054dcb0031479d8affcae34dd12757b19868eee63f79e83e9687e10fc74dbd3c1a61bfdb4ec98a75 
 +38f2c75eed1402d3edfd8dc28531c6d75a3786750afa0f48524d9adb4ec98a7538f2c75eed1402d3edfd8ddb4ec98a7538f2c75eed 
 +1402d3edfd8d64019b35eac50ab04f0239080a879f000b42253688df27967c492e721c9e91407edcf9ebd01fd7a17bc0219784322b 
 +5f0b42253688df27967c492e721c9e91402b5bebae08f2851e97e139390d4d6245925a96bbca45277ebecfd06fa54b510edb4ec98a 
 +7538f2c75eed1402d3edfd8d7edcf9ebd01fd7a17bc0219784322b5f3454fe7467cd0e2b6036f48a3c2246930b42253688df27967c 
 +492e721c9e91403856820345c0e11691b05d22b6005906668020a4b98905a562e051955ea720177edcf9ebd01fd7a17bc021978432 
 +2b5fec0e366b9ea7d725dc81fdec29b57bb3 
 + 
 +Napomena: u ciphertextu nema znakova novog reda, ali su ovdje dodani radi lakše čitljivosti. 
 + 
 +telnet chal.platforma.hacknite.hr 8083 
 +netcat chal.platforma.hacknite.hr 8083 
 + 
 +Flag je u formatu CTF2022[brojevi]
  
-Flag je u formatu CTF2021[brojevi] 
 </file> </file>
  
-U prilogu se još nalazi i program koji se smije koristiti za dešifriranje.\\ +U prilogu se nalazi i datoteka encrypt.py. 
-Možemo pokušati XOR-ati cijeli tekst za šifriranje s null-byteovima tako dobiti prvih 40 bajtova ključ(jer je to duljina teksta za šifriranje)Python programu bismo to postigli sljedećom naredbom u terminalu:  + 
-<code> +Pokušajmo se spojiti na chal.platforma.hacknite.hr i port 8083. Imamo mogućnost pisanja, a kao rezultat dobijemo ispis kodiranog teksta koji smo unijeli. U encrypt.py datoteci. vidimo da se koristi AES ECB mod (linija 19: cipher = AES.new(key, **AES.MODE_ECB**)) te da se svaki znak jasnog teksta tretira kao zasebni blok. U ECB načinu rada se svaki isti blok jasnog teksta uvijek šifrira u isti ciphertextUvjerimo se da je zaista tako. Upišimo jedno slovo, a zatim ponovimo to isto slovo tri puta:  
-python3 -c "print('\x00'*40)" | nc 172.17.0.2 4444+ 
 +{{ :nc-a.jpg?600 |}} 
 + 
 +Vidimo da se svaka pojava istog znaka šifrira jednako, što odgovara AES ECB modu. Sad upišimo dio flaga koji znamo, zatim i cijeli ciphertext da vidimo gdje u njemu počinje flag: 
 + 
 +{{ :nc-ctf2022.png?600 |}} 
 + 
 +Vidimo da počne odmah na početku. Sad nam preostaje dešifrirati ostatak teksta da bismo dobili flagNapišimo jednostavnu Python skriptu za to: 
 + 
 + <code python
 +data = "CTF2022[" 
 +import subprocess 
 +def get_enc(i)
 +    return str(subprocess.check_output(f"echo \"{i}\" | nc chal.platforma.hacknite.hr 8083", 
 +     shell=True))[2:-3] 
 + 
 +cipher = open("ciphertext", "r").read() 
 + 
 +while data[-1] != "]": 
 +    #print(data) 
 +    for x in "123456789[]": 
 +        #print(data + x) 
 +        r = get_enc(data + x) 
 +        if cipher.startswith(r): 
 +            data += x 
 +            break 
 +print(data)
 </code> </code>
-Nakon što smo dobili ključ, XOR-amo ga s tekstom za šifriranje. XOR-anje se može raditi koristeći neki online alat ili tako što stvorimo binarne datoteke ključa i teksta za šifriranje pa pokrenemo skriptu koju smo dobili + 
 +Objasnimo što skripta radi. Kao podatak (//data//) uzeli smo dio zastavice koji nam je poznat. Nakon toga, dok ne dođemo do kraja flaga (znak "]"), uključujući i njega//brute force// pogađamo koji je idući znak u skupu svih mogućih znakova koji se mogu pojaviti u flagu (brojevi i uglate zagrade). Svaki taj mogući znak kodiramo (funkcija //get_enc//) i, ako se kod poklapa s onime što slijedi u tekstu, znači da je taj znak idući i dodajemo ga na konačni flag. Funkcija get_enc jednostavno se spaja netcatom na stranicu zadanu u zadatku i ispisuje rezultat koji se dobije kodiranjem trenutnog znaka. Važno je napomenuti da uzima samo od indeksa 2 početka do trećeg znaka od kraja jer python dodaje stringovima //b'// na početak stringa i //'\n// na kraj pa da se i ti znakovi ne kodiraju. \\ 
 +Zakomentirani printovi služe za bolje razumijevanje skripte. Poželjno je dodati //sleep()// između svake iteracije petlje kako se poslužitelj ne bi preopteretio prevelikim brojem zahtjeva. 
 + 
 +__PRIMJER__ -**Zadatak s Hacknite platforme - Brojač** 
 + 
 +<file> 
 +Mnogi od vas već znaju da je AES ECB način rada nesiguran.  
 +Zato smo odlučili šifrirati tajnu poruku koristeći AES CTR način rada.  
 +Dostupan ti je ciphertext, djelomični plaintext te program koji se koristio za šifriranje poruke,  
 +ali ne i tajni AES ključ. 
 + 
 +Možeš li dešifrirati poruku? 
 +</file> 
 + 
 +Ideja zadatka jest pronaći ranjivost u AES implementaciji s CTR načinom rada. 
 +CTR način rada jest definiran sljedećom formulom za enkripciju: 
 + C = P ⊕ AES(key,CTR) 
 +gdje je C ciphertext, P plaintext, a CTR kombinacija nonce vrijednosti (neka nasumična vrijednost) i brojača (u našoj implementaciji su kombinirani pomoću XOR operacije). Funkcija AES ovdje ne šifrira sam plaintext, nego CTR vrijednost koja se zatim XOR-a s plaintextom. Rezultat funkcije AES(key,CTR) zovemo **keystream**. 
 + 
 + Ne šifrira se cijeli plaintext odjednom već se radi u blokovima od 16 bajtova. Prvi ciphertext 
 +blok jest veličine 16 te je nastao xoranjem keystreama (za prvu iteraciju) s prvim blokom (također 16 bajtova) plaintexta, drugi ciphertext xoranjem keystreama 
 +(za drugu iteraciju) s drugim blokom plaintexta itd... 
 +U odnosu na CBC način rada, gdje se svaki novi blok xora s prijašnjim, CTR-om nastali blokovi nisu međusobno ovisni. 
 + 
 +AES je funkcija koja prima dva parametra, key i CTR. CTR jest kombinacija noncea i countera. Nonce jest fiksna vrijednost koja se nikada ne mijenja tijekom enkripcije 
 +i dekripcije svih blokova, a counter jest vrijednost koja se inkrementira sa svakom novom iteracijom (krećući od 0 u implementaciji). Key jest tajna koja se koristi za enkripciju i  
 +dekripciju te se također nikada ne mijenja. AES je funkcija koja interno ne koristi randomizirane vrijednost jer dekripcija ne bi bila moguća. 
 +Proces dekripcije je opisan sljedećom formulom (suprotan proces od enkripcije): 
 + P = C ⊕ AES(key,CTR) 
 + 
 +Dakle, kako bi dekripcija bila moguća, za isti broj iteracije enkripcije i dekripcije koristi se isti keystream. 
 + 
 +U ZIP datoteci priloženoj uz zadatak dan je algoritam za enkripciju, cijeli ciphertext te parcijalni plaintext. Proučavanjem ciphertext datoteke vidimo da se ciphertext sastoji od 4160 bajtova (260 blokova), a u plaintext datoteci se nalazi 4138 bajtova. Budući da se jedan blok sastoji od 16 bajtova, možemo zaključiti da 
 +imamo cijeli plaintext do 257. bloka (bitno je zapamtiti da brojimo od nule!) , pola 258. bloka, a uopćnemamo 259. blok. 
 + 
 +Dakle, moramo pronaći način da dešifriramo 258. i 259. blok ciphertexta. 
 + 
 +Kod za enkripciju unutar encrypt.c jest sljedeći: 
 + 
 +<file> 
 + AES_EncryptInit(&ctx, key);  
 +      
 +      
 +     unsigned char counter = 0; 
 + 
 +     for (unsigned int offset = 0; offset < (4160); offset += AES_BLOCK_SIZE) { //CTR mode 
 + unsigned char nonce_xor_counter[AES_BLOCK_SIZE]; 
 + unsigned char enc_output[AES_BLOCK_SIZE]; 
 + for(int i=0;i<16;i++){ 
 +     nonce_xor_counter[i] = nonce[i] ^ counter; 
 + 
 +
 + counter +=1; 
 + AES_Encrypt(&ctx, nonce_xor_counter, enc_output); 
 + 
 + for(int i=offset;i<(offset+AES_BLOCK_SIZE);i++){  
 +     ciphertext[i] = enc_output[i%16]^plaintext[i]; 
 + 
 +
 +     } 
 + 
 +     output("\nEncrypted: 0x", ciphertext, (4160)); 
 + 
 +</file> 
 + 
 +Ranjivost implementacije je u tome da se za varijablu brojača (//counter//) koristi tip podatka char . Char jest veličine bajt, odnosno prima vrijednosti 0-255.  
 + 
 +Zbog toga, nakon vrijednosti 255 inkrementiranjem nastaje [[integer|integer overflow]] te se vrijednost resetira na 0. To značda je counter za iteraciju 258/259 zapravo 2/3 što onda znači da je keystream za navedene parove iteracija isti. 
 + 
 +Budući da imamo ciphertext i parcijalni plain text, moguće je doći do keystreama po formuli: 
 + C ⊕ P = AES(key,CTR) 
 + 
 +U nastavku se prikazuje postupak kojim se dolazi do rješenja, bitno je zapamtiti da brojač počinje od nule! 
 + 
 + plaintext[2] ⊕ ciphertext[2] = keystream [2] 
 + keystream[258] = keystream[2] // zbog integer overflowa, keystream kojim se šifrirao 258. blok jednak je onom kojim se šifrirao 2. blok 
 + plaintext[258] = keystream[258] ⊕ ciphertext[258] // ovako dobivamo plaintext 258. bloka 
 + 
 + // zatim ponovimo postupak za 259. blok 
 + 
 + plaintext[3] ⊕ ciphertext[3] = keystream [3] 
 + keystream[259] = keystream[3] // zbog integer overflowa, keystream kojim se šifrirao 259. blok jednak je onom kojim se šifrirao 3. blok 
 + plaintext[259] = keystream[259] ⊕ ciphertext[259] // ovako dobivamo plaintext 259bloka 
 + 
 + 
 + 
 + 
 + 
 + 
  
  
aes.1700475047.txt.gz · Last modified: 2025/12/01 11:40 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki