2016-12-19 18 views
1

Я следую инструкциям по переполнению буфера Youtube Computerphile, чтобы узнать, как это работает. Учебное пособие говорит об этом в Kali, и я использую 64-битный тест Kali, чтобы проверить его (я думаю, что он работает 32-битный).Основная путаница с ошибкой переполнения буфера

Он пишет простую программу, как это:

#include <stdio.h> 
#include <string.h> 

int main(int argc, char** argv) { 

    char buffer[500];   
    strcpy(buffer, argv[1]); 

    return 0; 
} 

Затем после запуска программы в GDB он работает:

(gdb) run $(python -c 'print "\x41" * 506')

и результатом неисправности сегментный, который показывает, что возвращение адрес был частично перезаписан двумя 41-м.

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

  1. Почему 506 только переписать два байта вместо трех, когда он бежит это?

  2. Зачем мне писать 522 байта для перезаписывания 2 байтов в обратном адресе ? Я думаю, что это связано с ним, возможно, с использованием 32-битного вместо 64-битного Kali, но я не совсем понимаю, как это различие складывается математически.

  3. Когда я делаю disassemble main Я вижу, что после пролог функции есть инструкция sub rsp, 0x210, поэтому он выглядит так, что буфер выделяется 528 байт. Почему это число в частности (его вместо subs 0x1f4, который ровно 500) и как он относится к выше, где требуется больше 520 байт, чтобы начать переписывать указатель инструкции?

  4. Что происходит в диапазоне написания [500520] байт, где это более , чем размер буфера, но не писать поверх указателя на инструкции?

+3

Возможно, 32-разрядная версия использует 4-байтовое выравнивание стека, тогда как 64-разрядная версия использует 8-байтовое выравнивание стека. 500 делится на 4, но не 8. «Буфер» будет дополняться 4 байтами, но это приведет к 504 байтам. Не уверен, откуда приходит 520. –

+0

Хм, возможно ли, что это 500 дополняется от 4 до 504, а затем от +16 до 520, потому что между буфером и адресом возврата является адрес базового указателя? – Austin

+0

Можете ли вы посмотреть на разборку 'strcpy'? Возможно, это толкает регистры в стек. Наверное, нет. –

ответ

8

Разнообразный вопрос задается каждый месяц или около того.

Дело довольно прост: Запись через границу буферной приводит к непредсказуемому поведению , который может или не может вовлечь ошибку сегментации и перезаписи какой-либо конкретная структуры в памяти.

Предполагаемое вами допущение состоит в том, что для каждого пользователя используется обязательный макет памяти, и это просто неправда, а тем более методы, такие как рандомизация адресного пространства или оптимизация компилятора.

Ад, почему должен main функция хранить традиционный обратный адрес? Вероятно, это может быть очень хорошо вложено в код запуска для системы/компилятора/бинарного формата.

Если компилятор умен, он будет даже заметить, что argv[1] только доступ strcpy, который копирует его в буфер - а затем, не принимая во внимание ничего будет получить доступ к адресному пространству на argv[1] больше после main, просто не выделять ничего для буфера и просто используйте вместо этого &(argv[1]). И поскольку это используется нигде, ваш main() будет пустым, но для return 0, выражения const и, следовательно, вызов main может быть заменен на запись 0 на eax или на любую другую платформу, используемую для возвращаемых значений.

Ненависть, чтобы рассказать вам об этом, но: кроме указания на то, что на самом деле может быть переполнение буфера, оно дает только то, что работает на конкретной машине с конкретной версией компилятора, компилируя определенный фрагмент кода с специфический libc для конкретной архитектуры. Результат не может быть обобщен.

+0

. Какую информацию мне нужно знать о конкретной системе Linux и о том, какие флагов компилятора мне нужно использовать, чтобы убедиться, что переполнение буфера переполнения файлов cookie будет работать? У меня есть тест, где мне нужно продемонстрировать некоторые из основных атак памяти на таких программах, как это, и все эти маленькие особенности меня действительно смущают. Итак, какова жизненно важная информация, которую мне нужно собрать, прежде чем начать? – Austin

+3

Не существует переполнения буфера для файлов cookie, которые всегда работают. При рандомизации адресного пространства существуют даже четкие методы, которые борются с этим. Конечно, вы можете взглянуть на конкретную компоновку и макет памяти, которые конкретный компилятор в конкретной версии с ее конкретными флагами генерирует от конкретного кода и вывести возможные векторы атак, но на самом деле здесь не так много куки-резаний: от того, как работают компиляторы, и затем, чтобы легко понять, что вам нужно изменить, чтобы вызвать вредные вещи, все это * методическое * знание, которое вам нужно изучить, а не копировать –

+0

не могу отключить рандомизацию адресного пространства в gdb для демонстрации? – Austin