Добро пожаловать! Это — архивная версия форумов на «Хакер.Ru». Она работает в режиме read-only.
 

Raw Socket для посылки UDP

Пользователи, просматривающие топик: none

Зашли как: Guest
Все форумы >> [Компилируемые языки] >> Raw Socket для посылки UDP
Имя
Сообщение << Старые топики   Новые топики >>
Raw Socket для посылки UDP - 2007-12-24 09:49:08.730000   
KX

Сообщений: 3
Оценки: 0
Присоединился: 2007-12-24 09:46:11.230000
Пытаюсь реализовать Raw Socket для посылки UDP на Delphi.
(к слову сказать в валяющихся в инете примерах таких сокетов допущены ошибки, примеры не рабочие).
Вроде всё получается. Формирую RAW IP сокет, формирую IP и UDP заголовки. Пакеты нормально уходят, а на получателе приходят!

Но когда пытаюсь "подделать" пакет, а именно src_addr указать не свой, а поддельный, то пакет никуда не уходит, получатель его не получает.

Подскажите в чём может быть дело. Фаерволы естественно отключены. Вообще говоря на машине, на которой подделываю заголовок, даже снифер не регистрирует исходящих пакетов. Но возможно просто снифер кривой.
Post #: 1
RE: Raw Socket для посылки UDP - 2007-12-25 07:09:13.966666   
Alaget

Сообщений: 330
Оценки: 0
Присоединился: 2007-11-08 15:57:53.170000
Я же не экстрасенс, скорей всего ты облажался, 
давай исходник, может и реабилитируешся.
Post #: 2
RE: Raw Socket для посылки UDP - 2007-12-25 08:08:45.350000   
KX

Сообщений: 3
Оценки: 0
Присоединился: 2007-12-24 09:46:11.230000
вот исходник
unit rawsocks; interface uses WinSock2,windows; procedure UDPRaw(srcip:string;srcport:word;dstip:string;dstport:word;adata:PByte;data_length:integer); implementation type ip_header=packed record version:byte; // номер версии протокола tos:byte; // тип сервиса length:word; // общая длина пакета id:word; // идентификатор пакета flags:word; // флаги ttl:byte; // Время жизни пакета proto:byte; // Протокол верхнего уровня crc:word; // CRC заголовка src_addr:cardinal; // IP- адрес отправителя dst_addr:cardinal; // IP- адрес получателя end; udp_header=packed record src_port:word; // номер порта отправителя dst_port:word; // номер порта получателя length:word; // длина датаграммы crc:word; // контрольная сумма заголовка end; pseudo_header=packed record src_addr:cardinal; // адрес отправителя dst_addr:cardinal; // адрес получателя zero:byte; //начальная установка proto:byte; // протокол length:word; // длина заголовка end; function rs_crc(buffer:Pword;length:integer):word; var crc:longword; begin crc:= 0; // Вычисление CRC while (length &gt; 1)do begin crc:=crc+buffer^;inc(buffer); length:=length-sizeof(word); end; if(length&lt;&gt;0)then crc:=crc+ PByte(buffer)^; // Закончить вычисления crc:=(crc shr 16)+(crc and $ffff); crc:=crc+(crc shr 16); //возвращаем инвертированное значение CRC result:=word(not crc); end; function rs_pseudo_crc(data:PByte;data_length:integer;src_addr:cardinal; dst_addr:cardinal;packet_length:integer;proto:byte):word; var buffer:PByte; full_length:cardinal; header_length:byte; ph:pseudo_header; p_crc:word; pdata:pByte; begin p_crc:=0; // Заполнение структуры псевдозаголовка ph.src_addr:=src_addr; ph.dst_addr:=dst_addr; ph.zero:=0; ph.proto:=proto; ph.length:=htons(packet_length); header_length:=sizeof(pseudo_header); full_length:=header_length + data_length; getmem(buffer,full_length);fillchar(buffer^,full_length,0); // Генерация псевдозаголовка move(ph,buffer^,header_length); pdata:=buffer;inc(pdata,header_length);move(data^,pdata^,data_length); // Вычисление CRC. p_crc:=rs_crc(PWord(buffer),full_length); freemem(buffer,full_length); result:=p_crc; end; function rs_init(v_major:integer;v_minor:integer):boolean; var wsadata:TWSAdata; begin result:=false; // Инициализация WinSock заданной версии if (WSAStartup(MAKEWORD(v_major, v_minor), wsadata)&lt;&gt;0)then exit; // Проверка версии WinSock if (LOBYTE(wsadata.wVersion) &lt;&gt; v_minor)or(HIBYTE(wsadata.wVersion) &lt;&gt; v_major)then begin WSACleanup; exit; end; result:=true; end; function rs_send_ip (s:TSocket;iph:ip_header;data:Pbyte; data_length:integer;dst_port_raw:word):integer; var buffer:PByte; target:TSockAddrIn ; header_length:byte; packet_length:cardinal; pdata:PByte; begin fillchar(target,sizeof(target),0); target.sin_family:=AF_INET; target.sin_addr.s_addr:=iph.dst_addr; target.sin_port:=dst_port_raw; // Вычисление длины и заголовка пакета header_length:=sizeof(ip_header); packet_length:=header_length+data_length; // Установка CRC. iph.crc:=0; // Заполнение некоторых полей заголовка IP . iph.version:=4*16+trunc(header_length/4); // Если длина пакета не задана , то //длина пакета приравнивается к длине заголовка if (iph.length=0)then iph.length:=htons(packet_length); getmem(buffer,packet_length);fillchar(buffer^,packet_length,0); // Копирование заголовка пакета в буфер ( CRC равно 0). move(iph,buffer^,sizeof(ip_header)); // Копирование данных в буфер if(data&lt;&gt;nil)then begin pdata:=buffer;inc(pdata,header_length);move(data^,pdata^,data_length); end; // Вычисление CRC. iph.crc:=rs_crc(PWord(buffer),packet_length); // Копирование заголовка пакета в буфер ( CRC посчитана). move(iph,buffer^,sizeof(ip_header)); // Отправка IP пакета в сеть. result:=sendto(s,buffer^,packet_length,0,target,sizeof(target)); freemem(buffer,packet_length); end; function rs_send_udp (s:TSocket;iph:ip_header;udph:udp_header; data:Pbyte;data_length:integer):integer; var buffer:PByte; header_length:byte; packet_length:cardinal; pdata:PByte; begin //вычисление длин пакета и заголовка. header_length:=sizeof(udp_header); packet_length:=header_length+data_length; // Установка CRC. udph.crc:=0; // Если длина пакета не задана , то //длина пакета приравнивается к длине заголовка if(udph.length=0)then udph.length:=htons(packet_length); getmem(buffer,packet_length);fillchar(buffer^,packet_length,0); // Копирование заголовка пакета в буфер ( CRC равно 0). move(udph,buffer^,sizeof(udp_header)); // Копирование протокола более высокого уровня (данных) if (data&lt;&gt;nil)then begin pdata:=buffer;inc(pdata,header_length);move(data^,pdata^,data_length); end; // Вычисление CRC. udph.crc:=rs_pseudo_crc(buffer,packet_length,iph.src_addr, iph.dst_addr,packet_length,IPPROTO_UDP); // Копирование заголовка пакета в буфер ( CRC посчитана). move(udph,buffer^,sizeof(udp_header)); // Отправка IP пакета со вложенным UDP пакетом. result:=rs_send_ip(s,iph,buffer,packet_length,udph.dst_port); freemem(buffer,packet_length); end; procedure UDPRaw(srcip:string;srcport:word;dstip:string;dstport:word;adata:PByte;data_length:integer); var iph:ip_header; udph:udp_header; s:TSocket; tos:integer; use_own_header:cardinal; begin //заполняем заголовок UDP пакета iph.version:=$04; iph.length:=0;//если в 0, то посчитается автоматом далее iph.id:=0; iph.ttl:=15; iph.flags:=0; iph.src_addr:=inet_addr(PChar(srcip)); iph.dst_addr:=inet_addr(PChar(dstip)); // Создание пустого буфера для данных. s:= WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,nil,0,WSA_FLAG_OVERLAPPED); tos:=0; setsockopt(s,IPPROTO_IP,3,PChar(@tos),sizeof(tos)); use_own_header:=1; setsockopt(s,IPPROTO_IP,2,PChar(@use_own_header),sizeof(use_own_header)); iph.proto:=IPPROTO_UDP; udph.src_port:=srcport; udph.dst_port:=dstport; //отправляем UDP пакет if(data_length&gt;0)then rs_send_udp (s, iph, udph, adata, data_length) else rs_send_udp (s, iph, udph, nil, 0); closesocket(s); end; end.
но когда в качестве исходящего адреса ставлю свой - всё уходит.
тестил в ethernet сети.
мне кажется дело не в коде, а в том, что нужно например ещё подменять мак, или ещё что то не учёл.
Post #: 3
RE: Raw Socket для посылки UDP - 2007-12-26 13:35:18.183333   
necrostaz

Сообщений: 172
Оценки: 0
Присоединился: 2007-02-27 15:54:59.460000
если стоит XP SP 2 или что-нить постарше, то подделать src_addr не получится, т.к. они эту лавочку в сырых сокетах прикрыли чтоб пресечь Ip-spoof на корню….так что сырые сокеты в винде не такие уж и сырые….выход есть - юзать WinPcap или что нить подобное
Post #: 4
Страниц:  [1]
Все форумы >> [Компилируемые языки] >> Raw Socket для посылки UDP







Связаться:
Вопросы по сайту / xakep@glc.ru

Предупреждение: использование полученных знаний в противозаконных целях преследуется по закону.