Автор: 'Unknown' Источник: Неизвестен Возможность захвата соединения - врожденный недостаток протокола TCP/IP. Правда, сей недостаток представляет не только инструмент для проникновения в чужую сеть, но и дополнительные средства управления и мониторинга потоков IP-пакетов, и, несомненно, знание этого механизма будет нелишним. Ознакомимся с упрощенной моделью захвата соединения, оговорив начальные условия. Главным при захвате является возможность прослушивания соответствующего трафика, для чего, как мы уже говорили, требуется реализация определенных условий. Internet - это не широковещательная сеть (иначе сегодняшний трафик ее бы просто похоронил), а посему перехват чужих пакетов возможен, только когда взломщик по чистой случайности находится в одном сегменте с жертвой - раз; когда взломщик действует на уровне провайдера - два; когда подключение к трафику происходит на уровне кабельных соединений - три. Последние две ситуации -безусловно исключительные, но криминальным структурам и некоторым государственным органам они вполне по плечу. Итак, предположив, что на двух концах соединения находятся клиент и сервер, примем следующую систему обозначений: SVR_SEQ - порядковый номер очередного байта, посылаемого сервером; SVR_ACK - следующий байт, который получит сервер (порядковый номер предыдущего байта + 1); SVR_WIND - окно приема сервера; CLT_SEQ, CLT_ACK, CLT_WIND - аналогичные величины для клиента. Введем также обозначения для полей заголовка пакета TCP: SEG_SEQ - порядковый номер пакета; SEG_ACK - ожидаемый порядковый номер следующего принимаемого байта; SEG_FLAG - набор контрольных битов пакета. Перечисленные параметры связаны между собой следующим образом: всегда: CLT_ACK е SVR_SEQ е CLT_ACK+CLT_WIND и SVR_ACK е CLT_SEQ е SVR_ACK+SVR_WIND; как правило (при прямом соединении): SEG_SEQ = CLT_SEQ и SEG_ACK = CLT_ACK. Теперь предположим, что установлено соединение TCP/IP. Перед установлением соединение на стороне клиента находится в закрытом состоянии, а на стороне сервера - в состоянии ожидания. Клиент сперва посылает свой начальный порядковый номер и устанавливает бит SYN: SEQ_SEQ = CLT_SEQ_O, SEG_FLAG = SYN. Получив этот пакет, сервер подтверждает порядковый номер клиента, посылает свой собственный начальный номер и устанавливает бит SYN: SEG_SEQ = SVR_SEQ_0, SEQ_ACK = CLT_SEQ_0+1, SEG_FLAG = SYN, затем сервер задает SVR_ACK= CLT_SEQ_0+1. Получив этот пакет, клиент подтверждает порядковый номер сервера: SEG_SEQ = CLT_SEQ_0+1, SEQ_ACK = SVR_SEQ_0+1, и устанавливает CLT_ACK = SVR_SEQ_0+1, переходя в состояние установленного соединения. По получении этого пакета на стороне сервера соединение также приходит в состояние "установлено". В итоге мы имеем: CLT_SEQ = CLT_SEQ_0+1 CLT_ACK = SVR_SEQ_0+1 SVR_SEQ = SVR_SEQ_0+1 SVR_ACK = CLT_SEQ_0+1 из чего следует, что SVR_SEQ=CLT_ACK и CLT_SEQ=SVR_ACK. После установления соединения пакет принимается сервером или клиентом, если его порядковый номер укладывается в интервал [XXX_ACK,XXX_ACK+XXX_WIND], где XXX - это SVR или CLT соответственно. Соединение прерывается после выставления флагов RST (получатель обрывает соединение немедленно) или FIN (получатель приступает к процедуре его постепенного закрытия). АТАКА СОЕДИНЕНИЯ Если два последних равенства перестают выполняться, то соединение (обмен данными в нашей модели отсутствует) переходит в десинхронизированное состояние. При отсутствии передачи информации такое состояние может оставаться стабильным сколь угодно долго. Если же передача начинается, то возможны две ситуации: CLT_SEQ SVR_ACK - информация принимается для дальнейшего использования, но не посылается пользователю, поскольку начало потока (под номером SVR_ACK) потеряно; CLT_SEQ > SVR_ACK + SVR_WIND или CLT_SEQ > SVR_ACK - пакет отбрасывается, а данные теряются. И в том и в другом случае обмен данными, даже если соединение не прерывается, невозможен. Предполагаемая атака основывается на приведении обоих концов соединения в десинхронизированное состояние, что прерывает обмен данными между ними, и создании пакетов, мимикрирующих под оригинальные, естественно таких, которые удовлетворяют текущему состоянию на соответствующем конце соединения. Предположим, сеанс TCP/IP десинхронизирован, а клиент продолжает слать пакеты, у которых SEG_SEQ = CLT_SEQ, а SEG_ACK = CLT_ACK. Пакеты, вследствие нарушения все тех же равенств, отбрасываются. Атакующий меняет SEG_SEQ и SEG_ACK (корректируя при этом контрольную сумму), чтобы они были равны SVR_ACK и SVR_SEG соответственно. Фактически получается, что взломщик пропускает трафик через свою машину - это дает ему возможность по своему усмотрению добавлять и удалять пакеты. Эффект таких действий описан выше. Как же атакующий добивается десинхронизации? Самый простой метод - десинхронизация при помощи пакетов с отсутствием данных. Клиент и сервер забрасываются большим количеством пакетов. Посылаемая информация не будет ими воспринята, но приведет к рассогласованию порядковых номеров на обоих концах. Если атакуемый сеанс TCP/IP допускает пересылку пакетов с информацией нулевой длины, то этот метод самый удобный, хотя его применение может повлечь за собой ряд непредсказуемых эффектов. В частности, особенно сильно проявится одно из последствий любой десинхронизации - ураган из ACK-пакетов. Суть этого стихийного явления в том, что отброшенные ACK-пакеты влекут за собой генерирование все новых и новых - процесс замыкается в петлю или, если угодно, в воронку урагана. К счастью (или же к несчастью - как хотите), поддержка TCP соотношения потерь ненулевых пакетов приводит рано или поздно к разрыву петли. Таким образом, процесс саморегулируется и поддерживает избыточный трафик на определенном уровне, не давая ему захлестнуть сеть. Наличие ACK-урагана, кстати, позволяет обнаружить чужое вмешательство в работу сети. Есть ряд более сложных и надежных (что делает их узкоприменимыми) методов. В качестве примера рассмотрим десинхронизацию на стадии установления соединения. Метод заключается в прерывании соединения со стороны сервера на ранней стадии и установлении нового соединения. Взломщик "высматривает" пакет SYN/ACK, идущий от сервера к клиенту (второй этап установления соединения). Обнаружив этот пакет, он посылает серверу пакет с флагом RST, затем пакет, аналогичный перехваченному по параметрам (порт TCP), но с другим номером последовательности, в дальнейшем обозначаемым как ATK_ACK_0. Получив RST-пакет, сервер прерывает первое соединение. Получив следом от атакующего SYN-пакет, он, используя тот же самый порт, откроет новое соединение c измененным номером последовательности (SVR_SEQ_0") и пошлет клиенту пакет SYN/ACK. Определив это, атакующий посылает ему свой ACK-пакет и тем самым переводит сервер в состояние установленного соединения. Клиент, получив пакет от сервера, также переходит в состояние установленного соединения. Очевидно, что основные равенства не выполняются, и соединение оказывается изначально десинхронизированным. Главная сложность такого метода - правильный выбор атакующим поддельного номера последовательности. Если разногласие в номерах последовательности позволит серверу осуществлять прием пакетов от клиента (первый вариант десинхронизации), то вполне вероятны нежелательные побочные эффекты.