Разработка эксплойтов, Часть 2 - Введение в переполнение буфера.
Наш telegram канал : @Save and betray
Описание ExploitMe
На этом уровне рассматривается концепция изменения переменных к конкретным значениям в программе и то, как переменные располагаются в памяти.
Этот уровень находится в / opt / protostar / bin / stack1
Переходить в каталог не нужно, так как мы сделали это в прошлый раз.
Советы
- Если вы не знакомы с отображаемым шестнадцатеричным числом, «man ascii» — ваш друг.
- little endian
Исходный код
C:
#include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> int main(int argc, char **argv) { volatile int modified; char buffer[64]; if(argc == 1) { errx(1, "please specify an argument\n"); } modified = 0; strcpy(buffer, argv[1]); if(modified == 0x61626364) { printf("you have correctly got the variable to the right value\n"); } else { printf("Try again, you got 0x%08x\n", modified); } }
Решение
В этом примере у нас так же есть
буфер на 64 байта, присутствует ключевое слово
volatile, но при этом тут нет теперь функции gets(), а в место неё есть функция strcpy().
Посмотрим описании функции.
Функция
strcpy
(destination, source) копирует данные из строки, на которую указывает аргумент source, в строку, на которую указывает аргумент destination, пока не встретится символ конца строки (нулевой символ). Копирование производится вместе с символом конца строки. Если строки перекрываются, результат копирования будет не определен.
Посмотрим на второе условие в программе, если переменная
modified
равняется значению «
0x61626364
», тогда печатается текст «
you have correctly got the variable to the right value
» иначе «
Try again, you got 0x%08x
», плюс указывается значение переменной modified в шестнадцатеричной системе счисления. Поскольку в программе, есть еще одно условие где используется аргумент
argc.
Запустить питон код, как в прошлой программе не получится. Воспользуемся BASH для подстановки значения, чтобы использовать наш вывод, в качестве аргумента.
Последовательность команд будет следующей.
./stack1 $(python -c "print 'a' * 65")
В итоге мы получим следующий текст на экране «Try again, you got 0x00000061», как видим переменная modified приняло текущее значение. Мы писали в буфер последовательность букв из «aaaa…», из них 64 байта пошли в буфер, последним перезаписали значение переменной modified. Стало быть modified равняется ‘a’. Посмотрим чему равно ‘a’ в хексе, воспользуемся man ascii. И видим, что ‘a’ равняется значению 0x61. Теперь еще раз взглянем на значение во втором условии «0x61626364», значит остальные числа в значении это «bcd», а всё вместе «abcd». Пробуем эксплуатировать, передадим 64 байта в буфер и еще 4 байта для перезаписи значения переменной modified.
./stack1 $(python -c "print 'a' * 64 + 'abcd' ")
Получаем строку «Try again, you got 0x64636261» , хм, что-то пошло не так и строка записалась в перевёрнутом виде. Почему? Если погуглить, то можно узнать о такой вещи, как little endian, т.е. в памяти, числа перевёрнутые. Значит делаем реверс строки и эксплуатируем уязвимость переполнения буфера в функции strcpy().
./stack1 $(python -c "print 'a' * 64 + 'abcd'[::-1]")
Отлично, переменная перезаписана, а на экране отображается текст «you have correctly got the variable to the right value» цель достигнута! Если в прошлом ExploitMe нашей задачей было просто изменить значение переменной, то в этой задаче мы научились устанавливать нужное нам значение для конкретной переменной используя уязвимость переполнения буфера. Теперь переходим на следующий уровень stack2.