User Tools

Site Tools


integer_overflow

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
integer_overflow [2023/11/15 16:45] kresimirinteger_overflow [2025/12/01 11:40] (current) – external edit 127.0.0.1
Line 2: Line 2:
  
 Do integer overflow-a dolazi kada se pokuša pohraniti vrijednost u varijablu koja je veća od maksimalno dopuštene. Do integer overflow-a dolazi kada se pokuša pohraniti vrijednost u varijablu koja je veća od maksimalno dopuštene.
-Sve numeričke vrijednosti tokom izvođenja operacija u kojima su oni operandi sačuvane su u registrima.+Sve numeričke vrijednosti tijekom izvođenja operacija u kojima su oni operandi sačuvane su u registrima.
 U današnje vrijeme to su najčešće 64 bitni registri. U današnje vrijeme to su najčešće 64 bitni registri.
  
Line 19: Line 19:
  
   *U unsigned notaciji: [0, 255]   *U unsigned notaciji: [0, 255]
-  *U signed notaciji : [-128, 127]+  *U signed notaciji: [-128, 127]
  
 Najveća vrijednost koju ona može sadržati u sebi jest broj 1111 1111(2) Najveća vrijednost koju ona može sadržati u sebi jest broj 1111 1111(2)
-S obzirom da su svi numerički operandi nalaze u registru (npr. 64 bitnom) zapis vrijednosti varijable a (recimo broj 255) +S obzirom na to da su svi numerički operandi nalaze u registru (npr. 64 bitnom) zapis vrijednosti varijable a (recimo broj 255) 
-u registru koji sadržu njenu vrijednost biti će : 00000...1111 1111(2) gdje je broj nula 64-8 = 56.+u registru koji sadržu njenu vrijednost bit će : 00000...1111 1111(2) gdje je broj nula 64-8 = 56.
  
 Kada bismo tom registru dodali vrijednost 1, zapis bi izgledao ovako: 0000....1 0000 0000(2), što bi značilo da se vrijednost Kada bismo tom registru dodali vrijednost 1, zapis bi izgledao ovako: 0000....1 0000 0000(2), što bi značilo da se vrijednost
Line 32: Line 32:
 Sklopovlje za zbrajanje registara interno koristi tzv. carry flag (rflags/eflags/status registra) Sklopovlje za zbrajanje registara interno koristi tzv. carry flag (rflags/eflags/status registra)
 To znači da kada se registar preplavi (odnosno upiše vrijednost veća od 2^64) on ispravlja svoj sadržaj To znači da kada se registar preplavi (odnosno upiše vrijednost veća od 2^64) on ispravlja svoj sadržaj
-(odnosno prikazuje upisanu vrijednost % 2^64 gdje je % operacija modulo-ostatak) i postavlja postavlja carry flag.+(odnosno prikazuje upisanu vrijednost % 2^64 gdje je % operacija modulo-ostatak) i postavlja carry flag.
 Kada bi se taj registar dalje koristio za operacije bile bi prikazane vrijednost manje od 2^64. Kada bi se taj registar dalje koristio za operacije bile bi prikazane vrijednost manje od 2^64.
 +
 +====Tajni chat====
 +
 +===Opis zadatka:===
 +
 +[[https://platforma.hacknite.hr/challenges#Tajni%20chat-42]]
 +
 +Ivan je skeniranjem interneta naišao na ovaj tajni chat. Zaista mu se želi pridružiti, no ne može se registrirati. Možeš li mu pomoći?
 +
 +Spoji se na program uz pomoć naredbe telnet (ako koristiš Windows) ili naredbe netcat (ako koristiš Linux):
 +
 +    telnet chal.platforma.hacknite.hr 8084
 +    
 +    netcat chal.platforma.hacknite.hr 8084
 +
 +===Rješenje:===
 +
 +Zastavica će se ispisati ako vrijedi uvjet (status->odobren && status->moze_citati_flag).
 +Potrebno je preplaviti status i postaviti ga na ispravne vrijednosti.
 +Jedini unos je preko scanf-a:
 + scanf("%10s",popis_pozivatelja[i].ime);
 + scanf("%10s",popis_pozivatelja[i].kontakt);
 +Objekt status nalazi se iza popis_pozivatelja.
 +Unos scanf-a ograničen je iteracijom po broju pozivatelja:
 + for(long long i=0; i<broj_pozivatelja; i++)
 + ...
 +
 +Također postavljan je uvjet na donju granicu broja pozivatelja:
 + if(broj_pozivatelja > 0) //Dakle broj pozivatelja ne smije biti negativan
 +Potrebno je napraviti overflow tako da iteracija omogućuje veći ispis po gomili od veličine popis_pozivatelja:
 + long long broj_pozivatelja; //qword (8 bajtova/64 bita)
 +
 +2^64 = 18,446,744,073,709,551,616 različitih vrijednosti:
 +  *U unsigned notaciji: [0, 18 446 744 073 709 551 615]
 +  *U signed notaciji : [-9 223 372 036 854 775 808, 9 223 372 036 854 775 807]
 +
 +Veličina popis_pozivatelja je određena s:
 + broj_pozivatelja * sizeof(struct pozivatelj)
 +Sizeof je operacija koja vraća tip size_t (unsigned int) i u ovom slučaju to će biti vrijednost 20 (10 char + 10 char gdje je char riječ definirana kao byte)
 +Broj_pozivatelja je long long 
 +Rezultat množenja je tip long long (implicit casting - uvijek se upcasta na najkompleksniji operand u operaciji npr. float*long *int *short = float).
 +
 +Kako bi se izveo overflow na razini registra koji čuva vrijednost umnoška potrebno je unijeti vrijednost za broj_pozivatelja na načina da je
 +rezultat veći od 2^64 jer: 
 +
 +Broj_pozivatelja*sizeof(struct pozivatelj) = (broj_pozivatelja*sizeof (struct pozivatelj) ) % 2^64 = (broj_pozivatelja*20)%2^64
 +
 +2^64 / 20 =  922337203685477581 kada se zaokruži na gornju granicu.
 +Time je ostatak 4 unutar malloc-a.
 +Naravno, moguće je izvesti overflow i s drukčijim brojevima.
 +-----
 +Rješenje je dakle:
 +  -Unos_1: 922337203685477581
 +  -Unos_2: Unos stringa do adrese status i preplavljivanje varijable moze_citati_flag
 +
 +{{tajnichat.png}}
 +
integer_overflow.1700066734.txt.gz · Last modified: 2025/12/01 11:40 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki