Посылка Raw IP-пакетов

Используя данный исходник можно конструировать собственные пакеты содержащие внутри всё, что угодно. Можно самостоятельно указывать в пакете IP-адрес получателя и отправителя, порт назначения и т.д. Если Вы не знаете, что это такое, то лучше не экспериментировать. 
Единственный недостаток, то, что скорее всего данный пример будет работать только в Windows 2000. Так же исходник позволяет произвести SYN flood и IP spoofing.
Необходимо зайти в систему под Администратором.
Совместимость: Delphi 5.x (или выше)
{
Raw Packet Sender
using: Delphi + Winsock 2
Copyright (c) 2000 by E.J.Molendijk (xes@dds.nl)
----------------------------------------------------------------------
Перед использованием измените значения SrcIP+SrcPort+DestIP+DestPort на нужные!
----------------------------------------------------------------------
}
unit main;
interface
uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, OleCtrls, Registry;
const
 SrcIP = '123.123.123.1';
 SrcPort = 1234;
 DestIP = '123.123.123.2';
 DestPort = 4321;
 Max_Message = 4068;
 Max_Packet = 4096;
type
 TPacketBuffer = Array[0..Max_Packet-1] of byte;
 TForm1 = class(TForm)
 Button1: TButton;
 Memo1: TMemo;
 procedure Button1Click(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 procedure SendIt;
 end;
// Заголовок IP пакета
type
 T_IP_Header = record
 ip_verlen : Byte;
 ip_tos : Byte;
 ip_totallength : Word;
 ip_id : Word;
 ip_offset : Word;
 ip_ttl : Byte;
 ip_protocol : Byte;
 ip_checksum : Word;
 ip_srcaddr : LongWord;
 ip_destaddr : LongWord;
 end;
// Заголовок UDP пакета
type
 T_UDP_Header = record
 src_portno : Word;
 dst_portno : Word;
 udp_length : Word;
 udp_checksum : Word;
 end;
// Некоторые объявления типов для Winsock 2
 u_char = Char;
 u_short = Word;
 u_int = Integer;
 u_long = Longint;
 SunB = packed record
 s_b1, s_b2, s_b3, s_b4: u_char;
 end;
 SunW = packed record
 s_w1, s_w2: u_short;
 end;
 in_addr = record
 case integer of
 0: (S_un_b: SunB);
 1: (S_un_w: SunW);
 2: (S_addr: u_long);
 end;
 TInAddr = in_addr;
 Sockaddr_in = record
 case Integer of
 0: (sin_family: u_short;
 sin_port: u_short;
 sin_addr: TInAddr;
 sin_zero: array[0..7] of Char);
 1: (sa_family: u_short;
 sa_data: array[0..13] of Char)
 end;
 TSockAddr = Sockaddr_in;
 TSocket = u_int;
const
 WSADESCRIPTION_LEN = 256;
 WSASYS_STATUS_LEN = 128;
type
 PWSAData = ^TWSAData;
 WSAData = record // !!! also WSDATA
 wVersion: Word;
 wHighVersion: Word;
 szDescription: array[0..WSADESCRIPTION_LEN] of Char;
 szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char;
 iMaxSockets: Word;
 iMaxUdpDg: Word;
 lpVendorInfo: PChar;
 end;
 TWSAData = WSAData;
// Определяем необходимые функции winsock 2
function closesocket(s: TSocket): Integer; stdcall;
function socket(af, Struct, protocol: Integer): TSocket; stdcall;
function sendto(s: TSocket; var Buf; len, flags: Integer; var addrto: TSockAddr;
 tolen: Integer): Integer; stdcall;{}
function setsockopt(s: TSocket; level, optname: Integer; optval: PChar;
 optlen: Integer): Integer; stdcall;
function inet_addr(cp: PChar): u_long; stdcall; {PInAddr;} { TInAddr }
function htons(hostshort: u_short): u_short; stdcall;
function WSAGetLastError: Integer; stdcall;
function WSAStartup(wVersionRequired: word; var WSData: TWSAData): Integer; stdcall;
function WSACleanup: Integer; stdcall;
const
 AF_INET = 2; // internetwork: UDP, TCP, etc.
 IP_HDRINCL = 2; // включаем заголовок IP пакета
 SOCK_RAW = 3; // интерфейс raw-протокола
 IPPROTO_IP = 0; // dummy for IP
 IPPROTO_TCP = 6; // tcp
 IPPROTO_UDP = 17; // user datagram protocol
 IPPROTO_RAW = 255; // raw IP пакет
 INVALID_SOCKET = TSocket(NOT(0));
 SOCKET_ERROR = -1;
var
 Form1: TForm1;
implementation
// Импортируем функции Winsock 2
const WinSocket = 'WS2_32.DLL';
function closesocket; external winsocket name 'closesocket';
function socket; external winsocket name 'socket';
function sendto; external winsocket name 'sendto';
function setsockopt; external winsocket name 'setsockopt';
function inet_addr; external winsocket name 'inet_addr';
function htons; external winsocket name 'htons';
function WSAGetLastError; external winsocket name 'WSAGetLastError';
function WSAStartup; external winsocket name 'WSAStartup';
function WSACleanup; external winsocket name 'WSACleanup';
{$R *.DFM}
//
// Function: checksum
//
// Description:
// This function calculates the 16-bit one's complement sum
// for the supplied buffer
//
function CheckSum(var Buffer; Size: Integer): Word;
type
 TWordArray = Array[0..1] of Word;
var
 ChkSum : LongWord;
 i : Integer;
begin
 ChkSum := 0;
 i := 0;
 while Size > 1 do
 begin
 ChkSum := ChkSum + TWordArray(Buffer)[i];
 Inc(i);
 Size := Size - SizeOf(Word);
 end;
 if Size = 1 then
 ChkSum := ChkSum + Byte(TWordArray(Buffer)[i]);
 ChkSum := (ChkSum shr 16) + (ChkSum and $FFFF);
 ChkSum := ChkSum + (Chksum shr 16);
 Result := Word(ChkSum);
end;
procedure BuildHeaders(
 FromIP : string;
 iFromPort : Word;
 ToIP : string;
 iToPort : Word;
 StrMessage : string;
 var Buf : TPacketBuffer;
 var remote : TSockAddr;
 var iTotalSize : Word
);
var
 dwFromIP : LongWord;
 dwToIP : LongWord;
 iIPVersion : Word;
 iIPSize : Word;
 ipHdr : T_IP_Header;
 udpHdr : T_UDP_Header;
 iUdpSize : Word;
 iUdpChecksumSize : Word;
 cksum : Word;
 Ptr : ^Byte;
 procedure IncPtr(Value: Integer);
 begin
 Ptr := Pointer(Integer(Ptr) + Value);
 end;
begin
 // преобразуем ip адреса
 dwFromIP := inet_Addr(PChar(FromIP));
 dwToIP := inet_Addr(PChar(ToIP));
 // Инициализируем заголовок IP пакета
 //
 iTotalSize := SizeOf(ipHdr) + SizeOf(udpHdr) + Length(strMessage);
 iIPVersion := 4;
 iIPSize := SizeOf(ipHdr) div SizeOf(LongWord);
 //
 // IP version goes in the high order 4 bits of ip_verlen. The
 // IP header length (in 32-bit words) goes in the lower 4 bits.
 //
 ipHdr.ip_verlen := (iIPVersion shl 4) or iIPSize;
 ipHdr.ip_tos := 0; // IP type of service
 ipHdr.ip_totallength := htons(iTotalSize); // Total packet len
 ipHdr.ip_id := 0; // Unique identifier: set to 0
 ipHdr.ip_offset := 0; // Fragment offset field
 ipHdr.ip_ttl := 128; // время жизни пакета
 ipHdr.ip_protocol := $11; // Protocol(UDP)
 ipHdr.ip_checksum := 0 ; // IP checksum
 ipHdr.ip_srcaddr := dwFromIP; // Source address
 ipHdr.ip_destaddr := dwToIP; // Destination address
 //
 // Инициализируем заголовок UDP пакета
 //
 iUdpSize := SizeOf(udpHdr) + Length(strMessage);
 udpHdr.src_portno := htons(iFromPort) ;
 udpHdr.dst_portno := htons(iToPort) ;
 udpHdr.udp_length := htons(iUdpSize) ;
 udpHdr.udp_checksum := 0 ;
 //
 // Build the UDP pseudo-header for calculating the UDP checksum.
 // The pseudo-header consists of the 32-bit source IP address,
 // the 32-bit destination IP address, a zero byte, the 8-bit
 // IP protocol field, the 16-bit UDP length, and the UDP
 // header itself along with its data (padded with a 0 if
 // the data is odd length).
 //
 iUdpChecksumSize := 0;
 ptr := @buf[0];
 FillChar(Buf, SizeOf(Buf), 0);
 Move(ipHdr.ip_srcaddr, ptr^, SizeOf(ipHdr.ip_srcaddr));
 IncPtr(SizeOf(ipHdr.ip_srcaddr));
 iUdpChecksumSize := iUdpChecksumSize + SizeOf(ipHdr.ip_srcaddr);
 Move(ipHdr.ip_destaddr, ptr^, SizeOf(ipHdr.ip_destaddr));
 IncPtr(SizeOf(ipHdr.ip_destaddr));
 iUdpChecksumSize := iUdpChecksumSize + SizeOf(ipHdr.ip_destaddr);
 IncPtr(1);
 Inc(iUdpChecksumSize);
 Move(ipHdr.ip_protocol, ptr^, SizeOf(ipHdr.ip_protocol));
 IncPtr(sizeof(ipHdr.ip_protocol));
 iUdpChecksumSize := iUdpChecksumSize + SizeOf(ipHdr.ip_protocol);
 Move(udpHdr.udp_length, ptr^, SizeOf(udpHdr.udp_length));
 IncPtr(sizeof(udpHdr.udp_length));
 iUdpChecksumSize := iUdpChecksumSize + SizeOf(udpHdr.udp_length);
 Move(udpHdr, ptr^, SizeOf(udpHdr));
 IncPtr(SizeOf(udpHdr));
 iUdpChecksumSize := iUdpCheckSumSize + SizeOf(udpHdr);
 Move(StrMessage[1], ptr^, Length(strMessage));
 IncPtr(Length(StrMessage));
 iUdpChecksumSize := iUdpChecksumSize + Length(strMessage);
 cksum := checksum(buf, iUdpChecksumSize);
 udpHdr.udp_checksum := cksum;
 //
 // Now assemble the IP and UDP headers along with the data
 // so we can send it
 //
 FillChar(Buf, SizeOf(Buf), 0);
 Ptr := @Buf[0];
 Move(ipHdr, ptr^, SizeOf(ipHdr)); IncPtr(SizeOf(ipHdr));
 Move(udpHdr, ptr^, SizeOf(udpHdr)); IncPtr(SizeOf(udpHdr));
 Move(StrMessage[1], ptr^, Length(StrMessage));
 // Apparently, this SOCKADDR_IN structure makes no difference.
 // Whatever we put as the destination IP addr in the IP header
 // is what goes. Specifying a different destination in remote
 // will be ignored.
 //
 remote.sin_family := AF_INET;
 remote.sin_port := htons(iToPort);
 remote.sin_addr.s_addr := dwToIP;
end;
procedure TForm1.SendIt;
var
 sh : TSocket;
 bOpt : Integer;
 ret : Integer;
 Buf : TPacketBuffer;
 Remote : TSockAddr;
 Local : TSockAddr;
 iTotalSize : Word;
 wsdata : TWSAdata;
begin
 // Startup Winsock 2
 ret := WSAStartup($0002, wsdata);
 if ret <> 0 then
 begin
 Memo1.Lines.Add('WSA Startup failed.');
 exit;
 end;
 with Memo1.Lines do
 begin
 Add('WSA Startup:');
 Add('Desc.: ' + wsData.szDescription);
 Add('Status: ' + wsData.szSystemStatus);
 end;
 try
 // Создаём сокет
 sh := Socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
 if (sh = INVALID_SOCKET) then
 begin
 Memo1.Lines.Add('Socket() failed: ' + IntToStr(WSAGetLastError));
 exit;
 end;
 Memo1.Lines.Add('Socket Handle = ' + IntToStr(sh));
 // Option: Header Include
 bOpt := 1;
 ret := SetSockOpt(sh, IPPROTO_IP, IP_HDRINCL, @bOpt, SizeOf(bOpt));
 if ret = SOCKET_ERROR then
 begin
 Memo1.Lines.Add('setsockopt(IP_HDRINCL) failed: ' + IntToStr(WSAGetLastError));
 exit;
 end;
 // строим пакет
 BuildHeaders( SrcIP, SrcPort,
 DestIP, DestPort,
 'THIS IS A TEST PACKET',
 Buf, Remote, iTotalSize );
 // Отправляем пакет
 ret := SendTo(sh, buf, iTotalSize, 0, Remote, SizeOf(Remote));
 if ret = SOCKET_ERROR then
 Memo1.Lines.Add('sendto() failed: ' + IntToStr(WSAGetLastError))
 else
 Memo1.Lines.Add('send ' + IntToStr(ret) + ' bytes.');
 // Закрываем сокет
 CloseSocket(sh);
 finally
 // Закрываем Winsock 2
 WSACleanup;
 end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
 SendIt;
end;
end.
Author: Erwin Molendijk
Source: http://forum.sources.ru
ID: 03548
Category:Связь
Category:Сокеты