This is a mirror of official site: http://jasper-net.blogspot.com/

Уязвимости серверов к медленному чтению

| Wednesday, January 11, 2012
Приветствую.
Хочу рассказать, чем я баловался в свободное от работы в Qualys время. Так как в англоязычном интернете на удивление много шума про Slow Read DoS attack, и уверен что получу здесь много полезной критики и дельных предложений.

В августе 2011 года написал програмку slowhttptest, которая тестирует веб-серверы на наличие уязвимостей, связанных с обработкой медленных HTTP запросов, таких как slowloris и slow HTTP Post. Цель — создать конфигурируемый инструмент, облегчающий работу разработчиков и позволить им концентрироваться на создании эффективных защит, а не ковырянии в питоне, на котором написаны большинство proof-of-concept эксплоитов.

А потом решил попробовать, как реагируют серверы на медленное чтение клиентами HTTP респонсов. На удивление плохо реагируют. Дефолтные apache, nginx, lightpd, IIS отказывают в обслуживании на ура.

А суть такова:

если найти ресурс на веб сервере, который размером больше send buffer-a, который ядро выделило для соединения, в который серверная программа пошлет ресурс, то если каким то образом вынудить ядро не принимать все данные — сервер будет пытаться послать оставшийся кусок данных, занимая ограниченную в размере очередь соединений, процессорное время, память, и свободное время сисадмина. Если забить такими соединяниями всю очередь — сервер, соответственно начнет отказывать в обслуживании быстрым клиентам.

Заставить ядро себя так вести довольно просто и описано было еще в 2008 году ребятами из Outpost24 в методе Sockstress: например, посылать в TCP пакете размер окна равным 0, т.е. у клиента нет места для приема данных. Дизайн TCP правильно подразумевает, что приложение, а не ядро обязано контролировать медленные и мертвые соеднинения. Однако за 4 года никто не пошевелил пальцем.

Sockstress вручную создает пакеты, высчитывает, когда послать очередное подтверждение, чтоб не ресетнуть persist timer на сервере, сложно короче.
Мой метод даже школьник в состоянии реализовать на практике:
Создаете сокет, задаете сравнительно малый размер receive buffer-а на клиенте, посылаете совершенно целостный и нормальный HTTP запрос на картинку размером 100Кб, например. Сервер берет картинку из памяти, дает ядру, чтоб тот передал ее в сеть. Сервер берет кусок картинки и шлет, клиент принимает первые тыщу байт, и говорит стоп, места нету. Сервер poll-ает сокет, пытаясь понять когда он будет готов к записи, а он не готов! Раз в минуту читаете пару байтов из клиентского receive buffer, чтоб TCP стек послал что то отличное от нуля, тем самым создав видимость живого соедниения для файрволов и IDS-ов.

Read more: Habrahabr.ru
QR: #habracut

Posted via email from Jasper-net

0 comments: