public void SendWpadFile(Packet packet) { lock (locker) { if (packet is EthernetPacket) { EthernetPacket ethPacket = packet as EthernetPacket; IPv6Packet ipv6Source = (IPv6Packet)packet.PayloadPacket; if (ipv6Source.PayloadPacket is PacketDotNet.TcpPacket) { TcpPacket tcp = ipv6Source.PayloadPacket as TcpPacket; string element = string.Format("{0}/{1}", tcp.SequenceNumber, tcp.AcknowledgmentNumber); ushort destPort = tcp.SourcePort; ushort sourcePort = tcp.DestinationPort; IPAddress destAddress = ipv6Source.SourceAddress; IPAddress sourceAddress = ipv6Source.DestinationAddress; PhysicalAddress sourceMac = Program.CurrentProject.data.GetDevice().MacAddress; PhysicalAddress destMac = ethPacket.SourceHwAddress; tcp.SourcePort = sourcePort; tcp.DestinationPort = destPort; if (tcp.Syn && !tcp.Ack && !tcp.Rst && tcp.PayloadData.Length == 0 && sourcePort == 80) { tcp.Ack = true; tcp.AcknowledgmentNumber = tcp.SequenceNumber + 1; tcp.SequenceNumber = tcp.SequenceNumber + 38; tcp.WindowSize = 14600; IPv6Packet ipv6Ack = new IPv6Packet(sourceAddress, destAddress); ipv6Ack.PayloadPacket = tcp; EthernetPacket eth = new EthernetPacket(sourceMac, destMac, EthernetPacketType.IpV6); eth.PayloadPacket = ipv6Ack; (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum(); Program.CurrentProject.data.SendPacket(eth); } else if (!tcp.Syn && tcp.Ack && tcp.PayloadData != null && !tcp.Rst && tcp.PayloadData.Length > 0 && sourcePort == 80) { if (Data.Data.WpadReqList.Contains(element)) return; Data.Data.WpadReqList.Add(element); HttpPacket http = new HttpPacket(((TcpPacket)(packet.PayloadPacket.PayloadPacket)).PayloadData); if (http.FullUrlRequest.Contains("wpad.dat")) { tcp.Psh = true; tcp.Fin = true; tcp.Ack = true; tcp.SequenceNumber = (ipv6Source.PayloadPacket as TcpPacket).AcknowledgmentNumber; tcp.AcknowledgmentNumber = tcp.SequenceNumber; string jsFunction = string.Format("function FindProxyForURL(url, host){{return \"PROXY [{0}]:{1}\";}}", ipv6Source.DestinationAddress.ToString(), proxyPort); string htmlHeader = string.Format("HTTP/1.1 200 OK\r\nContent-Type: application/x-ns-proxy-autoconfig\r\nContent-Length: {0}\r\n\r\n", jsFunction.Length); tcp.PayloadData = System.Text.Encoding.UTF8.GetBytes(string.Concat(htmlHeader, jsFunction)); EthernetPacket eth = new EthernetPacket(ethPacket.DestinationHwAddress, ethPacket.SourceHwAddress, EthernetPacketType.IpV6); IPv6Packet ip6 = new IPv6Packet(ipv6Source.DestinationAddress, ipv6Source.SourceAddress); ip6.PayloadPacket = tcp; eth.PayloadPacket = ip6; (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum(); Program.CurrentProject.data.SendPacket(eth); } } else if (tcp.Fin && tcp.Ack && !tcp.Rst && tcp.PayloadData.Length == 0) { tcp.Ack = true; tcp.Fin = false; uint ackOrg = tcp.AcknowledgmentNumber; tcp.AcknowledgmentNumber = tcp.SequenceNumber + 1; tcp.SequenceNumber = ackOrg; tcp.WindowSize = 1400; IPv6Packet ipv6Ack = new IPv6Packet(sourceAddress, destAddress); ipv6Ack.PayloadPacket = tcp; EthernetPacket eth = new EthernetPacket(sourceMac, destMac, EthernetPacketType.IpV6); eth.PayloadPacket = ipv6Ack; (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum(); Program.CurrentProject.data.SendPacket(eth); } } } } }
private void Ipv6ToIpv4(EthernetPacket orgPacket) { try { IPv6Packet ipv6 = (IPv6Packet)orgPacket.PayloadPacket; if (ipv6.PayloadPacket is PacketDotNet.ICMPv6Packet) { ICMPv6Packet icmp = ipv6.PayloadPacket as ICMPv6Packet; icmp.Type = ICMPv6Types.EchoReply; icmp.UpdateCalculatedValues(); icmp.Checksum = (ushort)ChecksumUtils.OnesComplementSum(icmp.Bytes); IPv6Packet ipv6Ack = new IPv6Packet(ipv6.DestinationAddress, ipv6.SourceAddress); ipv6Ack.PayloadPacket = icmp; EthernetPacket eth = new EthernetPacket(orgPacket.DestinationHwAddress, orgPacket.SourceHwAddress, EthernetPacketType.IpV6); eth.PayloadPacket = ipv6Ack; Program.CurrentProject.data.SendPacket(eth); } else if (ipv6.PayloadPacket is PacketDotNet.TcpPacket) { TcpPacket tcp = ipv6.PayloadPacket as TcpPacket; ushort destPort = tcp.SourcePort; ushort sourcePort = tcp.DestinationPort; IPAddress destAddress = ipv6.SourceAddress; IPAddress sourceAddress = ipv6.DestinationAddress; PhysicalAddress sourceMac = device.MacAddress; PhysicalAddress destMac = orgPacket.SourceHwAddress; tcp.SourcePort = sourcePort; tcp.DestinationPort = destPort; if (tcp.Syn && !tcp.Ack && !tcp.Rst && tcp.PayloadData.Length == 0) { if (sourcePort == 80) { tcp.Ack = true; tcp.AcknowledgmentNumber = tcp.SequenceNumber + 1; tcp.SequenceNumber = tcp.SequenceNumber + 38; tcp.WindowSize = 14600; IPv6Packet ipv6Ack = new IPv6Packet(sourceAddress, destAddress); ipv6Ack.PayloadPacket = tcp; EthernetPacket eth = new EthernetPacket(sourceMac, destMac, EthernetPacketType.IpV6); eth.PayloadPacket = ipv6Ack; (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum(); Program.CurrentProject.data.SendPacket(eth); } else if (sourcePort == 443) { tcp.Syn = false; tcp.Ack = true; tcp.Rst = true; tcp.Psh = false; uint ackOrg = tcp.AcknowledgmentNumber; tcp.AcknowledgmentNumber = tcp.SequenceNumber + 1; tcp.SequenceNumber = 0; tcp.WindowSize = 0; tcp.PayloadData = new byte[0]; IPv6Packet ipv6Ack = new IPv6Packet(sourceAddress, destAddress); ipv6Ack.PayloadPacket = tcp; EthernetPacket eth = new EthernetPacket(sourceMac, destMac, EthernetPacketType.IpV6); eth.PayloadPacket = ipv6Ack; (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum(); Program.CurrentProject.data.SendPacket(eth); } } else if (!tcp.Syn && tcp.Ack && tcp.PayloadData != null && !tcp.Rst && tcp.PayloadData.Length > 0 && sourcePort == 80) { string element = string.Format("{0}/{1}", tcp.SequenceNumber, tcp.AcknowledgmentNumber); if (!Data.Data.SlaacReqList.Contains(element)) { Data.Data.SlaacReqList.Add(element); HttpPacket httpReq = new HttpPacket(tcp.PayloadData); if (httpReq.IsCompleted) { SendHttpResponse(httpReq, orgPacket, tcp.SourcePort, tcp.DestinationPort, tcp.AcknowledgmentNumber, tcp.SequenceNumber + (uint)tcp.PayloadData.Length); } else { lock (htppLock) { //incomplete packet TcpReconstructorPacket previousPacket = (from p in Program.CurrentProject.data.ReconstructedPackets where p.ExpectedSequenceNumber == tcp.SequenceNumber select p).FirstOrDefault(); TcpReconstructorPacket nextPacket = (from p in Program.CurrentProject.data.ReconstructedPackets where p.FirstSequenceNumber == tcp.SequenceNumber + tcp.PayloadData.Length select p).FirstOrDefault(); if (nextPacket != null || previousPacket != null) { bool packetSend = false; if (nextPacket != null) { nextPacket.InsertPreviousTcpPacket(tcp); httpReq = new HttpPacket(nextPacket.Data); if (httpReq.IsCompleted) { packetSend = true; Program.CurrentProject.data.ReconstructedPackets.Remove(nextPacket); SendHttpResponse(httpReq, orgPacket, tcp.SourcePort, tcp.DestinationPort, tcp.AcknowledgmentNumber, nextPacket.ExpectedSequenceNumber); } } if (previousPacket != null && !packetSend) { if (nextPacket != null) { previousPacket.AppendTcpPacket(nextPacket); Program.CurrentProject.data.ReconstructedPackets.Remove(nextPacket); } else previousPacket.AppendTcpPacket(tcp); httpReq = new HttpPacket(previousPacket.Data); if (httpReq.IsCompleted) { Program.CurrentProject.data.ReconstructedPackets.Remove(previousPacket); SendHttpResponse(httpReq, orgPacket, tcp.SourcePort, tcp.DestinationPort, tcp.AcknowledgmentNumber, previousPacket.ExpectedSequenceNumber); } } } else { Program.CurrentProject.data.ReconstructedPackets.Add(new TcpReconstructorPacket(tcp)); } var toDelete = Program.CurrentProject.data.ReconstructedPackets.Where(p => DateTime.Now.Subtract(p.CreationTime).TotalMinutes > 2); foreach (var item in toDelete) { Program.CurrentProject.data.ReconstructedPackets.Remove(item); } } } } } else if (tcp.Fin && tcp.Ack && !tcp.Rst && tcp.PayloadData.Length == 0) { tcp.Ack = true; tcp.Fin = false; uint ackOrg = tcp.AcknowledgmentNumber; tcp.AcknowledgmentNumber = tcp.SequenceNumber + 1; tcp.SequenceNumber = ackOrg; tcp.WindowSize = 1400; IPv6Packet ipv6Ack = new IPv6Packet(sourceAddress, destAddress); ipv6Ack.PayloadPacket = tcp; EthernetPacket eth = new EthernetPacket(sourceMac, destMac, EthernetPacketType.IpV6); eth.PayloadPacket = ipv6Ack; (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum(); Program.CurrentProject.data.SendPacket(eth); } } } catch { } }
private void SendHttpResponse(HttpPacket httpReq, EthernetPacket orgEthPacket, ushort sourcePort, ushort destinationPort, uint ackNumber, uint expectedSeqNumber) { IPv6Packet ipv6 = (IPv6Packet)orgEthPacket.PayloadPacket; TcpPacket tcp = new TcpPacket(sourcePort, destinationPort); IPAddress destAddress = ipv6.SourceAddress; IPAddress sourceAddress = ipv6.DestinationAddress; PhysicalAddress sourceMac = device.MacAddress; PhysicalAddress destMac = orgEthPacket.SourceHwAddress; string urlRequest = string.IsNullOrEmpty(httpReq.Host) ? string.Format("http://{0}{1}", Ipv6To4Addr(ipv6.DestinationAddress.ToString()), httpReq.ResourceRequest) : httpReq.FullUrlRequest; bool validRequest = false; HttpWebRequest req = null; HttpWebResponse response = null; IPv6Packet ipv6Ack = null; EthernetPacket eth = null; CookieContainer lastCookies = httpReq.Cookies; string userAgent = httpReq.UserAgent; int repeatRedirect = 0; //Fix no Google's javascript redirect if (httpReq.Host.Contains("google") && httpReq.FullUrlRequest.Contains("/xjs/_/js/")) validRequest = true; while (!validRequest) { req = HttpWebRequest.Create(urlRequest) as HttpWebRequest; req.Host = req.Address.Host; req.UserAgent = userAgent; req.Method = httpReq.Method; //req.Accept = httpReq.Accept; req.Headers[HttpRequestHeader.AcceptLanguage] = httpReq.AcceptLanguage; req.Referer = httpReq.Referer; req.AllowAutoRedirect = false; if (lastCookies == null) lastCookies = new CookieContainer(); req.CookieContainer = lastCookies; if (httpReq.Method.ToLower() == "post" && httpReq.Data != null) { req.ContentType = httpReq.ContentType; req.ContentLength = httpReq.Data.Length; using (Stream dataStream = req.GetRequestStream()) { using (BinaryWriter writer = new BinaryWriter(dataStream)) { writer.Write(httpReq.Data); } } } try { response = req.GetResponse() as HttpWebResponse; if ((response.StatusCode == HttpStatusCode.Found || response.StatusCode == HttpStatusCode.Moved) && response.Headers[HttpResponseHeader.Location].StartsWith("https")) throw new WebException("302", null, WebExceptionStatus.UnknownError, response); else validRequest = true; } catch (WebException ex404) { if (ex404.Message.Contains("404") && ex404.Response != null) { if ((ex404.Response as HttpWebResponse) != null) response = (ex404.Response as HttpWebResponse); validRequest = true; } else if (ex404.Message.Contains("403") && ex404.Response.ResponseUri.AbsoluteUri.StartsWith("http:")) { validRequest = false; urlRequest = string.Format("https{0}", ex404.Response.ResponseUri.AbsoluteUri.Substring(4)); if (!string.IsNullOrEmpty(ex404.Response.Headers[HttpResponseHeader.SetCookie])) { CookieCollection col = HttpPacket.ParseSetCookies(ex404.Response.Headers[HttpResponseHeader.SetCookie]); if (col.Count > 0) { if (!string.IsNullOrEmpty(col[0].Domain)) { string domain = col[0].Domain; if (domain.StartsWith(".")) domain = domain.Remove(0, 1); lastCookies.Add(new Uri(string.Format("http://{0}", domain)), col); } else lastCookies.Add(ex404.Response.ResponseUri, col); } } } else if (ex404.Message.Contains("302")) { if (repeatRedirect < REDIRECTCOUNT) { validRequest = false; urlRequest = ex404.Response.Headers[HttpResponseHeader.Location]; if (!string.IsNullOrEmpty(ex404.Response.Headers[HttpResponseHeader.SetCookie])) { CookieCollection col = HttpPacket.ParseSetCookies(ex404.Response.Headers[HttpResponseHeader.SetCookie]); if (col.Count > 0) { if (!string.IsNullOrEmpty(col[0].Domain)) { string domain = col[0].Domain; if (domain.StartsWith(".")) domain = domain.Remove(0, 1); if (urlRequest.StartsWith("https")) lastCookies.Add(new Uri(string.Format("https://{0}", domain)), col); else lastCookies.Add(new Uri(string.Format("http://{0}", domain)), col); } else lastCookies.Add(ex404.Response.ResponseUri, col); } } repeatRedirect++; } else { validRequest = true; response = null; } } else { validRequest = true; } } catch (Exception) { } } int previousLength = 0; uint ackValue = expectedSeqNumber; uint sequence = ackNumber; if (response != null) { try { foreach (var item in response.GetBytes(1300)) { tcp.Psh = false; tcp.Fin = false; tcp.Ack = true; tcp.AcknowledgmentNumber = ackValue; tcp.SequenceNumber = sequence + (uint)previousLength; sequence = tcp.SequenceNumber; previousLength = item.Length; tcp.WindowSize = 1600; tcp.PayloadData = item; ipv6Ack = new IPv6Packet(sourceAddress, destAddress); ipv6Ack.PayloadPacket = tcp; eth = new EthernetPacket(sourceMac, destMac, EthernetPacketType.IpV6); eth.PayloadPacket = ipv6Ack; (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum(); Program.CurrentProject.data.SendPacket(eth); } } catch (Exception e) { e.ToString(); } tcp.Psh = true; tcp.Fin = true; tcp.Ack = true; tcp.AcknowledgmentNumber = ackValue; tcp.SequenceNumber = sequence + (uint)previousLength; tcp.WindowSize = 1600; tcp.PayloadData = new byte[0]; ipv6Ack = new IPv6Packet(sourceAddress, destAddress); ipv6Ack.PayloadPacket = tcp; eth = new EthernetPacket(sourceMac, destMac, EthernetPacketType.IpV6); eth.PayloadPacket = ipv6Ack; (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum(); Program.CurrentProject.data.SendPacket(eth); } else { tcp.Psh = true; tcp.Fin = true; tcp.Ack = true; tcp.AcknowledgmentNumber = ackValue; tcp.SequenceNumber = sequence + (uint)previousLength; tcp.WindowSize = 1600; tcp.PayloadData = HttpPacket.Get404Packet(); ipv6Ack = new IPv6Packet(sourceAddress, destAddress); ipv6Ack.PayloadPacket = tcp; eth = new EthernetPacket(sourceMac, destMac, EthernetPacketType.IpV6); eth.PayloadPacket = ipv6Ack; (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum(); Program.CurrentProject.data.SendPacket(eth); } }
public static IEnumerable <byte[]> GetBytes(this HttpWebResponse response, int maxLength) { using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(ms)) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("HTTP/{0} {1} {2} \r\n", response.ProtocolVersion, (int)response.StatusCode, response.StatusDescription))); if (response.Headers[HttpResponseHeader.Location] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("Location: {0}\r\n", response.Headers[HttpResponseHeader.Location].Replace("https", "http")))); } if (response.Headers[HttpResponseHeader.ContentType] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("Content-Type: {0}\r\n", response.Headers[HttpResponseHeader.ContentType]))); } if (response.Headers[HttpResponseHeader.Connection] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("Connection: {0}\r\n", response.Headers[HttpResponseHeader.Connection]))); } else if (response.Headers[HttpResponseHeader.KeepAlive] != null) { response.Headers[HttpResponseHeader.KeepAlive].ToString(); } if (response.Headers[HttpResponseHeader.Date] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("Date: {0}\r\n", response.Headers[HttpResponseHeader.Date]))); } if (response.Headers[HttpResponseHeader.Allow] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("Allow: {0}\r\n", response.Headers[HttpResponseHeader.Allow]))); } if (response.Headers[HttpResponseHeader.CacheControl] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("Cache-Control: {0}\r\n", response.Headers[HttpResponseHeader.CacheControl]))); } if (response.Headers["P3P"] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("P3P: {0}\r\n", response.Headers["P3P"]))); } if (response.Headers[HttpResponseHeader.Vary] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("Vary: {0}\r\n", response.Headers[HttpResponseHeader.Vary]))); } if (response.Headers[HttpResponseHeader.Expires] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("Expires: {0}\r\n", response.Headers[HttpResponseHeader.Expires]))); } if (response.Headers[HttpResponseHeader.Server] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("Server: {0}\r\n", response.Headers[HttpResponseHeader.Server]))); } if (response.Headers[HttpResponseHeader.ContentEncoding] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("Content-Encoding: {0}\r\n", response.Headers[HttpResponseHeader.ContentEncoding]))); } if (response.Headers[HttpResponseHeader.ContentLanguage] != null) { writer.Write(System.Text.Encoding.ASCII.GetBytes(string.Format("Content-Language: {0}\r\n", response.Headers[HttpResponseHeader.ContentLanguage]))); } if (response.Headers[HttpResponseHeader.TransferEncoding] != null && response.Headers[HttpResponseHeader.TransferEncoding].Contains("chunked") && response.Headers[HttpResponseHeader.Connection] == null) { writer.Write(System.Text.Encoding.ASCII.GetBytes("Connection: close\r\n")); } if (response.Headers[HttpResponseHeader.SetCookie] != null) { CookieCollection cookieCol = HttpPacket.ParseSetCookies(response.Headers[HttpResponseHeader.SetCookie]); foreach (Cookie item in cookieCol) { writer.Write(System.Text.Encoding.ASCII.GetBytes(HttpPacket.CookieToSetCookieHeader(item))); } } writer.Write(System.Text.Encoding.ASCII.GetBytes("\r\n")); } using (MemoryStream headerStream = new MemoryStream(ms.ToArray())) { using (BinaryReader reader = new BinaryReader(headerStream)) { while (reader.BaseStream.Position < reader.BaseStream.Length) { yield return(reader.ReadBytes(maxLength)); } } } } using (BinaryReader reader = new BinaryReader(response.GetResponseStream())) { int bytesRead; byte[] buffer = new byte[maxLength]; Encoding responseEncoding = null; while ((bytesRead = reader.Read(buffer, 0, buffer.Length)) > 0) { Array.Resize(ref buffer, bytesRead); if (response.ContentType.ToLower().Contains("html") || response.ContentType.ToLower().Contains("javascript") || response.ContentType.ToLower().Contains("json")) { if (responseEncoding == null) { responseEncoding = GetResponseEncoding(response.CharacterSet); } string htmlContent = responseEncoding.GetString(buffer); htmlContent = htmlContent.Replace("https", "http").Replace("Https", "http"); byte[] htmlBytes = responseEncoding.GetBytes(htmlContent); yield return(htmlBytes); } else { yield return(buffer); } buffer = new byte[maxLength]; } } }