Lohikäärme ghidra, C ja koko tarina
Tässä raportissa tutustumme ghidraan työkaluna, käänteismallinnamme ohjelmia ja selvitämme käännettyjen binäärien toimintatapaa.
Kalilla ghidran asennus kävi helposti
sudo apt-get install ghidra

Ensimmäisenä kuitenkin Lyhyesti Ghidra - John Hammondin youtubesta.
Ensin tutkii file, strings, strace, objdump ja ltrace komennoilla löytämättä mitään. Ghidralla hän löytää hexaluvun 0x86187 joka kääntyy ’549255’
packd ja passtr
Viime viikolla tutustuimme ja obfuskoimme packd/passwd ohjelmia. Koitetaan nyt kääntää näitä ghidralla.

Importtasin ja käänsin packd ohjelman sellaisenaan ja hämmennyin, koska en nähnyt selkeästi main ohjelmaa, tai mitään sen tapaista. Vaikka tiedänkin jo binäärin viime viikosta, en saanut sitä mitenkään luettavaan muotoon.
Sitten muistin tunnilta, toinen oppilas oli käyttänyt upxää ensin binäärin purkuun. Eli
upx -d packd
Tässä käytetään -d / decrompress muotoa joka purkaa ohjelman luettavaan muotoon. Paljon kätevämpi tapa kuin viime viikon RAM etsintä. Tallenna _purettu nimellä.

Sitten vaan ghidralla import->lohikäärme.
Main löytyi heti ja ajettava ohjelma.

Käyn koodin toimintalogiikan mistralini kanssa läpi. Teenpä siis muutoksia muuttujiin seuraavasti. Tämän jälkeen selitetty toimintalogiikka.
local_28 → sanasala: salasana muuttuja käyttäjälle iVar1 → tarkistus: pöydän tulos
Yritin myös etsiä ...201d muotoilua koodista, mutta tähän hätään en löytänyt sitä. Ymmärrän, että tämänkin pitäisi(?) löytyä tuolta merkkijonona. Olisi varmaan ihan kätevä debuggaukseen tietää esim. monta muotoa pitkä tuo olisi.
Korjattu logiikka kuitenkin seuraavasti.

Ohjelman toiminta vaiheittain:
Syötteen pyyntö: Ohjelma tulostaa käyttäjälle kehotteen, jossa pyydetään salasanaa.
Syötteen lukeminen: Käyttäjän syöte luetaan __isoc99_scanf-funktiolla. Funktio käyttää muistiosoitteessa DAT_0010201d sijaitsevaa muotoilumäärettä ja tallentaa syötetyn merkkijonon password-muuttujaan.
Salasanan vertailu: strcmp-funktio vertaa password-muuttujan arvoa ohjelmaan kovakoodattuun merkkijonoon piilos-AnAnAs. Vertailun tulos tallennetaan checker-muuttujaan. Ehdollinen tulostus: Ohjelma tarkistaa if-else-rakenteella checker-muuttujan arvon.
Jos arvo on 0 (salasanat täsmäävät), käyttäjälle tulostetaan onnitteluviesti ja lippu.
Jos arvo ei ole 0, käyttäjälle tulostetaan "Sorry, no bonus.".
Passtr ohitus
Seuraavaksi sama passtr binäärille. Toimintalogiikka on sama.

Tehtävänä on ratkaista tämä ohittamalla ohjelman toimintalogiikka meidän omalla. Eli lähdetään etsimällä string: ’password’ muistista (pikanäppäin s).

Avaan myös kohdan windows - function graph niin näen tapahtumataulun.

Taulun viimeinen tapahtuma on JNZ hyppy jossa hypätään ilman nollaa kohtaan jossa salasana on oikein.
Eli vaihdetaa Jump non zero = jump zero. Jolloin toimintalogiikka olisi päinvastainen. Ainoastaan oikea salasana ei toimisi.
Patch instuctions = JZ

Tämän jälkeen exporttasin, annoin toimintaoikeudet ja testasin toimivuuden.
Toimii

Nora CrackMe
1
Seruraavaksi yritetään selvittää Noran CrackMe tehtäviä.
Gitillä sisään ja lähdetään. Mukana on pelkät C-sorsat joten ykkönen pystyyn komennolla.
gcc crackme01.c -o crackme01
Ohjelma 01 pyytää argumentin, joten lähdetään selvittämään.

Ghidralla auki ja mainista näemme, että ohjelma kysyy salasanaa ”password1”.

Joka toimii.
1e
Oli sama, mutta salasanassa piti käyttää ’!’ pelkän ! tilalta.

2
Auki ghidralla ja toimintaselvitys Mistralilla.

Tässä siis (osin mistralin kautta selvitys) ’if (param_1 == 2) {’ varmistaa, että käyttäjältä tulee TASAN yksi salasana-argumentti. Muuten tulee virhe 0xffffffff.
Salasana vertaillaan ja jos lukumäärä on oikein, ohjelma aloittaa iteroinnin merkkijonon ”password1” läpi ja vertaa jokaista merkkiä käyttäjän antamaan salasanan vastaavaan merkkiin.
Kohdassa
if ("password1"[i] + -1 != (int)*(char *)((long)i + (long *)param_2 + 8)) {
printf("No, %s is not correct.\n", *(undefined8 *)argv + 8);
return 1;
}
vertailun tulos on oltava -1 merkistä, tai ohjelma lopettaa.
Voidaan periaatteessa vaihtaa param_1 ja _2, mutta sillä ei niin väliä. Local_c on selvästi i. Tehdään se.

Eli kyseessä on ASCII merkkijonosta joka täytyy muuttaa suunnassa -1. Jolloin jokainen merkki pitää muuttaa yksitellen. Pyydän Mistrallilta pelkkää merkkijonoa ilman kommentteja.
p 112 111 o
a 97 96 `
s 115 114 r
s 115 114 r
w 119 118 v
o 111 110 n
r 114 113 q
d 100 99 c
1 49 48 0
Eli vastauksessa muistettava erikoismerkin eteen \ = o\’rrvnqc0. Myös ’sisään’ käy.

Ja sehän toimi!
Kommentit
Ghidra on todella hyvä työkalu ja vasta tässä parin viikon jumppaamisellakin ymmärtänyt sen tärkeyttä. Näitä ollut kiva ratkoa.
Lähteet
Teron binäärit https://terokarvinen.com/sovellusten-hakkerointi/
John Hammond - Ghidra https://www.youtube.com/watch?v=oTD_ki86c9I
Dokumentissa käytetty apuna C-koodin ymmärryksessä ja ASCII taulukon tekemisessä LLM mistra-small3.2:24b mallia. Rautana käytössä ollut Macbook pro m2 max 64gb ja kääntäjänä LM-studio. https://huggingface.co/mistralai/Mistral-Small-3.2-24B-Instruct-2506 https://lmstudio.ai
JNZ selvite https://stackoverflow.com/questions/14841169/jnz-cmp-assembly-instructions
Crackmes tehtävät https://github.com/NoraCodes/crackmes
Kuvat optimoitu https://optimage.app
Käytetty aika 3h 20min