Всем привет.
Продолжаем продолжать.
Вариант решения таска.
По классике открываем IDA и смотрим main
Видим тут несколько функций (я переименовал функции, аргументы и пременные чтобы мне было удобно разбираться в алгоритме):
1. greeting - функция выводит свое приветствие. Ничего что может нам помочь нет.
2. enter_name - функция, принимающая пользовательский ввод. Может быть полезна, оставим на потом.
3. setting_current_position - функция устанавливающая + на карте. Ничего интересного тут нет.
4. moving - функция, принимающая от пльзователя AWSD и передвигает. В теории тут может быть выход за границу массива.
Просмотрев 2 интересные функции меня сильно заинтересовала enter_name
и ее стек
Ага. Буфер размером 16 (0x10) байт, а читаем 256. BOF!
Посмотрев на функции, которые есть в бинаре не увидел ничего что поможет получить флаг, значит тут не просто ROP, а ret2libc. Значит надо ликать адреса в libc, получать эту саму libc, получать ее базу и получть шелл.
Для того, что бы ликнуть адреса нам нужно их напечатать, для этого у нас есть функции puts, write. Хорошо. Использовать буду puts, т.к. она проще, потому что там только один аргумент и передается он с помощью гаджета POP RDI
Адреса функций, которые беруться из Libc находятся в .got.
Также нам понадобится адрес функции enter_name, для того, что бы можно было заново эксплуатировать уязвимость. Таким образом считаем нагрузку для ROP, далее печатаем адрес функции из got, запомниаем его и ищем какая же у нас либа. Так как я ленивый и искать на libc.blukat.me мне было лень, то я автоматизировал это.
На скриншоте видно, как берутся гаджеты из бинаря, как формируется PADDING (то что всегда необходимо делать перед ROP), как происходит получение адресов функций из .got и их печать, как возвращаемся в enter_name.
И две функции, которые получают возможные libc по ликнутым адресам, скачивают первую либу и подгружают ее, что бы иметь возможность искать прямо в либе оффсеты system и /bin/sh, ну и посчитать базу libc.
НО, почему-то я не смог взять адрес enter_name из EXE.symbols/EXE.sym. Если кто-то знает почему он тут не взялся, расскажите, ооочень интересно.
Сам эксплоит выглядит вот так:
0. Предыдущие шаги + классический io = start()
1. Ликаем адреса и запоминаем их.
2. Пробуем получить либу в libc.blukat.me (оно почему-то сломалось =)). Если не получается, то ищем через Libc database. Если снова не получилось, то что-то не то, перестает эксплоит работать.
3. Получение оффсетов из либс и подсчет базы libc. Я сделал 2 раза, чтобы наверняка =)
4. Ищем /bin/sh\x00, почему именно так, потому что бывают /bin/sh без завершающего 0, что совсем не надо.
5. Ищем system для получения шелла.
6. Финальная нагрузка.
7. PWNED
Спасибо.
Продолжаем продолжать.
Вариант решения таска.
По классике открываем IDA и смотрим main
Видим тут несколько функций (я переименовал функции, аргументы и пременные чтобы мне было удобно разбираться в алгоритме):
1. greeting - функция выводит свое приветствие. Ничего что может нам помочь нет.
2. enter_name - функция, принимающая пользовательский ввод. Может быть полезна, оставим на потом.
3. setting_current_position - функция устанавливающая + на карте. Ничего интересного тут нет.
4. moving - функция, принимающая от пльзователя AWSD и передвигает. В теории тут может быть выход за границу массива.
Просмотрев 2 интересные функции меня сильно заинтересовала enter_name
и ее стек
Ага. Буфер размером 16 (0x10) байт, а читаем 256. BOF!
Посмотрев на функции, которые есть в бинаре не увидел ничего что поможет получить флаг, значит тут не просто ROP, а ret2libc. Значит надо ликать адреса в libc, получать эту саму libc, получать ее базу и получть шелл.
Для того, что бы ликнуть адреса нам нужно их напечатать, для этого у нас есть функции puts, write. Хорошо. Использовать буду puts, т.к. она проще, потому что там только один аргумент и передается он с помощью гаджета POP RDI
Адреса функций, которые беруться из Libc находятся в .got.
Также нам понадобится адрес функции enter_name, для того, что бы можно было заново эксплуатировать уязвимость. Таким образом считаем нагрузку для ROP, далее печатаем адрес функции из got, запомниаем его и ищем какая же у нас либа. Так как я ленивый и искать на libc.blukat.me мне было лень, то я автоматизировал это.
На скриншоте видно, как берутся гаджеты из бинаря, как формируется PADDING (то что всегда необходимо делать перед ROP), как происходит получение адресов функций из .got и их печать, как возвращаемся в enter_name.
И две функции, которые получают возможные libc по ликнутым адресам, скачивают первую либу и подгружают ее, что бы иметь возможность искать прямо в либе оффсеты system и /bin/sh, ну и посчитать базу libc.
НО, почему-то я не смог взять адрес enter_name из EXE.symbols/EXE.sym. Если кто-то знает почему он тут не взялся, расскажите, ооочень интересно.
Сам эксплоит выглядит вот так:
0. Предыдущие шаги + классический io = start()
1. Ликаем адреса и запоминаем их.
2. Пробуем получить либу в libc.blukat.me (оно почему-то сломалось =)). Если не получается, то ищем через Libc database. Если снова не получилось, то что-то не то, перестает эксплоит работать.
3. Получение оффсетов из либс и подсчет базы libc. Я сделал 2 раза, чтобы наверняка =)
4. Ищем /bin/sh\x00, почему именно так, потому что бывают /bin/sh без завершающего 0, что совсем не надо.
5. Ищем system для получения шелла.
6. Финальная нагрузка.
7. PWNED
Спасибо.