Всем доброго времени суток! Набираем обороты... Сегодня мы будем 'пывнить" stack3.exe (ссылочка на файл, как обычно, на Github).
Stack3
Закидываем в Ghidra:
![](https://habrastorage.org/getpro/habr/upload_files/c72/fc2/018/c72fc20180744532d0455f7fbdf5c6c3.jpg)
Анализируем...
![](https://habrastorage.org/getpro/habr/upload_files/0e6/6ee/e13/0e66eee1349c1588d3182d31544939ab.jpg)
Получаем декомпилированный код. Нас встречает все тот же массив из 64-х байт. Небезопасная функция gets(). Функция gets() считывает строку символов из стандартного потока ввода (stdin) и помещает ее в массив local_54. Также в коде есть указатель (local_14) на функцию и проверка (if), не является ли local_14 - NULL. Т.е. если мы "перезапишем" local_14, то попадем в ветку THEN и получим сообщение "calling function pointer, jumping to...", а также перейдем по адресу, которым мы перезапишем local_14:
![](https://habrastorage.org/getpro/habr/upload_files/94f/bc0/2d6/94fbc02d6fae7b29a2d860220eadd171.jpg)
Вроде бы все понятно, но есть ощущение, что чего-то нехватает? :)
Обращаем внимание на функцию "win":
![](https://habrastorage.org/getpro/habr/upload_files/a13/a5e/119/a13a5e1197e6a5bea8d2d4da5bd2816d.jpg)
Функция "win" просто выводит сообщение "code flow successfully changed":
![](https://habrastorage.org/getpro/habr/upload_files/708/794/6a7/7087946a735b74e8fe6e3ebc9a984de1.jpg)
Фактически, нам нужно использовать BOF, чтобы изменить значение указателя функции, сделав так, чтобы он указывал на адрес функции "win" (это и будет успешным прохождением таска "Stack3").
Переходим к "динамике". Делаем поиск по strings:
![](https://habrastorage.org/getpro/habr/upload_files/637/01f/506/63701f506d5c3fd8d1323106282dcf30.jpg)
Кликаем по строчке с "code flow successfully changed" и смотрим адрес инструкции "push ebp" (З.Ы. Это начало функции "win". Кому интересно, почему так, читайте про пролог/эпилог процедуры):
![](https://habrastorage.org/getpro/habr/upload_files/d57/a49/dd6/d57a49dd6ea884cad2b6654c444ef75b.jpg)
Супер! Адрес есть. Давайте посмотрим на наш "пейлоад", который мы подадим на стандартный поток ввода (stdin):
![64 байта "A" + адрес инструкции "push ebp" в LE 64 байта "A" + адрес инструкции "push ebp" в LE](https://habrastorage.org/getpro/habr/upload_files/3ac/0ea/95d/3ac0ea95da23dadc01f2aab3371941fb.jpg)
Эксплуатируем. Указатель изменён и мы попали в функцию "win" (о чем говорит сообщение "code flow successfully changed"):
![](https://habrastorage.org/getpro/habr/upload_files/3b9/9d0/75e/3b99d075e3528f53369501b651ae22a0.jpg)
Всем спасибо за внимание! Если понравилась статья, буду рад "пальцу вверх"!