Понимание и выполнение внедрения кода в C - PullRequest
9 голосов
/ 16 ноября 2009

Я немного запутался в идее внедрения кода в C. Если бы кто-то мог объяснить это и показать, как это делается, я был бы признателен.

Итак, допустим, в C у вас есть массив Char размером 512, который записывается в содержимое сокета длиной 1024, и этот массив char теперь содержит некоторый код, но только половину того, что было написано.

Как вредоносный код выполняется при переполнении буфера, думаю, я запутался в структуре процесса (стек, куча, данные, текст).

Ответы [ 3 ]

10 голосов
/ 16 ноября 2009

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

 void foo()
 {
    int array[5];
    int var = 0;
    int var2 = 0;

    // read in user input
    printf("Enter index and value to write:");
    scanf("%i", var);
    scanf("%i", var2);

    // malicious user might set var to -1 and var2 to an address to execute
    // if say the 32-bit value before the stack variables is the instruction to
    // return to
    array[var] = var2

    // return now goes to malicious code
 }

(Таким образом, ваша задача - создать код, чтобы это было невозможно. :))

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

2 голосов
/ 16 ноября 2009

Если вы выделяете буфер в стеке, и он переполняется, он записывает в стек. Стек содержит указатель возврата для функции, которая разместила буфер. Таким образом, если вы переполняете буфер в стеке, вы можете установить указатель возврата на что-то произвольное; тем самым давая вам контроль над потоком выполнения.

Что касается фактического внедрения кода, это зависит. Стек - или, скорее, страница, содержащая его - часто устанавливается так, чтобы не допустить выполнения кода; но исторически было возможно хранить небольшие вредоносные программы в самом буфере в стеке. Программирование, ориентированное на возврат - это довольно новый вариант атаки return-to-libc , обе из которых работают с битами NX.

0 голосов
/ 16 ноября 2009

Типичный стек для каждой подпрограммы может выглядеть следующим образом:

  • параметры (значения, которые были переданы в качестве параметров этой подпрограмме)
  • адрес возврата (адрес кода, с которого была вызвана эта подпрограмма)
  • сохраненные значения регистра
  • локальные переменные

Если подпрограмма имеет локальную переменную и каким-либо образом записывает после конца локальной переменной, то она перезаписывает значения (в стеке), как адрес возврата, то есть адрес кода, который будет выполнен в конце подпрограмма, когда подпрограмма «возвращает».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...