sto lavorando su una vulnerabilità di laboratorio format-string, dove si sta per fornire il seguente codice:Accesso secondo elemento di un array in un attacco vulnerabilità format string
#define SECRET1 0x44
#define SECRET2 0x55
int main(int argc, char *argv[])
{
char user_input[100];
int *secret;
int int_input;
int a, b, c, d; /* other variables, not used here.*/
/* The secret value is stored on the heap */
secret = (int *) malloc(2*sizeof(int));
/* getting the secret */
secret[0] = SECRET1;
secret[1] = SECRET2;
printf("The variable secret's address is 0x%.8x (on stack)\n", &secret);
printf("The variable secret's value is 0x%.8x (on heap)\n", secret);
printf("secret[0]'s address is 0x%.8x (on heap)\n", &secret[0]);
printf("secret[1]'s address is 0x%.8x (on heap)\n", &secret[1]);
printf("Please enter a decimal integer\n");
scanf("%d", &int_input); /* getting an input from user */
printf("Please enter a string\n");
scanf("%s", user_input); /* getting a string from user */
/* vulnerable place */
printf(user_input);
printf("\n");
/* Verify whether your attack is successful */
printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2);
printf("The new secrets: 0x%x -- 0x%x\n", secret[0], secret[1]);
return 0;
}
Non dovremmo modificare il codice a tutti. Usando solo l'input, abbiamo 4 obiettivi: arrestare il programma, stampare il valore su secret [1], modificare il valore su secret [1] e modificare il valore su secret [1] su un valore predeterminato.
Esempio di output che ottengo è:
The variable secret's address is 0xbfffe7cc (on stack)
The variable secret's value is -x0804a008 (on heap)
secret[0]'s address is 0x0804a008 (on heap)
secret[1]'s address is 0x0804a00c (on heap)
Please enter a decimal integer
65535
Please enter a string
%08x.%08x.%08x.%08x.%08x.%08x.%08x%08x.
bfffe7d0.00000000.00000000.00000000.00000000.0000ffff.0804a008.78383025
Quindi, inserendo 8 "% 08x" s, stampo l'indirizzo del segreto + 4, poi a stampare gli indirizzi di interi a, b, c, e d - ma dato che non ho mai dato loro un valore, non puntano da nessuna parte e mostrano solo gli 0. Di seguito è riportato il decimale che immetto, scelto in modo che il 'ffff' sia chiaramente visibile. Segue l'indirizzo di segreto [0], quindi arrivo ad altri valori memorizzati nel programma.
Se dovessi immettere AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x%08x.
, dopo il .0804a008 sarebbe .41414141, perché gli A della stringa di input sarebbero memorizzati lì.
È abbastanza facile arrestare il programma: abbastanza% s sull'input della stringa provoca un segfault. Ora ho bisogno di leggere il valore in segreto [1], però, e sono totalmente perso. Ho provato a provare a mettere l'indirizzo nello stack in qualche modo, mettendolo all'inizio della stringa in questo modo: \xd0\xe7\xff\xbf_%08x.%08x.%08x.%08x.%08x.%08x.%s
, ma l'indirizzo non viene spinto ovunque e stampo solo il segreto [0] (che, per i curiosi, è 'D'). Ho provato tutti i tipi di indirizzo, ma dopo un po 'mi sono reso conto che stavo semplicemente memorizzandoli tutti come una stringa in cui quelli di A si sono presentati in precedenza. Non vengono convertiti in esagoni o altro.
Ho visto molte discussioni su questo codice su SA e in altri luoghi, ma devo ancora vedere qualcuno parlare di come si ottengono i valori in segreto [1].
Qualsiasi aiuto sarebbe molto apprezzato.
Sì, questo è quello che mi mancava. Mi sono sentito un idiota TOTAL dopo averlo scoperto. Grazie! – Max