re@REBOP ~ $ nc challenges-box1.pwn.tn 5112
[+] solve 50 of my binaries in less than 50s and i'll give you the flag
;echo -n "stringa" | base64 --decode
[0x00001165]> pdf
179: int main (int argc, char **argv, char **envp);
;var int64_t var_14h @ rbp-0x14
;var int64_t var_15h @ rbp-0x15
;var char *s @ rbp-0x40
;var void *s2 @ rbp-0x70
0x00001165 55 push rbp
0x00001166 4889e5 mov rbp, rsp
0x00001169 53 push rbx
0x0000116a 4883ec68 sub rsp, 0x68
;qui stiamo allocando 104 byte
0x0000116e 488d45c0 lea rax, [s]
0x00001172 4889c6 mov rsi, rax
0x00001175 488d3d880e00. lea rdi, str._32s
;0x2004 ; "%32s" ; const char *format ; stringa di 32 caratteri
0x0000117c b800000000 mov eax, 0
0x00001181 e8dafeffff call sym.imp.scanf
;int scanf(const char *format)
;legge una stringa di 32 caratteri
0x00001186 c745ec000000. mov dword [var_14h], 0
0x0000118d eb30 jmp 0x11bf
0x0000118f 8b45ec mov eax, dword [var_14h]
0x00001192 4898 cdqe
0x00001194 0fb64c05c0 movzx ecx, byte [rbp + rax - 0x40]
;rax è un indice, la stringa di riferimento è quella inserita
0x00001199 8b45ec mov eax, dword [var_14h]
0x0000119c 4898 cdqe
0x0000119e 488d15bb2e00. lea rdx, str.gekzcadtwzhskyhpppavghshitetegbl ;0x4060
;in rdx ci mette l'indirizzo di questa stringa gekzcadtwzhskyhpppavghshitetegbl di 32 caratteri che è ogni volta diversa
0x000011a5 0fb60410 movzx eax, byte [rax + rdx]
;rax qui funge da indice, sta scorrendo i singoli byte di queste stringa
0x000011a9 31c8 xor eax, ecx
;quindi lo xor viene fatto tra l'iesimo byte della stringa segreta e l'iesimo byte della stringa in ingresso
0x000011ab 8845eb mov byte [var_15h], al
;il risultato dello xor va in [var_15]
0x000011ae 8b45ec mov eax, dword [var_14h]
0x000011b1 4898 cdqe
0x000011b3 0fb655eb movzx edx, byte [var_15h]
0x000011b7 88540590 mov byte [rbp + rax - 0x70], dl
;sta costruendo un'altra stringa in [rbp-0x70] byte per byte con rax che funge da indice
0x000011bb 8345ec01 add dword [var_14h], 1
0x000011bf 8b45ec mov eax, dword [var_14h]
0x000011c2 4863d8 movsxd rbx, eax
0x000011c5 488d45c0 lea rax, [s]
0x000011c9 4889c7 mov rdi, rax ; const char *s
0x000011cc e86ffeffff call sym.imp.strlen
;size_t strlen(const char *s)
0x000011d1 4839c3 cmp rbx, rax
0x000011d4 72b9 jb 0x118f
;qui fa una comparazione con la lunghezza della stringa inserita e un contatore per xorare tutti e 32 i caratteri
0x000011d6 488d4590 lea rax, [s2] [rbp-0x70]
0x000011da ba20000000 mov edx, 0x20
;"@" ; size_t n sono 32 bytes
0x000011df 4889c6 mov rsi, rax ; const void *s2
0x000011e2 488d3db72e00. lea rdi, [0x000040a0] ; const void *s1
0x000011e9 e862feffff call sym.imp.memcmp
;int memcmp(const void *s1, const void *s2, size_t n) fa la comparazione tra due regioni di memoria, quella dove si trova la stringa generata dallo xor e una regione di 32 byte randomici
0x000011ee 85c0 test eax, eax
0x000011f0 750e jne 0x1200
0x000011f2 488d3d100e00. lea rdi, [0x00002009] ;"Yes"
0x000011f9 e832feffff call sym.imp.puts ;int puts(const char *s)
0x000011fe eb0c jmp 0x120c
0x00001200 488d3d060e00. lea rdi, [0x0000200d] ;"No"
0x00001207 e824feffff call sym.imp.puts ;int puts(const char *s)
0x0000120c b800000000 mov eax, 0
0x00001211 4883c468 add rsp, 0x68
0x00001215 5b pop rbx
0x00001216 5d pop rbp
0x00001217 c3 ret
;esadecimale del chunk di 32 byte estratti dall'eseguibile
xxd pawn > b1.hex
xxd pawn2 > b2.hex
diff b1.hex b2.hex
00003060: jtepabwfnsawfgsp
00003070: lpvcdfhpirdfddbd
---
00003060: fygmvrllhipffaxh
00003070: bnzpsoivmfylcovs
000030a0: ................
000030b0: ................
---
000030a0: ................
000030b0: ................
0x3060 --> 12384
0x30a0 --> 12448
dd skip=12384 count=32 if=pawn of=pawnstr bs=1
dd skip=12448 count=32 if=pawn of=pawnstr2 bs=1
;confrontando due binari tra loro, si individuano gli offset delle porzioni di 32 byte ciascuna contenenti una chiave di 32 byte e il blocco di 32 byte randomici; con dd riusciamo ad estrarre entrambi i blocchi facilmente e li scriviamo nei file pawnstr e pawnstr2;
;con uno script perl facciamo lo xoring dei due file e poi con strings stampiamo la stringa che invieremo al server;
;basta ora automatizzare il tutto con uno script perl ed inviare le 50 stringhe richieste dal server in meno di 50 secondi e otteniamo la flag del CTF;