Посылка Raw IP-пакетов |
Previous Top Next |
Автор: Erwin Molendijk
Используя данный исходник можно конструировать собственные пакеты содержащие внутри всё, что угодно. Можно самостоятельно указывать в пакете IP-адрес получателя и отправителя, порт назначения и т.д. Если Вы не знаете, что это такое, то лучше не эксперементировать. Единственный недостаток, то, что скорее всего данный пример будет работать только в Windows 2000. Так же исходник позволяет произвести SYN flood и IP spoofing.
Необходимо зайти в систему под Администратором.
Совместимость: Delphi 5.x (или выше)
Code: |
{ 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. |
©Drkb::03548
Взято из http://forum.sources.ru