Все части переполнение буфера
Предыдущая часть Использование среды переменных окружения для переполнения буфера - разработка эксплойтов, часть 3
Следующая часть Переполнение буфера и перезапись адреса возврата - разработка эксплойтов, часть 5
Привет Codeby =) В предыдущей статье мы научились использовать среду переменных окружения для переполнения буфера, что само по себе уже не плохо. В этой статье мы познакомимся с новым принципом при переполнение буфера и немного поиграем с адресами памяти. Поехали!!!
Описание ExploitMe
Stack3 рассматривает переменные среды и способы их установки, а также перезапись указателей функций, хранящихся в стеке (в качестве прелюдии к перезаписи сохраненного EIP)
Советы
Исходный код
Решение
Рассмотрим код программы, значит у нас так же есть volatile, есть функция gets(), есть буфер на 64 байта, и есть указатель (*fp)() на не существующую функцию и есть функция которая никогда не будет вызвана win().
Исходя из этого нам нужно, каким-то образом сделать так, чтобы функция win() отработала, т.е. её надо как-то вызвать. Вопрос, как это сделать ??? А сделать это можно следующим способом. В нашей программе ведь есть уязвимость переполнения буфера, потому, как присутствует опасная функция gets(). И вся суть задачи сводится к тому, что нам нужно перезаписать теперь не значение переменной, а указатель на функцию. При вызове fp, указатель будет вызывать любой адрес памяти, расположенный в пределах fp, если он не равен нулю.
Указатель fp является локальной переменной и если мы переполним буфер, мы можем потенциально изменить значение fp, так как он находится в том же кадре стека. Условный оператор if проверяет, что fp не равен нулю. Если это так, он вызовет указатель функции fp на любой адрес памяти, сохраненный в нем.
Для того, чтобы это сделать, нам надо узнать адрес функции win(), сделать это можно двумя способами, через отладчик GDB или же через программу Objdump, которая позволяет просмотреть информацию об объектных файлах.
Рассмотрим первый вариант и запустим программу под отладчиком GDB, чтобы заглянуть под капот программы.
Далее дизассемблируем функцию win() чтобы получить её адрес.
И видим, что функция win() находится в памяти по адресу "0x08048424".
Отлично адрес получен. Теперь перейдем к способу номер два, но с начало выйдем из отладчика GDB, командой
И видим, что адрес функции win() опять получен и он не чем не отличается. Кстати говоря, если просто запустить objdump без утилиты grep, то мы получим полное ассемблерное полотно всей программы, что не очень удобно в данном случае, поэтому мы поступили именно так, чтобы получить конкретный адрес интересующей нас функции.
Вот и всё, это было довольно таки просто, адрес 08048424 у нас есть, теперь перейдем к эксплуатации уязвимости переполнение буфера, чтобы перезаписать указатель *fp на функцию win(). Будем все так же использовать питон.
После чего на экране появится две строчки «calling function pointer, jumping to 0x08048424» и «code flow successfully changed». Первая строчка означает, что мы перезаписали адрес указателя на функцию, а вторая означает, что можно переходить на следующий уровень
Предыдущая часть Использование среды переменных окружения для переполнения буфера - разработка эксплойтов, часть 3
Следующая часть Переполнение буфера и перезапись адреса возврата - разработка эксплойтов, часть 5
Привет Codeby =) В предыдущей статье мы научились использовать среду переменных окружения для переполнения буфера, что само по себе уже не плохо. В этой статье мы познакомимся с новым принципом при переполнение буфера и немного поиграем с адресами памяти. Поехали!!!
Описание ExploitMe
Stack3 рассматривает переменные среды и способы их установки, а также перезапись указателей функций, хранящихся в стеке (в качестве прелюдии к перезаписи сохраненного EIP)
Советы
- и gdb и objdump — ваши друзья, вы определяете где функция win () находится в памяти.
Ссылка скрыта от гостей
, VMИсходный код
C:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("code flow successfully changed\n");
}
int main(int argc, char **argv)
{
volatile int (*fp)();
char buffer[64];
fp = 0;
gets(buffer);
if(fp) {
printf("calling function pointer, jumping to 0x%08x\n", fp);
fp();
}
}
Решение
Рассмотрим код программы, значит у нас так же есть volatile, есть функция gets(), есть буфер на 64 байта, и есть указатель (*fp)() на не существующую функцию и есть функция которая никогда не будет вызвана win().
Исходя из этого нам нужно, каким-то образом сделать так, чтобы функция win() отработала, т.е. её надо как-то вызвать. Вопрос, как это сделать ??? А сделать это можно следующим способом. В нашей программе ведь есть уязвимость переполнения буфера, потому, как присутствует опасная функция gets(). И вся суть задачи сводится к тому, что нам нужно перезаписать теперь не значение переменной, а указатель на функцию. При вызове fp, указатель будет вызывать любой адрес памяти, расположенный в пределах fp, если он не равен нулю.
Указатель fp является локальной переменной и если мы переполним буфер, мы можем потенциально изменить значение fp, так как он находится в том же кадре стека. Условный оператор if проверяет, что fp не равен нулю. Если это так, он вызовет указатель функции fp на любой адрес памяти, сохраненный в нем.
Для того, чтобы это сделать, нам надо узнать адрес функции win(), сделать это можно двумя способами, через отладчик GDB или же через программу Objdump, которая позволяет просмотреть информацию об объектных файлах.
Рассмотрим первый вариант и запустим программу под отладчиком GDB, чтобы заглянуть под капот программы.
gdb -q ./stack3
Далее дизассемблируем функцию win() чтобы получить её адрес.
disassemble win
И видим, что функция win() находится в памяти по адресу "0x08048424".
Отлично адрес получен. Теперь перейдем к способу номер два, но с начало выйдем из отладчика GDB, командой
quit
После чего запускаем objdump с такими параметрами.objdump -d stack3 | grep win
И видим, что адрес функции win() опять получен и он не чем не отличается. Кстати говоря, если просто запустить objdump без утилиты grep, то мы получим полное ассемблерное полотно всей программы, что не очень удобно в данном случае, поэтому мы поступили именно так, чтобы получить конкретный адрес интересующей нас функции.
Вот и всё, это было довольно таки просто, адрес 08048424 у нас есть, теперь перейдем к эксплуатации уязвимости переполнение буфера, чтобы перезаписать указатель *fp на функцию win(). Будем все так же использовать питон.
python -c "print 'a' * 64 + '\x08\x04\x84\x24'[::-1]" | ./stack3
После чего на экране появится две строчки «calling function pointer, jumping to 0x08048424» и «code flow successfully changed». Первая строчка означает, что мы перезаписали адрес указателя на функцию, а вторая означает, что можно переходить на следующий уровень
Ссылка скрыта от гостей
.