Всем привет! В этой серии райтапов мы разберем известные задания по эксплуатации бинарных уязвимостей с Exploit Exercises (там их больше нет, поэтому я их перекомпилировал под Win). О том, что такое Buffer Overflow прекрасно и с примерами написано ТУТ (отличная статья от @Mogen). Кстати говоря, много крутых задачек на тему PWN есть на Codeby Games, так что рекомендую :)
Итак... мы будем решать наши задачки, используя статический (Ghidra) и динамический анализ (x64dbg). И самое главное, мы будем делать это без исходников уязвимой программы, в отличие от того, как это сделано ТУТ и ТУТ.
Stack0
Для решения этой задачки я буду использовать свою «песко‑реверс‑лабораторию», где у меня уже все «стоит» :)
![](https://habrastorage.org/getpro/habr/upload_files/ae2/ce1/c57/ae2ce1c574e89bbde49c225699c6b08e.jpg)
Сначала будем делать «статику». Запускаем гидру и закидываем программу, которую будем «пывнить».
![](https://habrastorage.org/getpro/habr/upload_files/ade/86d/1ca/ade86d1ca44a676f71d94243d3dd8b27.jpg)
Запускаем анализ:
![](https://habrastorage.org/getpro/habr/upload_files/8b6/35d/dc1/8b635ddc15ebe14096e99c3b7ead30a8.jpg)
Получаем дизасм-листинг и декомпилированный код:
![](https://habrastorage.org/getpro/habr/upload_files/4e3/048/0fc/4e30480fca0cc6a61675b4b1b707f7e6.jpg)
Переименовываем переменные (тут кода мало — не сильно нужно, но привычка хорошая):
![](https://habrastorage.org/getpro/habr/upload_files/7dd/05f/98c/7dd05f98c555ca149897f83dcd58adea.jpg)
Итак, видим, что у нас есть массив buf на 64 символа и «плохая» функция gets(). Также у нас есть условие: если переменная var1 = 0, то мы получим «Try again». Соответственно, чтобы попасть в ветку else, нам нужно как‑то модифицировать переменную var1. Выделяем код и запоминаем инструкцию «test eax, eax», она нам пригодится чуть позже.
![](https://habrastorage.org/getpro/habr/upload_files/88d/6f7/cab/88d6f7cabd4cd3ad3a3d783f01f9b749.jpg)
Переходим к «динамике». Открываем программу в x64dbg, смотрим strings и находим тот самый «Try again», проваливаемся по инструкции, видим «test eax, eax» и «test al, al». Ставим на любой из этих инструкций точку останова.
![](https://habrastorage.org/getpro/habr/upload_files/414/49c/f2f/41449cf2fbc18baf8ac98c11907786bc.jpg)
![](https://habrastorage.org/getpro/habr/upload_files/1cc/d42/65a/1ccd4265accb0b40c270dab7b3bff6b7.jpg)
«Подаем на вход» 10 символов.
![](https://habrastorage.org/getpro/habr/upload_files/753/d9b/964/753d9b964d2bf508892c9882a9d5ddf4.jpg)
Видим, что регистр EAX никак не поменялся (равен 0). P. S. Инструкция «test eax, eax» в языке ассемблера x86/x64 выполняет битовый логический оператор AND между регистром eax и самим собой. Инструкция «test» не изменяет значение в регистре eax, но влияет на флаги процессора, в частности, на флаг нуля (ZF), который устанавливается, если результат операции AND равен нулю. Это означает, что если eax содержит нуль, то ZF будет установлен, а если eax не равен нулю, то ZF будет сброшен. Это позволяет использовать инструкцию je (jump if equal) или jne (jump if not equal) для перехода к определенным меткам в зависимости от значения EAX.
Делаем условный переход (je) и получаем «Try again».
![](https://habrastorage.org/getpro/habr/upload_files/8cd/808/ddc/8cd808ddc3b790c607e282d3b590d583.jpg)
![](https://habrastorage.org/getpro/habr/upload_files/f09/d04/d47/f09d04d47183355ebe45eba5f7353fc1.jpg)
Здорово! А что будет, если мы отправим не 64 символа, а 65?
![](https://habrastorage.org/getpro/habr/upload_files/f14/98e/e60/f1498ee60b50ff758f01d485234a036f.jpg)
Видим, что в EAX находится единичка. Таким образом, 64 байта «привели» нас к началу измененной переменной (var1), и уже следующий байт будет помещен в измененную переменную. Другими словами, 65 байт данных изменят 0×00 000 000 на 0×00 000 041 (65-й символ «A»). Таким образом, небезопасная функция gets() позволила нам переполнить buf и изменить переменную var1, что привело нас к следующему результату:
![](https://habrastorage.org/getpro/habr/upload_files/280/ef5/65a/280ef565ab1d674e2399c37455f73dac.jpg)
Всем спасибо за внимание :)
PaulKaplan
Здравствуйте. Не подскажите аналогичные инструменты под Linux? С графическим интерфейсом.