Рандомизация макета адресного пространства и структуры в C - PullRequest
0 голосов
/ 17 октября 2018

У меня есть такая структура:

struct Books {
 char  title[50];
 char  author[50];
};

Допустим, я знаю, что если я передаю arg1 программе, в какой-то части кода она добавляет несколько символов в направлении $title+52поэтому значение author перезаписывается (переполнение буфера).

Теперь я добавляю ASLR в мой двоичный файл.Таким образом, некоторые направления являются случайными, поэтому я думаю, что переполнение буфера, которое я описал ранее, не могло быть возможным.

Это правда?Или даже если я добавлю ASLR, направления членов структуры будут вместе и переполнение буфера будет возможно?

Ответы [ 3 ]

0 голосов
/ 17 октября 2018

ASLR не влияет на вещи, которые находятся во время компиляции.Компилятор выбирает компоновку структуры во время компиляции, и это жестко закодировано в результирующем объектном коде.

Кроме того, стандарт C требует, чтобы последовательные элементы структуры размещались в памяти в порядке их появления вопределение структуры (с неопределенным заполнением между членами, но это также исправлено во время компиляции)

0 голосов
/ 17 октября 2018

Я думаю, что вы неправильно понимаете эффекты ASLR (рандомизации размещения адресного пространства): ASLR случайным образом размещает позиции разных областей виртуальной памяти процесса (исполняемый, стек, куча, данные, библиотеки и т. Д.) В каждомвыполнение.Он не меняет относительное положение элементов в одной и той же области виртуальной памяти.


Возьмем, к примеру, следующую простую программу:

int main(void) {
    struct {
        char a[10];
        char b[10];
    } myvar;

    printf("a: %p\n", &myvar.a);
    printf("b: %p\n", &myvar.b);

    return 0;
}

Вот виртуальная память программы с ASLR отключено :

0x555555554000     0x555555555000 r-xp     1000 0      /home/marco/test/test [executable segment]
0x555555754000     0x555555755000 r--p     1000 0      /home/marco/test/test [read only data]
0x555555755000     0x555555756000 rw-p     1000 1000   /home/marco/test/test [bss (global variables)]
0x7ffffffde000     0x7ffffffff000 rw-p    21000 0      [stack] <-- myvar is here

Вывод (ASLR отключен):

$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a
$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a
$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a

А вот та же программа с включенным ASLR :

0x559fefcbe000     0x559fefcbf000 r-xp     1000 0      /home/marco/test/test [executable segment]
0x559fefebe000     0x559fefebf000 r--p     1000 0      /home/marco/test/test [read only data]
0x559fefebf000     0x559fefec0000 rw-p     1000 1000   /home/marco/test/test [bss (global variables)]
0x7ffe3bb5e000     0x7ffe3bb7f000 rw-p    21000 0      [stack] <-- myvar is here

Вывод (ASLR включен):

$ ./test
a: 0x7ffe3bb5e080
b: 0x7ffe3bb5e08a
$ ./test 
a: 0x7ff4abdeea80
b: 0x7ff4abdeea8a
$ ./test 
a: 0x7efa6b8fa080
b: 0x7efa6b8fa08a

Ваша переменная все еще будет находиться внутри определенного непрерывного блока виртуальной памяти и относительное положение полей не изменится вообще.Смежные массивы по-прежнему будут смежными с использованием ASLR: они просто начнутся с другой позиции в памяти.

Поскольку поля struct по умолчанию являются смежными в памяти (и следуют их порядку объявления), это означает, что переполнение буфера все еще будет потенциальной проблемой , даже при использовании ASLR.

0 голосов
/ 17 октября 2018

Конкретное упомянутое вами переполнение все еще возможно.

За исключением битовых полей, поля структуры следуют друг за другом по порядку в памяти (с некоторым возможным заполнением между ними).Это подробно описано в разделе 6.7.2.1p15 стандарта C :

Внутри структурного объекта, элементов, не являющихся битовыми полями, и единиц, в которых бит-поля постоянно имеют адреса, которые увеличиваются в порядке их объявления. Указатель на объект структуры, соответствующим образом преобразованный, указывает на его начальный элемент (или, если этот элемент является битовым полем, то на единицу вкоторый он проживает), и наоборот.В объекте структуры может быть безымянный отступ, но не в его начале.

Таким образом, в этом случае поле author будет всегда следовать за полем title, независимо от того,по какому конкретному адресу находится объект типа struct Books.Единственным возможным отличием может быть количество отступов, но если вы не добавите или не удалите поля в структуре, это, вероятно, не изменится.

...