Сканирование отображения: атаки на TCP без возможности подмены трафика (часть II)

Сканирование отображения: атаки на TCP без возможности подмены трафика (часть II)

В данной статье рассматривается, каким образом поток траффика, взятый из общей очереди пакетов, может быть использован как сторонний канал, через который нарушитель может получить  конфиденциальную информацию.

Автор:Ян Вробель

wrr@mixebit.org

Информация о Netfilter.

Почему Netfilter не отклоняет SYN-ACK сегменты, получаемые в контексте уже установленного подключения? Существует, как минимум, два показателя некорректности SYN-ACK сегмента:
  1. Номер ACK не подтверждает ни один SYN-сегмент.
  2. Обмен данными был произведен в обоих направлениях, должен пройти алгоритм трехстороннего рукопожатия.

В комментарии к исходному коду netfilter сказано:

«Наше подключение может не быть синхронизировано, поэтому игнорируйте пакеты, которые могут сигнализировать о настоящем подключении между клиентов и сервером» (игнорировать, в данном случае, не значить отбрасывать)

Проблема заключается в том, что netfilter и TCP стек Linux являются разными, несвязанными элементами. Netfilter не имеет доступа к состоянию TCP подключению, но может воссоздавать его на основе сегментов, рассмотренных ранее. В данном случае не подразумевается, что защищаемая конечная точка находится на той же машине, и что принятые ей сегменты достигли цели.

5.2 Номера последовательности

Для того чтобы вставить данные в начало окна на одном из концов соединения (с конца жертвы или пира жертвы), нарушителю необходимо знать, каковым по счету будет следующий октет (SND.NXT), отправляемый с другого конца соединения. Знать точное значение SND.NXT конечной точки, в которой производится вставка данных, необязательно, нужно лишь, чтобы сегмент, вставляющий данные, имел подходящий номер подтверждения. Вставить данные достаточно легко, при условии, что конечная точка не обменивается активно информацией с сетевым узлом, и размер окна и SND.NXT остаются постоянными. Невыполнение последнего условия образует дополнительное препятствие для нарушителя. Подобный случай в работе не рассматривается.

Необходимые шаги для определения SND.NXT значительно различаются для двух проведенных экспериментов. В обоих случаях используются ACK-сегменты и одноразовый порт, определенные на предыдущем шаге. При установленном соединении (корректные IP-адреса и порты) межсетевой экран Windows никогда не отбрасывает ACK-сегменты, поэтому при анализе ответов Windows необходимо принимать во внимание только правила, установленные документом RFC 793. NetFilter применяет более строгие правила фильтрации. В следующем подразделе демонстрируется, что более строгие правила фильтрации значительно уменьшают количество ресурсов, необходимых для атаки.

Хост работает строго по правилам RFC 793

В первую очередь необходимо определить номер последовательности на узле сети жертвы. Если окно содержит номер последовательности следующего ACK-сегмента, и значение поля “номер подтверждения” принимается, то сегмент не вызывает никакого ответа. В противном случае, в ответ высылается ACK-сегмент. Согласно RFC 793, номер подтверждения принимается, если его значение равно или меньше не более чем на 231 номера следующего отсылаемого октета. Другими словами, принимаемое значение номера подтверждения лежит в промежутке [SND.NXT - 231; SND.NXT] (в терминах “арифметики последовательностей”). Поэтому одно из двух значений поля “номер подтверждения”, различающихся на 231, гарантировано будет приниматься. Нарушителю необходимо послать

запросов, чтобы найти номер последовательности, содержащийся в окне. Риск случайно внести в сессию искажения пренебрежимо мал. Сессия будет искажена, только если нарушитель подтвердит получение данных, потерянных при передаче. В этом случае данные повторно передаваться не будут.

Нарушителю не нужно в точности знать размер окна жертвы, хотя этот размер очень часто можно c легкостью определить (см. [11]). Сначала нарушитель может предположить, что размер окна максимальный (1 ГБ) и проверить номера последовательности, отличающиеся на 230. Если ни один из таких номеров последовательности в окне не содержится, то нарушитель может разбить предыдущий промежуток поиска пополам и проверить уже другие номера последовательности. Так если жертва использует окно размером 0.5 ГБ, то один из полученных номеров последовательности окажется внутри окна. Шаги можно повторять, каждый раз уменьшая размер окна в два раза, до тех пор, пока не будет найден номер последовательности, содержащийся внутри окна. Подобный поиск более подробно описан в [8].

Из N запросов необходимо выделить единственный, который не вызывает положительного ответа. Ситуация противоположна сканированию портов, где, наоборот, производится поиск запроса, вызывающего положительный ответ. В действительности, поиск отрицательного ответа более сложен. Это вызвано следующими возможными проблемами:

  • “бутылочное горлышко” сети постоянно перегружено. В этом случае сканирование необходимо проводить последовательно, с достаточно большими интервалами между отдельными запросами, так как нужно ждать, пока освободится место в очереди “бутылочного горлышка”. Сканировать несколько значений одновременно невозможно, потому что можно достаточно легко заметить скачки трафика и их отсутствие, и намного труднее отличить один скачок трафика от другого скачка, чуть менее сильного.
  • Естественный трафик может скрывать отсутствие ответа. И напротив, когда производится поиск запроса, на который ответит система, скачки трафика могут только усиливаться.

Из рис. 4 видно, как уменьшается время RTT, когда номер последовательности находится внутри окна. В таблице 2 показано, что даже в случае простоя, для полного сканирования требуется значительное время. В экспериментальное среде PoC коду потребовалось примерно 36 часов, чтобы провести сканирование при закачивании данных.

Зная номер последовательности внутри окна, нарушитель может найти SND.NXT узла сети жертвы. Для этого нужно найти минимальный номер последовательности, который не генерирует ответ. Значение SND.NXT не превосходит размера окна, меньше номера последовательности, и может быть найдено с помощью бинарного поиска за логарифмическое относительно размера окна число запросов.

Кроме того, если требуется найти значение SND.NXT жертвы, то теперь это можно легко сделать. Для наибольшего номера подтверждения, который не генерирует ответа (если принимается), необходимо сделать 31 запрос в бинарном поиске. Полученное число равно значению SND.NXT жертвы.

Для защиты используется Netfilter

В первую очередь необходимо определить номер последовательности жертвы. В способе определения номера используются правила проверки номера подтверждения, описанные в разделе 5.1. ACK-сегмент принимается только в том случае, если его номер подтверждения равен или меньше не более чем на max(66000, максимальный размер видимого окна отправителя) номера следующего октета. Другими словами, принимаемый номер подтверждения лежит в промежутке [SND.NXT - max(66000, максимальный размер видимого окна отправителя), SND.NXT] (в терминах “арифметики последовательностей”). Сегменты с неподходящим номером подтверждения отбрасываются межсетевым экраном. Netfilter не проверяет номера последовательности ACK-сегментов. В Linux’е на TCP уровне в неотброшенных сегментах проверяется номер последовательности, и, если внутри окна его нет, то в ответ высылается ACK-сегмент.

Благодаря этому можно найти подходящий номер подтверждения за 232/ max(66000, максимальный размер видимого окна отправителя) попыток. Если жертва отвечает на сегмент с неправильным номером последовательности, то это означает, что номер подтверждения был принят Netfilter’ом. Поиск подходящего номера подтверждения аналогичен поиску одноразового порта. Необходимо проверить по крайней мере 232/ 66000 = 65075 значений, и только одно из этих значений вызывает генерацию положительного ответа, поэтому также за один запрос можно проверять несколько значений. Для оценки необходимых ресурсов можно вновь обратиться к таблице 1.

Таблица 1. Поиск одноразового порта. Поиск осуществлялся на всем пространстве из 65К одноразовых портов.

Тип соединения

Время сканирования

Количество

запросов

Пинг

Максимальное число проверенных портов за запрос

Поддельные сегменты

Отраженные сегменты

бездействие

35

592

2960

5 за запрос

итого: 0,25 МБ

среднее RTT: 22мс

200

2202780

30 портов за запрос

итого: 171 МБ

330

25 КБ

скачивание

852

849

8490

10 за запрос

итого: 0,7 МБ

среднее RTT: 749мс

100

73614000

1000 портов за запрос

итого: 5741 МБ

12000

0,9 МБ

закачивание

690

852

8520

10 за запрос

итого: 0,7 МБ

среднее RTT: 656мс

100

74013000

1000 портов за запрос

итого: 5773 МБ

10000

0,8 МБ

Таблица 2. Поиск номера последовательности, находящегося внутри окна, в случае строгого следования RFC 793. Размер окна: 65 КБ.

Тип соединения

Время сканирования

Количество

запросов

Пинг

Поддельные сегменты

Отраженные сегменты

бездействие

16860

~5 ч.

131338

394014

3 за запрос

итого: 32 МБ

среднее RTT: 85мс

3940140

30 за запрос

итого: 307 МБ

3939930

Таблица 3. Поиск подходящего номера подтверждения. Нарушитель обманывает Netfilter, увеличивая окно отправителя до 8.3 МБ, это позволяет проверить всё возможное пространство номеров подтверждения за небольшое количество запросов.

Тип соединения

Время сканирования

Количество

запросов

Пинг

Максимальное число проверенных номеров подтверждения за запрос

Поддельные сегменты

Отраженные сегменты

бездействие

3.4

60

300

5 за запрос

итого: 24 КБ

среднее RTT: 21мс

25

20520

30 номеров подтверждения за запрос

итого: 1.6 МБ

240

18 КБ

скачивание

61

51

510

10 за запрос

итого: 42 КБ

среднее RTT: 866мс

25

627000

1000 номеров подтверждения за запрос

итого: 49 МБ

4000

0,3 МБ

закачивание

59

56

560

10 за запрос

итого: 45 КБ

среднее RTT: 602мс

25

728000

1000 номеров подтверждения за запрос

итого: 57 МБ

6000

0,5 МБ

результаты сканирования номера последовательности (нормализация: 0 внутри окна)

(а) бездействие, 5 пинг на каждый номер последовательности, 30 поддельных сегментов на каждый номер последовательности

результаты сканирования номера последовательности (нормализация: 0 внутри окна)

(а) закачка, 10 пинг на каждый номер последовательности, 1000 поддельных сегментов на каждый номер последовательности

Рисунок 4. Измерено наименьшее среднее время RTT и количество потерь, в случае, когда поддельный сегмент находится внутри окна. Время RTT и количество потерь для других замеров достаточно велико и поэтому, длительность сканирования увеличивается. Естественные скачки трафика могут маскировать минимумы. Пинг считается потерянным, если ответ не получен по прошествии двух интервалов RTT с момента последнего пинга для того же номера последовательности.

Существует уловка, которая позволяет улучшить эффективность поиска. Netfilter можно легко обмануть, установив максимально возможный размер окна отправителя. Точное значение максимума определяется во время установки сессии. Для того чтобы обойти фильтр потребуется отослать 65075 ACK-пакетов, покрывающих все пространство в 232 номеров подтверждения, причем значения номеров будут отличаться на 66000. Для всех таких ACK-сегментов устанавливается максимально возможный размер окна: 0xFFFF. Один из ACK-сегментов должен приниматься Netfiltr’ом и устанавливать максимальный размер видимого окна в (заметим, что это не повлияет на реальный размер окна, протокол TCP в конечной точке отбросит ACK-сегмент, поскольку он содержит неправильный номер последовательности). Во время эксперимента, отправитель устанавливал размер окна равным 114, а коэффициент масштабирования равным 7, следовательно, размер видимого окна устанавливается в . Последовательная отправка поддельных ACK-сегментов обманывает Netfilter и увеличивает размер видимого окна до . С помощью окна такого размера можно покрыть все пространство в 232 номеров подтверждения, задействовав всего 512 значений. Если бы целью атаки являлся хост, работающий строго по RFC 793, то нарушителю можно было бы обойтись без знания размера окна жертвы и масштабирующего множителя. Можно предположить, что размер окна максимальный (1 ГБ), и путем последовательного деления пополам найти номер подтверждения.

Сводная информация о необходимых для атаки ресурсах приведена в таблице 3.

Зная подходящий номер подтверждения, с помощью бинарного поиска легко находится номер последовательности следующего октета, отсылаемого жертвой. Для этого необходимо log(max(66000, максимальный размер видимого окна отправителя)) запросов.

У нарушителя есть несколько способов узнать значение SND.NXT сетевого узла жертвы:

  • Сегменты с единственным байтом данных. Netfilter проверяет номера последовательности в сегментах, содержащих данные. Если номер содержится внутри окна, то сегмент передается на TCP уровень, где в ответ генерируется ACK-сегмент, так как данные повреждены. Если номера последовательности внутри окна нет, то Netfilter отбрасывает сегмент. Риск данного метода кроется в вероятности нарушить сессию, если байт данных все-таки будет принят.
  • Если нарушитель имеет возможность слать подмененный трафик в оба конца соединения и бесперебойно отслеживать в них скачки трафика, то целью нарушителя может стать другой конец соединения. Если другой конец работает согласно RFC 793, понадобиться всего 32 запроса, чтобы найти второй SND.NXT. Если же на другом конце установлен Netfilter, можно применить метод, описанный в этом разделе.
  • Как и в предыдущем подразделе можно осуществить ресурсоемкий поиск номера последовательности, который не вызывает никакого ответа. Единственное отличие заключается в том, что номер подтверждения уже известен, и нужно определить только номер последовательности внутри окна.

5.3 Другие случаи

В различных реализациях протокола TCP правила обработки сегментов отличаются друг от друга, и это может как устранить некоторые уязвимости, описанные в настоящей статье, так и открыть новые. Например, для предотвращения слепой RST-инъекции (описание атаки в [12]), созданы новые рекомендации для обработки RST-сегментов [3]. Согласно RFC 793, любой RST-сегмент, находящийся внутри окна, должен приниматься и затем разрывать соединение. Более строгие и более безопасные правила требуют, чтобы номер последовательности RST-сегмента в точности совпадал со следующим ожидаемым номером последовательности. В противном случае, RST-сегмент должен в ответ вызывать генерацию ACK-сегмента и не разрывать соединение. В документе советуется выборочно пропускать такие ACK-сегмены. Если эти сегменты не пропускать, нарушитель сможет с помощью RST-сегмента запросить окно, практически не рискуя случайно разорвать сессию.

6. Улучшенные методы сканирования

С помощьюрежима fast retransmit [13] и относительно небольшого количества поддельных сегментов можно вызвать большие скачки трафика. Режим fast retransmit активируется при получении трех дубликатов ACK-сегментов. На уровне TCP подобные дубликаты воспринимаются как сообщения о том, что один сегмент был потерян, но три последующих сегмента успешно получены. Каждый последующий дубликат ACK-сегмента расценивается как подтверждение того, что какой-то другой сегмент успешно получен, но потерянный сегмент так и не достиг своей точки назначения. Поскольку сегменты покидают сеть, отправитель отсылает новый сегмент в ответ на каждый дубликат ACK-сегмента. Существует вероятность, что резкое увеличение ACK-сегментов вынудит отправителя отослать полное окно данных за очень короткий промежуток времени, как это описано в [9]. Коэффициент усиления для сети с MTU 1500 равен 37. Это и позволяет нарушителю вызвать заметные скачки трафика, используя значительно меньшее количество поддельных сегментов.

Метод также подходит для обнаружения номера одноразового порта хоста, который не отфильтровывает сегменты, принадлежащие несуществующему соединению, а вместо этого отвечает RST-сегментом на каждый такой сегмент. Последовательность поддельных сегментов, направленная на некорректный номер порта вызывает генерацию последовательности RST-сегментов, отбрасываемых на другом конце соединения без каких-либо дополнительных действий. Последовательность поддельных сегментов, направленная на корректный номер порта вызывает генерацию последовательности ACK-сегментов, которая, в свою очередь, вынуждает другую сторону выслать полное окно данных. Если нарушитель заметит скачок трафика, причиной которого служит отправка полного окна данных, то он также сможет определить порт.

На практике такой метод не проверялся.

7. Защита

Для предотвращения утечек информации по побочным каналам способами, описанными в данной статье, протокол должен гарантировать, что ответ на неаутентифицированные сегменты никогда не будет генерироваться. Тогда нарушитель получит информацию только о том, что сегмент не был аутентифицирован. Достаточно сильный механизм аутентификации, сводящий вероятность генерации подходящего запроса к минимуму, не позволит нарушителю получить дополнительную информацию через побочный канал. Опция TCP Authentication [14] предоставляет нужный механизм аутентификации, но эта опция редко когда используется.

Если аутентификация основывается на номерах последовательности, то иногда бывает сложно убедиться в том, что протокол никогда не отвечает на отброшенные сегменты. Номера последовательности предназначены для решения двух задач. В первую очередь они нужны для обнаружения дубликатов, потерянных и поврежденных сегментов. Но в дополнение к этому номера последовательности стали выступать в качестве защитного механизма от атаки, и такая функция не упоминается даже в исходной документации. Если Netfilter отфильтрует SYN-ACK сегменты, направленные на установленное соединение, и отбросит ACK-сегменты c некорректными номерами последовательности, то атака на систему, защищенную Netfilter’ом, вероятнее всего, окажется неудачной. Но составлять более строгие правила фильтрации нужно с особой аккуратностью, так как в противном случае иногда такие правила могут привести к зависанию соединения.

Выборочный пропуск ответов на отброшенные сегменты не должен делать утечку информации возможной на практике. Метод выборочного пропуска ответов для ACK-сегментов, генерируемых в ответ на RST и SYN-ACK сегменты, находящихся внутри окна, был предложен в работе [3]. Этот механизм эффективен только тогда, когда ACK-сегменты будут выборочно пропускаться в ответ и на другие отброшенные сегменты.

Атака упрощается, если нарушитель находится по ту же сторону от пограничного маршрутизатора, что и жертва. Расстояние в несколько близлежащих хопов также идеально подходит для фильтрации подмененных IP пакетов. Сеть, сконфигурированная отбрасывать подобный трафик, защищена, по крайней мере, от внутренней атаки.

Политика постановки в очередь, позволяющая изолировать трафик, идущий от различных пользователей, также может усложнить реализацию атаки. В работе [15] изучается политика диспетчеризации и защиты конфиденциальности. Авторам удалось значительно снизить влияние видов трафика различных пользователей в очереди друг на друга, не налагая дополнительных ограничений на производительность. Разработанная политика снижает утечки информации в зависимости от конкретного вида трафика, но поток трафика по-прежнему остается высоким из-за увеличения времени обработки пакета. Для реализации атаки, описанной в настоящей статье достаточно обнаружить увеличение потока трафика, когда как знать конкретный вид трафика необязательно. В дальнейших исследованиях необходимо оценить влияние различных политик постановки в очередь на эффективность атаки.

8. Заключение

В работе демонстрируется, как изменения во времени обработки пакетов, проходящих через разделяемую очередь, позволяют узнать, отвечает ли хост на подмененный трафик. Показано, что в случае протокола TCP для компрометации сессии не нужно непосредственно вмешиваться в TCP трафик, достаточно лишь определить, отвечает ли система на подмененные сегменты. Были исследованы две различные реализации протокола TCP с различными правилами обработки сегментов. В обеих реализациях на некорректные сегменты генерируется ответ, что позволяет нарушителю за несколько шагов узнать значения секретных полей сегмента. Значительная часть работы посвящена вопросу, возможно ли проведение такой атаки на практике и сколько ресурсов для этого может потребоваться. В заключении работы приводится несколько способов противодействия атаке.

Автор не ставит перед собой цель определить в работе практические ограничения для атаки. Осталось еще множество проблем для дальнейшего исследования, например в контексте ситуаций более неблагоприятных для нарушителя (низкая полоса пропускания между нарушителем и жертвой, постоянно загруженное “бутылочное горлышко”, разделяемое несколькими пользователями, различные политики постановки в очередь). Проведенные эксперименты могут послужить в качестве отправной точки для дальнейших исследований. В работе также не делается попыток провести детальное изучение эффективности атаки по отношению к распространенным реализациям протокола TCP. И наконец, работа в центр внимания ставит компрометацию TCP сессий, хотя предложенная атака может быть использована и для других случаев.

9. Благодарности

Автор хотел бы передать настоящий ACK-сегмент Войтеку Матиевичу в благодарность за рецензирование черновиков работы, ценные замечания и советы.

Ссылки

[1] J. Postel, Transmission control protocol, RFC 793, Internet Engineering Task Force, 1981, http://tools.ietf.org/html/rfc793
[2] G. Van Rooij, Real Stateful TCP Packet Filtering in IP Filter, 2001, www.usenix.org/events/sec01/invitedtalks/rooij.pdf
[3] A. Ramaiah, R. Stewart, M. Dalal, Improving TCP’s Robustness to Blind In-Window Attacks, RFC 5961, 2011, http://tools.ietf.org/html/rfc5961
[4] M. Larsen, F. Gont, Transport Protocol Port Randomization Recommendations, RFC 6056, 2011, http://tools.ietf.org/html/rfc6056
[5] F. Gont, Security Assessment of the Transmission Control Protocol, 2011 http://tools.ietf.org/ html/draft-ietf-tcpm-tcp-security-0
[6] S. Kadloor, Xun Gong, N. Kiyavash, T. Tezcan, N. Borisov. 2010, Low-Cost Side Channel Remote Traffic Analysis Attack in Packets Networks, ICCIEEE, 2010
[7] Antirez, New tcp scan method, 1998, http://seclists.org/bugtraq/1998/Dec/79
[8] klm, Blind TCP/IP hijacking is still alive, 2007, http://www.phrack.org/issues.php?issue=64&id=15
[9] S. Savage, N. Cardwell, D. Wetherall, T. Anderson, TCP Congestion Control with a Misbehaving Receiver, ACM Computer Communication Review, 29(5), October 1999
[10] A. Kumar, D. Sisalem, TCP based denial of service attacks to edge network: Analysis and detection, 2004, iptel.org/~dor/papers/Kumar1204_TCP.pdf
[11] Fyodor, Remote OS Detection, Nmap Network Scanning. http://nmap.org/book/osdetect.Html
[12] P. Watson, Slipping in the Window: TCP Reset Attacks, CanSecWest 2004 Conference
[13] M. Allman, V. Paxson, W. Stevens, TCP Congestion Control, RFC 2581, 1999, http://tools.ietf.org/html/rfc2581
[14] J. Touch, A. Mankin, R. Bonica, The TCP Authentication Option, RFC 5925, 2010, http://tools.ietf.org/html/rfc5925
[15] S. Kadloor, Xun Gong, N. Kiyavash, P. Venkitasubramaniam, Designing Privacy Preserving Router Scheduling Policies, Information Sciences and Systems (CISS), 2011
[16] Reflection Scan Proof of Concept https://github.com/wrr/reflection_scan

Где кванты и ИИ становятся искусством?

На перекрестке науки и фантазии — наш канал

Подписаться