Säieet ohjelmistoon.
Tässä raportissa tutustumme binäärien sisältöön, strings komennon kautta. Lisäksi tutustumme binääriin rammissa ja c-kieleen.
ezbin-challenges
Opettajan binäärit saamme ladattua hänen sivulta. Suora linkki on tässä, mutta ikuista varmuutta zip tiedostoon ei ole. Varoituksen sana.
Ensimmäisenä tutustumme ’strings’ haasteeseen. Lataus wgetillä, unzip ja kansion sisään.
Saamme binäärin ’passtr’. Ajan file komennolla.
file passtr
passtr: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=ceddb0a2caba0d00947ffcb1883ad738aa8b9f07, for GNU/Linux 3.2.0, not stripped
Tässä näemme, että binääri on ”not stripped”, eli sen voi ajaa debuggerilla tai disasseblerissa. Nyt tässä ei kuitenkaan sille tarvetta.
Etsimme salasanaa ohjelmassa joten yksinkertaisesti ajan
strings passtr | grep pass
Tämä tuo ensimmäisenä FLAG arvon eteen ja ”What’s the password?”. Otetaan rivit mukaan molemmilta puolilta.
strings passtr | grep -A 1 -B 1 pass

Tästä löytyy sala-hakkeri-321
Kokeillaan vielä ajaa.

Korjataan C-binääri
C-on itselleni suht vieras kieli, mutta olen tässä disobeyn tehtäviin juuri opetellut XOR-obfuskoinnista. Eli sotkemme salasanan bitin-vakio luvulla (obfuskointi). Näin strings ei ymmärrä koodia, eikä näytä sitä.
Alkuperäinen koodi
#include <stdio.h>
#include <string.h>
int main() {
char password[20];
printf("What's the password?\n");
scanf("%19s", password);
if (0 == strcmp(password, "sala-hakkeri-321")) {
printf("Yes! That's the password. FLAG{Tero-d75ee66af0a68663f15539ec0f46e3b1}\n");
} else {
printf("Sorry, no bonus.\n");
}
return 0;
}
Lisäämme vakion (define) avain joka vaikka arvolla 0x42 (66) joka ajetaan ennen kuin koodi käännetään c:ssä. Luodaan myös salasanan jokaiselle merkille avaimen (0x42) vakio mukaan. Jolloin salasana kokonaisuudessaan obfuskoidaan.
Arvot piilo_sanasala ja piilo_libbu obfuskoi arvot ja oikea_sanasala/oikea_libbu palauttavat taulukot oikeaan arvoon.
Tämän käännös kääntää salasanan takaisin ennen lukua.
Muutin myös koodin termistön omaan lukuun helpommaksi ’duh’.
Käytin xor-arvoissa ja koodin pohjassa apuna mistral-small3.2 LLM apuna. Koodissa oli paljon vikaa joten korjasin pohjakoodia todella paljon. Epäilin, että myös xor avaimessa olisi, mutta siitä kohta lisää /retrospect/.
#include <stdio.h>
#include <string.h>
int main() {
char password[20];
unsigned char piilo_sanasala[] = {
0x31, 0x21, 0x2e, 0x21, 0x6b, 0x2a, 0x21, 0x2d, 0x2d, 0x27,
0x30, 0x2b, 0x6b, 0x71, 0x70, 0x73
};
unsigned char piilo_libbu[] = {
0x04, 0x0e, 0x03, 0x05, 0x39, 0x16, 0x27, 0x30, 0x2d, 0x6f,
0x26, 0x75, 0x77, 0x27, 0x27, 0x74, 0x74, 0x23, 0x24, 0x72,
0x23, 0x74, 0x7a, 0x74, 0x74, 0x71, 0x24, 0x73, 0x77, 0x77,
0x71, 0x7b, 0x27, 0x21, 0x72, 0x24, 0x76, 0x74, 0x27, 0x71,
0x20, 0x73, 0x3f
};
unsigned char avain = 0x42;
printf("What's the password?\n");
scanf("%19s", password);
size_t sanasala_pituus = sizeof(piilo_sanasala);
char salis[64];
for (int i = 0; i < sanasala_pituus; i++) {
salis[i] = piilo_sanasala[i] ^ avain;
}
salis[sanasala_pituus] = '\0';
if (0 == strcmp(password, salis)) {
printf("Yes! That's the password. ");
size_t libbu_pituus = sizeof(piilo_libbu);
char lippu[64];
for (int i = 0; i < libbu_pituus; i++) {
lippu[i] = piilo_libbu[i] ^ avain;
}
lippu[libbu_pituus] = '\0';
printf("%s\n", lippu);
} else {
printf("Sorry, no bonus.\n");
}
return 0;
}
Tämän jälkeen ajan uuden koodin c-compilerin läpi ja tarkastan, että se toimii.
gcc -o passtr.obf passtr.obf.c
/.passtr.obf

Thoimii! Paitsi ei toimi. Ohjelma ei toimi enää toiseen suuntaan. Epäilen, että mistrall on tehnyt XOR taulukossa virheen, mutta sen sijaan, että tarkastan taulukon - teen pienen debuggerin.
Tunnen koodin niin helppo on ajaa oma taulukko uudestaan, verrata purettuun salasanaan ja oikeaan salasanaan.
#include <stdio.h>
#include <string.h>
int main() {
unsigned char piilo_sanasala[] = {
0x31, 0x21, 0x2e, 0x21, 0x6b, 0x2a, 0x21, 0x2d, 0x2d, 0x27,
0x30, 0x2b, 0x6b, 0x71, 0x70, 0x73
};
unsigned char avain = 0x42;
printf("Purettu salasana: '");
for (int i = 0; i < sizeof(piilo_sanasala); i++) {
char merkki = piilo_sanasala[i] ^ avain;
printf("%c", merkki);
}
printf("'\n");
char oikea[] = "sala-hakkeri-321";
printf("Oikea salasana: '%s'\n", oikea);
printf("Oikeat XOR-arvot: ");
for (int i = 0; i < strlen(oikea); i++) {
printf("0x%02x, ", (unsigned char)(oikea[i] ^ avain));
}
printf("\n");
return 0;
}
Laitan mukaan myös oikeat XOR arvot printtamaan. Tämä hyvä huijaus-pöytä jos jatkossa ongelmia näiden kanssa. Nimittäin tässä näitä tullut ja huomaan jatkuvasti etsiväni omista muistiinpanoista ohjauksia 😂
./debugPurettu salasana: 'sclc)hcooeri)321'Oikea salasana: 'sala-hakkeri-321'Oikeat XOR-arvot: 0x31, 0x23, 0x2e, 0x23, 0x6f, 0x2a, 0x23, 0x29, 0x29, 0x27, 0x30, 0x2b, 0x6f, 0x71, 0x70, 0x73,

Sieltähän tuo löytyi. Korjataan koodiin suoraan tuosta. Vastaavan olisin voinut tehdä FLAG arvolle, mutta se jostain syystä oikein.
Live love laugh.
unsigned char piilo_sanasala[] = {
0x31, 0x23, 0x2e, 0x23, 0x6f, 0x2a, 0x23, 0x29, 0x29, 0x27,
0x30, 0x2b, 0x6f, 0x71, 0x70, 0x73
};
Thoimii!

Packd ja haetaan rammista.
Olen tässä tutustunut edellisen viikon aikana hex koodiin rammista (disobey tehtävä) ja samalla on tullut vastaan uusia työkaluja. Näistä apua tässä.
Katsotaan Teron seuraavaa binääriä.
> file packd
packd: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), statically linked, no section header
> strings packd | grep -A 1 -B 1 pass
u+UH
What's the password?
piilos-An
Tässä huomataan, että salasana on piilossa. Äkkiseltään piilos-An tai ’What’s the password?’ arvojen lähelle.
Me siis voidaan ajaa prosessi rammista suoraan kätevällä python lisäkirjastolla pwndbg. Asennusohjeet tässä. Eli me voidaan etsiä merkkijonoja itse prosessista suoraan RAM-muistista. Huikean kätevää.
Ajan prosessin tmuxilla käyntiin pohjalle, erotan ikkunan ja etsin prosessin PID numeron jonka voin lähettää eteenpäin.
ps -aux | grep packd
henry 12713 0.0 0.0 2564 1280 pts/2 S+ 01:43 0:00 ./packd
pwndbg -p 12713
Tässä voimme etsiä pwndbgllä arvojen läheltä missä kohtaa tuo ’What's the password?’ on.
Saamme vastaukseksi kohdan anon_7f86c10bb. Joka voidaan hexdumpata pwndbgn sisällä.
pwndbg> search -t string "What's the password?"
Searching for string: b"What's the password?\x00"
[anon_7f86c10bb] 0x7f86c10bb008 "What's the password?"
packd 0x7f86c10bf560 "What's the password?"
pwndbg> hexdump anon_7f86c10bb
+0000 0x7f86c10bb000 01 00 02 00 00 00 00 00 57 68 61 74 27 73 20 74 │........│What's.t│
+0010 0x7f86c10bb010 68 65 20 70 61 73 73 77 6f 72 64 3f 00 25 31 39 │he.passw│ord?.%19│
+0020 0x7f86c10bb020 73 00 70 69 69 6c 6f 73 2d 41 6e 41 6e 41 73 00 │s.piilos│-AnAnAs.│
+0030 0x7f86c10bb030 59 65 73 21 20 54 68 61 74 27 73 20 74 68 65 20 │Yes!.Tha│t's.the.│
Ja tämä tuo arvon ’piilos-AnAnAs’
Kokeillaan sitä.

Ratkaistu!
Lähteet
Teron binäärit https://terokarvinen.com/sovellusten-hakkerointi/
Dokumentissa käytetty apuna c-koodissa ja XOR salauksessa ja väärin tehdyn XOR salauksen debuggauksessa (heheh) 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
Pwndbg https://github.com/pwndbg/pwndbg
Kuvat optimoitu https://optimage.app
Käytetty aika 2h 30min