В чем разница между атакой переполнения буфера и атакой ROP? - PullRequest
3 голосов
/ 08 июня 2019

Я начал изучать безопасность программного обеспечения, и у меня возникли проблемы с получением того, что такое атака переполнения буфера и атака ROP.

Насколько я понимаю,

Атака переполнения буфера:

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

Атака ROP:

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

Но какова точная разница между этими двумя?

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

Например, если у меня естькод

  1 #include <stdio.h>
  2 
  3 void check(){
  4     printf("overflow occurs!\n");
  5 }
  6 
  7 int main(int argc, char* argv[]){
  8     char buffer[256];
  9     gets(buffer);
 10     printf("%s\n", buffer);
 11     return 0;
 12 }

и попытаться выполнить функцию check(), передав определенный ввод функции gets().

Это атака ROP или атака переполнения буфера?

1 Ответ

2 голосов
/ 08 июня 2019

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


Переполнение буфера происходит, когда неправильная проверка границ или обработка данных неявной длины (например, strcpy или strcat) позволяет злонамеренному вводу записывать память за конец массива. Это становится интересным, когда массив размещается в стеке вызовов, поэтому одна из следующих вещей - это адрес возврата этой функции.

(Теоретически перезапись статической переменной после конца статического массива может быть полезна в качестве эксплойта, и это также может быть переполнением буфера. Но обычно переполнение буфера подразумевает наличие буфера в стеке, что позволяет злоумышленнику контролировать обратный адрес. И, таким образом, получить контроль над указателем инструкции.)

Помимо нового обратного адреса, ваши вредоносные данные будут содержать больше данных, которые будут в памяти ниже и выше этого обратного адреса. Частично это полезная нагрузка . Одного контроля обратного адреса обычно недостаточно: в большинстве процессов вы нигде не можете перейти к нему (без других входов), например, execve оболочка, прослушивающая порт TCP.

Традиционно вашей полезной нагрузкой будет машинный код («шелл-код»), а обратным адресом будет адрес стека, где вы знали, что полезная нагрузка приземлится. (+ - слайд NOP, поэтому вам не нужно было правильно его понимать).

Stack ASLR и неисполняемые стеки сделали невозможным использование традиционного метода вставки шелл-кода для использования переполнения буфера в обычных современных программах. «Атака переполнения буфера» раньше (я думаю) подразумевала внедрение шелл-кода, потому что не было необходимости искать более сложные атаки. Но это уже не так.


Атака ROP - это когда полезная нагрузка представляет собой последовательность адресов возврата и данных, которые должны быть извлечены инструкциями pop и / или некоторыми строками, такими как "/bin/sh". первый обратный адрес в полезной нагрузке отправляет выполнение некоторым уже существующим байтам по известному адресу в исполняемой странице.


и попробуйте выполнить функцию check(), введя определенный ввод для функции gets().

Код для check() уже существует в целевой программе, поэтому самой простой атакой будет атака ROP.

Это абсолютная простейшая форма ROP-атаки, когда код для выполнения именно того, что вы хотите, существует по одному известному адресу, без необходимости использования «аргументов функций». Так что это хороший пример для представления темы.

Это атака ROP или атака переполнения буфера?

Это оба. Это переполнение буфера для внедрения полезной нагрузки ROP.

Если программа была скомпилирована с -z execstack -no-pie, вы можете также ввести инъекцию, например. шелл-код x86, который сделал mov eax, imm32 / jmp eax для перехода к известному абсолютному адресу check. В этом случае это будет переполнение буфера, но не атака ROP; это будет атака с внедрением кода.

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


Атака переполнения буфера:

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

Опция "в коде" будет ROP-атакой. Вы указываете адрес возврата на код, который уже находится в памяти.

Опция "или его / ее собственный шеллкод" будет представлять собой атаку с внедрением кода. Вы указываете адрес возврата в буфер, который вы только что переполнили. (Либо напрямую, либо с помощью R2-атаки ret2reg, чтобы победить ASLR в стеке, например, ища гаджет jmp esp на x86.)

Это определение "переполнения буфера" все еще немного узкое: оно исключает перезапись некоторых других критических переменных (например, bool user_authenticated) без перезаписи адреса возврата.

Но да, кодВнедрение и ROP-атаки являются двумя основными способами, при этом внедрение кода обычно невозможно из-за неисполняемой стековой памяти.

...