rev2_bp_counter
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| rev2_bp_counter [2025/10/30 16:15] – created mbunic | rev2_bp_counter [2025/12/01 11:40] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Breakpoint counter | + | ==== Zadatak s Hacknite platforme - rev2 - rješenje |
| - | Pošto ovaj programski kod ima "early exit", odnosno kad detektira da je neka znamenka korisničkog unosa kriva, odmah ispisuje "Wrong password!" | ||
| - | Ovim načinom se može napraviti " | + | |
| + | Prije nego što pročitate ovaj članak, preporučuje se pregled writeupa rješenja istog zadatka pomoću alata Ghidra. | ||
| + | |||
| + | [[rev2_ghidra|CTF writeup - rev2-Ghidra]] | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | Programski kod u ovom programu ima "early exit", odnosno kad detektira da je neka znamenka korisničkog unosa kriva, odmah ispisuje "Wrong password!" | ||
| + | |||
| + | Ovim načinom se može napraviti " | ||
| < | < | ||
| Line 9: | Line 18: | ||
| </ | </ | ||
| - | No pošto | + | Budući da je poznato da je unos duljine 21, te da je u formatu:: |
| < | < | ||
| - | CTF2025[< | + | CTF2025[< |
| </ | </ | ||
| Line 21: | Line 30: | ||
| </ | </ | ||
| - | Što je lagano | + | Što je lako rješivo. |
| U slučaju da program nema raniji završetak izvršavanja programa pri pronalasku prvog neispravnog znaka, ovaj način rješavanja ne bi bio moguć. Umjesto " | U slučaju da program nema raniji završetak izvršavanja programa pri pronalasku prvog neispravnog znaka, ovaj način rješavanja ne bi bio moguć. Umjesto " | ||
| Line 29: | Line 38: | ||
| </ | </ | ||
| - | što nije izvedivo. | + | što praktično |
| Pseudokod ovog rješenja je postavljanje breakpointa na određeni dio do while petlje te isprobavanje svih mogućih unosa za prvi nepoznati znak. Onaj znak koji je uzrokovao izvršavanje više koda (što će se dogoditi samo u slučaju kada je ispravan znak), odnosno znak za koji se u izvršavanju više puta prošlo breakpointom na ulasku u petlju, je ispravan znak za tu poziciju unosa. | Pseudokod ovog rješenja je postavljanje breakpointa na određeni dio do while petlje te isprobavanje svih mogućih unosa za prvi nepoznati znak. Onaj znak koji je uzrokovao izvršavanje više koda (što će se dogoditi samo u slučaju kada je ispravan znak), odnosno znak za koji se u izvršavanju više puta prošlo breakpointom na ulasku u petlju, je ispravan znak za tu poziciju unosa. | ||
| - | Za rješenje koje broji prolaske breakpointova koristi se libdebug | + | Za rješenje koje broji prolaske breakpointova koristi se biblioteka |
| < | < | ||
| Line 44: | Line 53: | ||
| Zadnja naredba pokreće skriptu. | Zadnja naredba pokreće skriptu. | ||
| - | Skripta je prikazana | + | Skripta je prikazana |
| - | {{: | ||
| - | Važno je da skripta u svakom pokušaju pošalje unos duljine 21, kako bi uvijek bio zadovoljen uvjet da je korisnički unos duljine 21, te nakon toga na opisani način redoslijedom pronalazi jedan po jedan znak korisničkog unosa, koji jednom više prođe postavljenim breakpointom nego drugi znakovi na toj poziciji. | ||
| - | Također je važan redoslijed, da prolazi znakove | + | < |
| + | from libdebug import debugger | ||
| + | import string | ||
| + | |||
| + | d = debugger(" | ||
| + | |||
| + | flag_length = 21 | ||
| + | flag = ['#' | ||
| + | print() | ||
| + | |||
| + | def count_loops(passphrase): | ||
| + | io = d.run() | ||
| + | my_callback_breakpoint = d.breakpoint(0x401900, | ||
| + | d.cont() | ||
| + | io.sendline(passphrase.encode()) | ||
| + | d.wait() | ||
| + | return my_callback_breakpoint.hit_count | ||
| + | |||
| + | |||
| + | for i in range(flag_length): | ||
| + | best_char = "#" | ||
| + | best_instructions = -1 | ||
| + | |||
| + | for c in string.digits + string.ascii_letters + string.punctuation: | ||
| + | test_flag = "" | ||
| + | instructions = count_loops(test_flag) | ||
| + | |||
| + | if instructions > best_instructions: | ||
| + | print(f" | ||
| + | best_instructions = instructions | ||
| + | best_char = c | ||
| + | |||
| + | flag[i] = best_char | ||
| + | |||
| + | print(f" | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | Važno je da skripta u svakom pokušaju pošalje unos duljine 21, kako bi uvijek bio zadovoljen uvjet da je korisnički unos duljine 21, te nakon toga na opisani način redoslijedom pronalazi jedan po jedan znak korisničkog unosa. Onaj znak za koji program jedan put više prođe postavljenim breakpointom nego za druge znakove na toj poziciji je ispravan znak. | ||
| + | |||
| + | Također je važan redoslijed da se pronalaze znakovi unosa redom od najmanjeg do najvećeg indeksa (prvo znak odmah nakon " | ||
| Adresa breakpointa je postavljena kao: | Adresa breakpointa je postavljena kao: | ||
| Line 60: | Line 108: | ||
| Adresa instrukcije na kojoj je postavljen breakpoint koji se broji pri izvršavanju je prikazana slikom ispod: | Adresa instrukcije na kojoj je postavljen breakpoint koji se broji pri izvršavanju je prikazana slikom ispod: | ||
| - | {{: | + | {{rev2_bp_counter: |
| - | Ovaj kod će se izvršiti samo ako je znamenka na toj poziciji odnosno u toj iteraciji petlje bila ispravna, pa se nije dogodio jump na ispis "Wrong password!" | + | Ovaj kod će se izvršiti samo ako je znamenka na toj poziciji, odnosno u toj iteraciji petlje bila ispravna, pa se nije dogodio jump na ispis "Wrong password!" |
| - | {{: | ||
| Pokretanjem ove skripte dobiva se rješenje zadatka. | Pokretanjem ove skripte dobiva se rješenje zadatka. | ||
| + | |||
| + | |||
| + | {{rev2_bp_counter: | ||
| + | |||
| + | |||
rev2_bp_counter.1761840951.txt.gz · Last modified: 2025/12/01 11:40 (external edit)