Программирование, ориентированное на возврат (ROP)
Объединяйте гаджеты ROP, чтобы обойти NX/DEP и создавать эксплойты без шелл-кода.
«Программирование, ориентированное на возврат (ROP)» — бесплатный урок Cyber Security Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Cyber Security Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Cyber Security Academy содержит 4 уроков всего.
Зачем нужен ROP
При включённых NX/DEP внедрённый шелл-код не может выполняться. Программирование, ориентированное на возврат (ROP) обходит эту защиту, объединяя небольшие существующие последовательности кода (гаджеты), которые заканчиваются инструкциями ret. Новый код не внедряется — используются только стек и уже существующий код.
Что такое гаджет ROP
Гаджет — это короткая последовательность инструкций, заканчивающаяся ret, найденная в бинарном файле или загруженных библиотеках. Примеры: pop rdi; ret, pop rsi; ret, mov eax, 0; ret. Гаджеты являются строительными блоками цепочек ROP.
Поиск гаджетов
Инструменты для поиска гаджетов ROP в бинарных файлах:
# ROPgadget:
ROPgadget --binary ./vuln --rop
# ropper:
ropper -f ./vuln --search "pop rdi"
# pwntools:
from pwn import *
elf = ELF("./vuln")
rop = ROP(elf)
rop.find_gadget(["pop rdi", "ret"])Построение цепочки ROP
Цепочка ROP — это последовательность адресов возврата в стеке. Когда выполняется перезаписанный адрес возврата, управление переходит к гаджету 1 (он выполняет полезное действие, а затем делает возврат), который извлекает следующий адрес и переходит к гаджету 2, и так далее.
ret2plt и перезапись GOT
ret2plt вызывает функции через PLT (таблицу связывания процедур). Это удобно для вызова puts(), чтобы раскрыть адреса libc, а затем использовать их для вызова system(). Структуры PLT/GOT предсказуемы даже при включённом ASLR для основного бинарного файла (без PIE).
Обход ASLR с помощью ROP
ROP может раскрыть адрес функции libc из GOT с помощью гаджета, вызывающего puts(GOT_entry). Утёкший адрес раскрывает базовый адрес libc. Смещение system() вычисляется так: system_addr = leak - libc.symbols["puts"] + libc.symbols["system"].
SROP: программирование, ориентированное на sigreturn
SROP использует системный вызов sigreturn для загрузки поддельного кадра sigcontext, устанавливая все регистры в значения, контролируемые злоумышленником, с помощью одного гаджета. Это полезно, когда доступно мало гаджетов.
Варианты JOP и COP
Помимо ROP:
- JOP (программирование, ориентированное на переходы) — объединяет гаджеты, заканчивающиеся
jmp, а неret - COP (программирование, ориентированное на вызовы) — объединяет гаджеты, заканчивающиеся
call
Такие защиты, как CFI (целостность потока управления), направлены на предотвращение всех этих атак.
Целостность потока управления (CFI)
CFI требует, чтобы косвенные переходы (вызовы и возвраты) выполнялись только к допустимым целям. Этот механизм нарушает работу ROP, проверяя цель возврата по теневому стеку или списку разрешённых адресов. Intel CET (технология контроля потока управления) реализует CFI на аппаратном уровне.
Практический пример ROP
64-разрядный ret2libc через ROP:
# pwntools ROP chain example:
from pwn import *
p = process("./vuln")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf = ELF("./vuln")
rop = ROP(elf)
# Leak puts GOT to get libc base
rop.puts(elf.got["puts"])
rop.main()Обзор механизмов защиты
Защиты от ROP:
- CFI — проверяет цели переходов
- Теневой стек (CET) — аппаратно защищённая копия адреса возврата
- RELRO (полный) — делает GOT доступным только для чтения и предотвращает перезапись
- PIE — рандомизирует базовый адрес бинарного файла, поэтому для поиска гаджетов требуется утечка
Быстрая проверка: ROP
Что такое гаджет ROP?
Итоги урока
ROP обходит NX/DEP, объединяя существующие последовательности кода (гаджеты, заканчивающиеся на ret), — внедрение шелл-кода не требуется. Инструменты поиска гаджетов: ROPgadget и ropper. ret2plt раскрывает адреса libc, позволяя обойти ASLR. Защиты: CFI, теневые стеки (Intel CET), PIE и полный RELRO. ROP — основа современного эксплуатирования бинарных файлов.
Часто задаваемые вопросы
Урок «Программирование, ориентированное на возврат (ROP)» бесплатный?
Да — полный текст урока «Программирование, ориентированное на возврат (ROP)» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Cyber Security Academy, подпишись на CoddyKit PRO. Курс Cyber Security Academy содержит 4 уроков всего.
Чему я научусь в уроке «Программирование, ориентированное на возврат (ROP)»?
Объединяйте гаджеты ROP, чтобы обойти NX/DEP и создавать эксплойты без шелл-кода. Ты практикуешь Cyber Security Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Cyber Security Academy?
Предыдущий опыт не требуется. Cyber Security Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Программирование, ориентированное на возврат (ROP)»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Cyber Security Academy?
Да. Каждый урок Cyber Security Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Переполнение буфера стека
- Программирование, ориентированное на возврат (ROP)
- Уязвимости форматных строк
- Эксплуатация кучи: Use-After-Free и распыление кучи