Сокеты 2 (Кодинг блокирующих сокетов)Delphi , Интернет и Сети , СокетыСокеты 2 (Кодинг блокирующих сокетов)
Простейший клиент Рассмотрим пример простейшего SMTP-клиента, отсылающего в скрытом режиме некоторую информацию на указанный e-mail. Пример возьмем из моей статьи Troyan #1. Используется блокирующий сокет. Рассмотрим более подробно немного измененный кусок на Delphi, отвечающий за инициализацию и соединение с SMTP-сервером:
Отправка данных Как уже говорилось в первой статье, send - это неблокирующая операция. Здесь есть небольшие грабли. Если нам необходимо отправить кусок данных ОПРЕДЕЛЕННОГО размера, то send может мгновенно положить в очередь кусок данных (сколько сможет), а остальное из-за неблокирующего режима просто не успеть отправить, перейдя на выполнение следующего кода. Т.к. эта функция возвращает количество отправленных байт, то можно написать функцию доотправки данных. Вот исходники на Delphi:
А вот исходники на MASM:
Также пишется и функции отправки данных. Только вместо send - recv. Только recv может работать на синхронном или асинхронном сокете или на сервере. Для клиента на блоктрующем сокете - все один к одному. Для неблокирующего сокета и сервера на блокирующем - см. ниже. Клиент на асинхронном сокетном движке Рассмотрим другую мою статью Взлом e-mail #1. Для создания сокетного движка использовались блокирующие сокеты и определенное количество отдельно работающих процессов. Каждый процесс содержал сокет. Еще один пример сокетного движка в асинхронном режиме можно посмотреть в моей программе "DScan v.1.2". Побольшому счету, эти два примера отличаются только созданием процессов работы с сокетами. Такой сокетный движок имеет свои преимущества по сравнению с неблокирующим режимом и свои недостатки. Преимущества в том, что оператор select вызывается в блокирующем режиме самой системой и нет постоянного цикла опроса, загружающего процессор. Плюс то, что все процессы работают отдельно и при возникновении какой-либо ошибки, процесс, в котором произошла ошибка, просто останавливается с последующим освобождением занятой им памяти. Остальные при этом продолжают работать. Как уже говорилось в первой статье, этот способ (по моему мнению) идеально подходит для DiulUp и не очень широкого канала при выделенке. Для очень хорошего канала и с очень большим количеством процессов, такой сокетный движок будет очень загружать ядро системы. Особенно это неприемлимо для win-9x/me, где отвратительно сделана многозадачность, распределение памяти, синхронизация и "синий экран" при многопоточных приложениях - обычное дело. Простейший сервер Рассмотрим пример простейшего сервера на MASM (почему на MASM - смотри мои статьи по BackDoor). Используется блокирующий сокет, с реакцией на соединение, получение данных от клиента и разрыв связи. Реакция на эти действия производится в функции обработки оконных сообщений, которую мы связываем с сокетом функцией WSAAsyncSelect (см. первую статью). Этот наш сервер будет реагировать на соединение и получение данных от клиента тем, что будет отвечать строкой 'hello'. Вот исходники на MASM:
Компилим, запускаем. Должно появиться маленькое окно. Теперь можно написать клиент или просто соединиться TelNet-ом на 10001 порт. Сервер при соединении и посылке ему любых данных, будет слать обратно строку "Hello". Можно этот код переписать на Delphi или C - все используемые функции из ядра виндов. Отличается только синтаксис. Также следует отметить, что принцип действия всех серверов и в никсах и в виндах примерно одинаков. Поняв принцип работы одного - примерно понимаешь принцип работы всех. "Грабли" сервера Мы примерно поняли принцип работы серверов. Теперь рассмотрим наиболее распространенные ошибки при написании этих самых серверов. Серверу надо принять столько данных, сколько мы ему послали. Так как принимает сервер их частями и в функции реакции на прием данных в рассмотренном выше примере их нельзя как-то докачать (после срабатывания FD_READ, recv для докачки не может получить из стека остальные данные потому, что еще не была вызвана функция получения сообщения от винды и доступ к очереди сокета закрыт). Значит необходимо хранить где-то все сокетные соединения и часть уже пришедших на них данных и при срабатывании FD_READ, накапливать эти данные. При достижении необходимого размера или комбинации символов, соответствующих сигналу конца пакета, соответственно реагировать. Структура сервера при этом усложнится. Необходимо выбрать для себя режим работы с пакетами - по размеру или по определенной комбинации символов - признак окончания пакета. Теперь о самом главном. В виндоуз есть несколько очень уникальных WinAPI функций, которые допускают DoS. Это функции lstr..., printf и прочие. Для сервера, нас интересуют именно функции для работы со строками с нулевым символом на конце (lstr...). Например, буфер накопления данных от клиента имеет определенный размер. И сервер понимает окончание пакета, как получение от клиента куска данных этого размера. Пока не накопит - не реагирует. Можно подобрать размер отправляемых данных таким образом, что накапливаемые данные превысят размер буфера, попадут в область кода или в область других данных и произойдет выполнение определенных команд или отказ работы всего сервера. Если в конце принимаемого пакета обязательно должна стоять определенная комбинация символов, то посылая большие куски данных, не содержащие эти символы, мы также можем сделать переполнение буфера. Также можно поиздеваться над сервером, посылая данные с разными флагами (например, MSG_OOB - самый простой Nuke на 139 порт), попробовать инициализировать соединение как UDP, ICMP и т.д. и т.п. Есть целый ряд уязвимостей различных сервисов, основанных на этом принципе. В основном, это способы удаленного отказа работы сервера. Найти уязвимость, заставляющую сервер исполнять определенный кусок данных, переполнив буфер - это высший пилотаж. В следующей статье будут рассмотрены несколько самых простых примеров удаленного отказа в обслуживании. В следующей статье я рассмотрю работу с неблокирующими сокетами. Как пример, будет рассмотрена уязвимость w2k, приводящая к зависанию всей системы в целом. P.S. Статья и программы предоставлены в целях обучения и вся ответственность за использование ложится на твои хилые плечи. Сокеты 2 (Кодинг блокирующих сокетов) - Описание статьи о кодировании блокирующих сокетов, включая примеры программного кода на Delphi и MASM для создания клиента и сервера, использующих блокирующие сокеты. Комментарии и вопросыМатериалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
|
||||||||||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |