pracuję na format string podatności laboratorium, dokąd dany następujący kod:Dostęp 2nd element tablicy w ataku podatności 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;
}
Nie powinniśmy zmodyfikować kod w ogóle. Używając tylko danych wejściowych, mamy 4 cele: awarię programu, wydruk wartości w tajemnicy [1], modyfikowanie wartości w tajemnicy [1] i modyfikowanie wartości w tajemnicy [1] do wcześniej ustalonej wartości.
Przykładowe wyjście pojawia się:
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
Tak, wprowadzając 8 "% 08X" S, wydrukować adres sekret + 4, a następnie wydrukować adresy int a, b, c, i d - ale ponieważ nigdy nie dałem im żadnej wartości, nie wskazują one nigdzie i wyświetlają tylko cyfry 0. Następnie wprowadzany jest dziesiętny, tak aby "ffff" był wyraźnie widoczny. Następnie przychodzi adres sekretu [0], a następnie dostaję się do innych wartości zapisanych w programie.
Jeśli miałbym wprowadzić AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x%08x.
, po .0804a008 będzie .41414141, ponieważ A z ciągu znaków będą tam przechowywane.
Program dość łatwo ulega zawieszeniu: wystarczająca liczba% s na wejściu łańcuchowym powoduje błąd segfault. Teraz muszę przeczytać wartość w tajemnicy [1], a ja jestem totalnie zagubiony. Próbowałem jakoś umieścić adres na stosie, umieszczając go na początku łańcucha w następujący sposób: \xd0\xe7\xff\xbf_%08x.%08x.%08x.%08x.%08x.%08x.%s
, ale adres nie jest nigdzie nigdzie popychany i po prostu drukuję sekret [0] (co dla ciekawskich, to "D"). Próbowałem różnych adresów, ale po pewnym czasie uświadomiłem sobie, że przechowuję je wszystkie jako ciąg znaków, gdzie te A pojawiły się wcześniej. Nie są konwertowane na hex lub cokolwiek.
Widziałem wiele dyskusji na temat tego kodu na SA i innych miejscach, ale jeszcze nie widziałem, aby ktoś mówił o tym, jak uzyskać tajne wartości [1].
Każda pomoc zostanie bardzo doceniona.
Tak, tego właśnie mi brakowało. Czułem się jak totalny idiota po stwierdzeniu tego. Dziękuję Ci! – Max