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

в 9:23, , рубрики: buffer overflow, ctf, pwn, pwnable.kr, stack overflow, информационная безопасность, Программирование
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@ssw0rdx00";
        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. Таким образом возможно “изменить” пароль на свой, передав программе, к примеру, такую строку 11111111x0011111111x00.

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 += 'xbexbaxfexca'

conn.send(payload)

conn.interactive()

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

image

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

image

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

Автор: RalfHacker

Источник


* - обязательные к заполнению поля