Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="httpPacket"></param>
        /// <param name="tcpPacket"></param>
        /// <param name="sourceHost"></param>
        /// <param name="destinationHost"></param>
        /// <param name="mainPacketHandler"></param>
        /// <returns>True if the data was successfully parsed. False if the data need to be parsed again with more data</returns>
        private bool ExtractHttpData(Packets.HttpPacket httpPacket, Packets.TcpPacket tcpPacket, NetworkHost sourceHost, NetworkHost destinationHost, PacketHandler mainPacketHandler)
        {
            if (httpPacket.MessageTypeIsRequest)
            {
                //HTTP request

                System.Collections.Specialized.NameValueCollection cookieParams = null;
                if (httpPacket.UserAgentBanner != null && httpPacket.UserAgentBanner.Length > 0)
                {
                    sourceHost.AddHttpUserAgentBanner(httpPacket.UserAgentBanner);
                }
                if (httpPacket.RequestedHost != null && httpPacket.RequestedHost.Length > 0)
                {
                    destinationHost.AddHostName(httpPacket.RequestedHost);
                }
                if (httpPacket.Cookie != null)
                {
                    cookieParams = new System.Collections.Specialized.NameValueCollection();
                    char[] separators = { ';', ',' };
                    foreach (string s in httpPacket.Cookie.Split(separators))
                    {
                        string cookieFragment = s.Trim();
                        int    splitOffset    = cookieFragment.IndexOf('=');
                        if (splitOffset > 0)
                        {
                            cookieParams.Add(cookieFragment.Substring(0, splitOffset), cookieFragment.Substring(splitOffset + 1));
                        }
                        else
                        {
                            cookieParams.Add(cookieFragment, "");
                        }
                    }
                    NetworkCredential inCookieCredential = NetworkCredential.GetNetworkCredential(cookieParams, sourceHost, destinationHost, "HTTP Cookie parameter", httpPacket.ParentFrame.Timestamp);
                    if (inCookieCredential != null)
                    {
                        mainPacketHandler.AddCredential(inCookieCredential);
                    }

                    mainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(tcpPacket.ParentFrame.FrameNumber, sourceHost, destinationHost, "TCP " + tcpPacket.SourcePort, "TCP " + tcpPacket.DestinationPort, cookieParams, httpPacket.ParentFrame.Timestamp, "HTTP Cookie"));
                    NetworkCredential credential = new NetworkCredential(sourceHost, destinationHost, "HTTP Cookie", httpPacket.Cookie, "N/A", httpPacket.ParentFrame.Timestamp);
                    mainPacketHandler.AddCredential(credential);
                }
                if (httpPacket.AuthorizationCredentialsUsername != null)
                {
                    NetworkCredential nc = new NetworkCredential(sourceHost, destinationHost, httpPacket.PacketTypeDescription, httpPacket.AuthorizationCredentialsUsername, httpPacket.AuthorizationCredentialsPassword, httpPacket.ParentFrame.Timestamp);
                    mainPacketHandler.AddCredential(nc);
                    //this.AddCredential(nc);
                }
                if (httpPacket.HeaderFields != null && httpPacket.HeaderFields.Count > 0)
                {
                    SortedList <string, string> ignoredHeaderNames = new SortedList <string, string>();
                    ignoredHeaderNames.Add("accept", null);
                    ignoredHeaderNames.Add("connection", null);
                    ignoredHeaderNames.Add("accept-language", null);
                    ignoredHeaderNames.Add("accept-encoding", null);

                    //Build a sortedList of all headers
                    System.Collections.Specialized.NameValueCollection httpHeaders = new System.Collections.Specialized.NameValueCollection();
                    //SortedList<string, string> httpHeaders = new SortedList<string, string>();
                    foreach (string header in httpPacket.HeaderFields)
                    {
                        int delimiterIndex = header.IndexOf(':');
                        if (delimiterIndex > 0 && delimiterIndex < header.Length)
                        {
                            string headerName = header.Substring(0, delimiterIndex).Trim();
                            //if (!httpHeaders.ContainsKey(headerName))
                            if (!ignoredHeaderNames.ContainsKey(headerName.ToLower()))
                            {
                                httpHeaders.Add(headerName, header.Substring(delimiterIndex + 1).Trim());
                            }
                        }
                    }
                    //mainPacketHandler.OnParametersDetected
                    base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(httpPacket.ParentFrame.FrameNumber, sourceHost, destinationHost, "TCP " + tcpPacket.SourcePort, "TCP " + tcpPacket.DestinationPort, httpHeaders, httpPacket.ParentFrame.Timestamp, "HTTP Header"));

                    foreach (string headerName in httpHeaders.Keys)
                    {
                        /**
                         * http://mobiforge.com/developing/blog/useful-x-headers
                         * http://nakedsecurity.sophos.com/2012/01/25/smartphone-website-telephone-number/
                         * http://www.nowsms.com/discus/messages/485/14998.html
                         * http://coding-talk.com/f46/check-isdn-10962/
                         **/
                        if (headerName.StartsWith("X-", StringComparison.InvariantCultureIgnoreCase))
                        {
                            sourceHost.AddNumberedExtraDetail("HTTP header: " + headerName, httpHeaders[headerName]);
                        }
                        else if (headerName.StartsWith("HTTP_X", StringComparison.InvariantCultureIgnoreCase))
                        {
                            sourceHost.AddNumberedExtraDetail("HTTP header: " + headerName, httpHeaders[headerName]);
                        }
                        else if (headerName.StartsWith("X_", StringComparison.InvariantCultureIgnoreCase))
                        {
                            sourceHost.AddNumberedExtraDetail("HTTP header: " + headerName, httpHeaders[headerName]);
                        }
                        else if (headerName.StartsWith("HTTP_MSISDN", StringComparison.InvariantCultureIgnoreCase))
                        {
                            sourceHost.AddNumberedExtraDetail("HTTP header: " + headerName, httpHeaders[headerName]);
                        }
                    }
                }


                //file transfer
                if ((httpPacket.RequestMethod == Packets.HttpPacket.RequestMethods.GET || httpPacket.RequestMethod == Packets.HttpPacket.RequestMethods.POST) && httpPacket.RequestedFileName != null)
                {
                    System.Collections.Specialized.NameValueCollection queryStringData = httpPacket.GetQuerystringData();
                    if (queryStringData != null && queryStringData.Count > 0)
                    {
                        //parentForm.ShowParameters(tcpPacket.ParentFrame.FrameNumber, sourceHost, destinationHost, "TCP "+tcpPacket.SourcePort, "TCP "+tcpPacket.DestinationPort, queryStringData, tcpPacket.ParentFrame.Timestamp, "HTTP QueryString");
                        mainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(tcpPacket.ParentFrame.FrameNumber, sourceHost, destinationHost, "TCP " + tcpPacket.SourcePort, "TCP " + tcpPacket.DestinationPort, queryStringData, tcpPacket.ParentFrame.Timestamp, "HTTP QueryString"));
                        //mainPacketHandler.AddCredential(new NetworkCredential(sourceHost, destinationHost, "HTTP GET QueryString",
                        NetworkCredential credential = NetworkCredential.GetNetworkCredential(queryStringData, sourceHost, destinationHost, "HTTP GET QueryString", tcpPacket.ParentFrame.Timestamp);
                        if (credential != null)
                        {
                            mainPacketHandler.AddCredential(credential);
                        }
                        if (queryStringData.HasKeys())
                        {
                            Dictionary <string, string> queryStringDictionary = new Dictionary <string, string>();
                            foreach (string key in queryStringData.AllKeys)
                            {
                                queryStringDictionary.Add(key, queryStringData[key]);
                            }

                            if (queryStringDictionary.ContainsKey("utmsr"))
                            {
                                sourceHost.AddNumberedExtraDetail("Screen resolution (Google Analytics)", queryStringDictionary["utmsr"]);
                            }
                            if (queryStringDictionary.ContainsKey("utmsc"))
                            {
                                sourceHost.AddNumberedExtraDetail("Color depth (Google Analytics)", queryStringDictionary["utmsc"]);
                            }
                            if (queryStringDictionary.ContainsKey("utmul"))
                            {
                                sourceHost.AddNumberedExtraDetail("Browser language (Google Analytics)", queryStringDictionary["utmul"]);
                            }
                            if (queryStringDictionary.ContainsKey("utmfl"))
                            {
                                sourceHost.AddNumberedExtraDetail("Flash version (Google Analytics)", queryStringDictionary["utmfl"]);
                            }
                            if (httpPacket.RequestMethod == Packets.HttpPacket.RequestMethods.POST && queryStringDictionary.ContainsKey("a") && queryStringDictionary["a"].Equals("SendMessage"))
                            {
                                if (!httpPacket.ContentIsComplete())//we must have all the content when parsing AOL data
                                {
                                    return(false);
                                }
                            }
                        }
                    }

                    //file transfer stuff
                    string fileUri     = httpPacket.RequestedFileName;
                    string queryString = null;
                    if (fileUri.Contains("?"))
                    {
                        if (fileUri.IndexOf('?') + 1 < fileUri.Length)
                        {
                            queryString = fileUri.Substring(fileUri.IndexOf('?') + 1);
                        }
                        fileUri = fileUri.Substring(0, fileUri.IndexOf('?'));
                    }
                    if (fileUri.StartsWith("http://"))
                    {
                        fileUri = fileUri.Substring(7);
                    }
                    if (fileUri.StartsWith("www.") && fileUri.Contains("/"))
                    {
                        fileUri = fileUri.Substring(fileUri.IndexOf("/"));
                    }

                    //char[] separators={ '/' };
                    char[] separators = new char[System.IO.Path.GetInvalidPathChars().Length + 1];
                    Array.Copy(System.IO.Path.GetInvalidPathChars(), separators, System.IO.Path.GetInvalidPathChars().Length);
                    separators[separators.Length - 1] = '/';

                    string[] uriParts = fileUri.Split(separators);
                    string   filename;
                    string   fileLocation = "";

                    if (fileUri.EndsWith("/"))
                    {
                        filename = "index.html";
                        for (int i = 0; i < uriParts.Length; i++)
                        {
                            if (uriParts[i].Length > 0 && !uriParts[i].Contains(".."))
                            {
                                fileLocation += "/" + uriParts[i];
                            }
                        }
                    }
                    else
                    {
                        filename = uriParts[uriParts.Length - 1];
                        for (int i = 0; i < uriParts.Length - 1; i++)
                        {
                            if (uriParts[i].Length > 0 && !uriParts[i].Contains(".."))
                            {
                                fileLocation += "/" + uriParts[i];
                            }
                        }
                    }

                    //make sure all queryString-depending dynamic webpages are shown individually
                    if (queryString != null && queryString.Length > 0)
                    {
                        filename += "." + queryString.GetHashCode().ToString("X4");
                    }

                    //I will have to switch source and destination host here since this is only the request, not the actual file transfer!
                    try {
                        //see if there is an old assembler that needs to be removed
                        if (mainPacketHandler.FileStreamAssemblerList.ContainsAssembler(destinationHost, tcpPacket.DestinationPort, sourceHost, tcpPacket.SourcePort, true))
                        {
                            FileTransfer.FileStreamAssembler oldAssembler = mainPacketHandler.FileStreamAssemblerList.GetAssembler(destinationHost, tcpPacket.DestinationPort, sourceHost, tcpPacket.SourcePort, true);
                            mainPacketHandler.FileStreamAssemblerList.Remove(oldAssembler, true);
                        }

                        string fileDetails = httpPacket.RequestedFileName;
                        if (httpPacket.RequestedHost != null && httpPacket.RequestedHost.Length > 0 && httpPacket.RequestedFileName != null && httpPacket.RequestedFileName.StartsWith("/"))
                        {
                            fileDetails = httpPacket.RequestedHost + httpPacket.RequestedFileName;
                        }
                        FileTransfer.FileStreamAssembler assembler = new FileTransfer.FileStreamAssembler(mainPacketHandler.FileStreamAssemblerList, destinationHost, tcpPacket.DestinationPort, sourceHost, tcpPacket.SourcePort, tcpPacket != null, FileTransfer.FileStreamTypes.HttpGetNormal, filename, fileLocation, fileDetails, httpPacket.ParentFrame.FrameNumber, httpPacket.ParentFrame.Timestamp);
                        //FileTransfer.FileStreamAssembler assembler=new FileTransfer.FileStreamAssembler(mainPacketHandler.FileStreamAssemblerList, destinationHost, tcpPacket.DestinationPort, sourceHost, tcpPacket.SourcePort, tcpPacket!=null, FileTransfer.FileStreamTypes.HttpGetNormal, filename, fileLocation, httpPacket.RequestedFileName, httpPacket.ParentFrame.FrameNumber, httpPacket.ParentFrame.Timestamp);
                        mainPacketHandler.FileStreamAssemblerList.Add(assembler);
                    }
                    catch (Exception e) {
                        mainPacketHandler.OnAnomalyDetected("Error creating assembler for HTTP file transfer: " + e.Message);
                    }


                    //Large HTTP POSTs should also be dumped to files
                    //if(httpPacket.RequestMethod==Packets.HttpPacket.RequestMethods.POST && !httpPacket.ContentIsComplete() && httpPacket.ContentLength>4096 && httpPacket.ContentType.StartsWith("multipart/form-data")) {

                    if (httpPacket.RequestMethod == Packets.HttpPacket.RequestMethods.POST)
                    {
                        //All Multipart MIME HTTP POSTs should be dumped to file
                        //the fileAssembler extracts the form parameters after assembly
                        if (httpPacket.ContentType != null && httpPacket.ContentType.StartsWith("multipart/form-data"))
                        {
                            FileTransfer.FileStreamAssembler assembler = null;
                            try {
                                //see if there is an old assembler that needs to be removed
                                if (mainPacketHandler.FileStreamAssemblerList.ContainsAssembler(sourceHost, tcpPacket.SourcePort, destinationHost, tcpPacket.DestinationPort, true))
                                {
                                    FileTransfer.FileStreamAssembler oldAssembler = mainPacketHandler.FileStreamAssemblerList.GetAssembler(sourceHost, tcpPacket.SourcePort, destinationHost, tcpPacket.DestinationPort, true);
                                    mainPacketHandler.FileStreamAssemblerList.Remove(oldAssembler, true);
                                }

                                string mimeBoundary;
                                if (httpPacket.ContentType.ToLower(System.Globalization.CultureInfo.InvariantCulture).StartsWith("multipart/form-data; boundary=") && httpPacket.ContentType.Length > 30)
                                {
                                    mimeBoundary = httpPacket.ContentType.Substring(30);
                                }
                                else
                                {
                                    mimeBoundary = "";
                                }

                                assembler = new FileTransfer.FileStreamAssembler(mainPacketHandler.FileStreamAssemblerList, sourceHost, tcpPacket.SourcePort, destinationHost, tcpPacket.DestinationPort, tcpPacket != null, FileTransfer.FileStreamTypes.HttpPostMimeMultipartFormData, filename + ".form-data.mime", fileLocation, mimeBoundary, httpPacket.ParentFrame.FrameNumber, httpPacket.ParentFrame.Timestamp);
                                assembler.FileContentLength         = httpPacket.ContentLength;
                                assembler.FileSegmentRemainingBytes = httpPacket.ContentLength;
                                mainPacketHandler.FileStreamAssemblerList.Add(assembler);
                                if (assembler.TryActivate())
                                {
                                    //assembler is now active
                                    if (httpPacket.MessageBody != null && httpPacket.MessageBody.Length > 0)
                                    {
                                        assembler.AddData(httpPacket.MessageBody, tcpPacket.SequenceNumber);
                                    }
                                }
                            }
                            catch (Exception e) {
                                if (assembler != null)
                                {
                                    assembler.Clear();
                                }
                                mainPacketHandler.OnAnomalyDetected("Error creating assembler for HTTP file transfer: " + e.Message);
                            }
                        }
                        else  //form data (not multipart)
                        {
                            System.Collections.Generic.List <Mime.MultipartPart> formMultipartData = httpPacket.GetFormData();
                            if (formMultipartData != null)
                            {
                                foreach (Mime.MultipartPart mimeMultipart in formMultipartData)
                                {
                                    if (mimeMultipart.Attributes["requests"] != null && httpPacket.GetQuerystringData() != null && httpPacket.GetQuerystringData()["a"] == "SendMessage")
                                    {
                                        //To handle AOL webmail
                                        string encodedMessage = mimeMultipart.Attributes["requests"];
                                        if (encodedMessage.StartsWith("[{") && encodedMessage.EndsWith("}]"))
                                        {
                                            encodedMessage = encodedMessage.Substring(2, encodedMessage.Length - 4);
                                        }
                                        int startIndex = -1;
                                        int endIndex   = -1;
                                        while (endIndex < encodedMessage.Length - 2)
                                        {
                                            //startIndex = endIndex + 1;
                                            if (endIndex > 0)
                                            {
                                                startIndex = encodedMessage.IndexOf(',', endIndex) + 1;
                                            }
                                            else
                                            {
                                                startIndex = 0;
                                            }
                                            bool escapedString = encodedMessage[startIndex] == '\"';
                                            if (escapedString)
                                            {
                                                startIndex = encodedMessage.IndexOf('\"', startIndex) + 1;
                                                endIndex   = encodedMessage.IndexOf('\"', startIndex);
                                                while (encodedMessage[endIndex - 1] == '\\')
                                                {
                                                    endIndex = encodedMessage.IndexOf('\"', endIndex + 1);
                                                }
                                            }
                                            else
                                            {
                                                endIndex = encodedMessage.IndexOf(':', startIndex);
                                            }

                                            string attributeName = encodedMessage.Substring(startIndex, endIndex - startIndex);

#if DEBUG
                                            //System.Diagnostics.Debug.Assert(encodedMessage[endIndex + 1] == ':');
                                            if (encodedMessage[endIndex] != ':' && encodedMessage[endIndex + 1] != ':')
                                            {
                                                System.Diagnostics.Debugger.Break();
                                            }
#endif
                                            startIndex    = encodedMessage.IndexOf(':', endIndex) + 1;
                                            escapedString = encodedMessage[startIndex] == '\"';
                                            if (escapedString)
                                            {
                                                startIndex = encodedMessage.IndexOf('\"', startIndex) + 1;
                                                endIndex   = encodedMessage.IndexOf('\"', startIndex);
                                                while (encodedMessage[endIndex - 1] == '\\')
                                                {
                                                    endIndex = encodedMessage.IndexOf('\"', endIndex + 1);
                                                }
                                            }
                                            else if (encodedMessage.IndexOf(',', startIndex) > 0)
                                            {
                                                endIndex = encodedMessage.IndexOf(',', startIndex);
                                            }
                                            else
                                            {
                                                endIndex = encodedMessage.Length;
                                            }

                                            string attributeValue = encodedMessage.Substring(startIndex, endIndex - startIndex);
                                            //replace some special characters
                                            encodedMessage = encodedMessage.Replace("\\n", System.Environment.NewLine).Replace("\\r", "\r").Replace("\\t", "\t");
                                            mimeMultipart.Attributes.Add(attributeName, attributeValue);
                                        }
                                        //END OF AOL WEBMAIL CODE
                                    }
                                }
                                this.MainPacketHandler.ExtractMultipartFormData(formMultipartData, sourceHost, destinationHost, tcpPacket.ParentFrame.Timestamp, httpPacket.ParentFrame.FrameNumber, "TCP " + tcpPacket.SourcePort, "TCP " + tcpPacket.DestinationPort, ApplicationLayerProtocol.Http, cookieParams);
                            }
                        }
                    }
                }
            }
            else  //reply
            {
                if (httpPacket.ServerBanner != null && httpPacket.ServerBanner.Length > 0)
                {
                    sourceHost.AddHttpServerBanner(httpPacket.ServerBanner, tcpPacket.SourcePort);
                }
                if (httpPacket.WwwAuthenticateRealm != null && httpPacket.WwwAuthenticateRealm.Length > 0)
                {
                    sourceHost.AddHostName(httpPacket.WwwAuthenticateRealm);
                    sourceHost.ExtraDetailsList["WWW-Authenticate realm"] = httpPacket.WwwAuthenticateRealm;
                }
                if (mainPacketHandler.FileStreamAssemblerList.ContainsAssembler(sourceHost, tcpPacket.SourcePort, destinationHost, tcpPacket.DestinationPort, true))
                {
                    FileTransfer.FileStreamAssembler assembler = mainPacketHandler.FileStreamAssemblerList.GetAssembler(sourceHost, tcpPacket.SourcePort, destinationHost, tcpPacket.DestinationPort, true);

                    //http://www.mail-archive.com/[email protected]/msg08695.html
                    //There could also be no content-length when http-keepalives are not used.
                    //In that case, the client just collects all data till the TCP-FIN.
                    //-1 is set instead of null if Content-Length is not defined
                    if (httpPacket.ContentLength >= 0 || httpPacket.ContentLength == -1)
                    {
                        assembler.FileContentLength         = httpPacket.ContentLength;
                        assembler.FileSegmentRemainingBytes = httpPacket.ContentLength;//we get the whole file in one segment (one serie of TCP packets)
                    }

                    if (httpPacket.ContentLength == 0)
                    {
                        mainPacketHandler.FileStreamAssemblerList.Remove(assembler, true);
                    }
                    else
                    {
                        if (httpPacket.ContentDispositionFilename != null)
                        {
                            assembler.Filename = httpPacket.ContentDispositionFilename;
                        }
                        //append content type extention to file name
                        if (httpPacket.ContentType != null && httpPacket.ContentType.Contains("/") && httpPacket.ContentType.IndexOf('/') < httpPacket.ContentType.Length - 1)
                        {
                            string extension = Utils.StringManglerUtil.GetExtension(httpPacket.ContentType);

                            /*
                             * string extension=httpPacket.ContentType.Substring(httpPacket.ContentType.IndexOf('/')+1);
                             * if(extension.Contains(";"))
                             *  extension=extension.Substring(0, extension.IndexOf(";"));
                             * */
                            if (extension.Length > 0 &&
                                !assembler.Filename.EndsWith("." + extension, StringComparison.InvariantCultureIgnoreCase) &&
                                !(assembler.Filename.EndsWith("jpg", StringComparison.InvariantCultureIgnoreCase) && extension.Equals("jpeg", StringComparison.InvariantCultureIgnoreCase)) &&
                                !(assembler.Filename.EndsWith("htm", StringComparison.InvariantCultureIgnoreCase) && extension.Equals("html", StringComparison.InvariantCultureIgnoreCase)))
                            {
                                //append the content type as extension
                                assembler.Filename = assembler.Filename + "." + extension;
                            }
                        }

                        if (httpPacket.TransferEncoding == "chunked")
                        {
                            assembler.FileStreamType = FileTransfer.FileStreamTypes.HttpGetChunked;
                        }
                        if (httpPacket.ContentEncoding != null && httpPacket.ContentEncoding.Length > 0)
                        {
                            if (httpPacket.ContentEncoding.Equals("gzip"))//I'll only care aboute gzip for now
                            {
                                assembler.ContentEncoding = Packets.HttpPacket.ContentEncodings.Gzip;
                            }
                            else if (httpPacket.ContentEncoding.Equals("deflate"))//http://tools.ietf.org/html/rfc1950
                            {
                                assembler.ContentEncoding = Packets.HttpPacket.ContentEncodings.Deflate;
                            }
                        }


                        if (assembler.TryActivate())
                        {
                            //the assembler is now ready to receive data

                            if (httpPacket.MessageBody != null && httpPacket.MessageBody.Length > 0)
                            {
                                if (assembler.FileStreamType == FileTransfer.FileStreamTypes.HttpGetChunked || httpPacket.MessageBody.Length <= assembler.FileSegmentRemainingBytes || assembler.FileSegmentRemainingBytes == -1)
                                {
                                    assembler.AddData(httpPacket.MessageBody, tcpPacket.SequenceNumber);
                                }
                            }
                        }
                    }
                    //}
                    //else {
                    //    mainPacketHandler.FileStreamAssemblerList.Remove(assembler, true);
                    //}
                }
            }
            return(true);
        }
Пример #2
0
        public int ExtractData(NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable <PacketParser.Packets.AbstractPacket> packetList)
        {
            //Packets.UdpPacket udpPacket = null;
            int parsedBytes = 0;
            //Packets.ITransportLayerPacket transportLayerPacket = null;
            FiveTuple ft = null;

            foreach (Packets.AbstractPacket p in packetList)
            {
                if (p is Packets.ITransportLayerPacket transportLayerPacket)
                {
                    //transportLayerPacket = (Packets.ITransportLayerPacket)p;
                    if (transportLayerPacket is Packets.UdpPacket)
                    {
                        ft = new FiveTuple(sourceHost, transportLayerPacket.SourcePort, destinationHost, transportLayerPacket.DestinationPort, FiveTuple.TransportProtocol.UDP);
                    }
                    else if (transportLayerPacket is Packets.TcpPacket)
                    {
                        ft = new FiveTuple(sourceHost, transportLayerPacket.SourcePort, destinationHost, transportLayerPacket.DestinationPort, FiveTuple.TransportProtocol.TCP);
                    }
                }
                if (p is Packets.SipPacket sipPacket)
                {
                    //Packets.SipPacket sipPacket=(Packets.SipPacket)p;
                    System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection();
                    if (sipPacket.RequestMethod != null)
                    {
                        nvc.Add(sipPacket.RequestMethod.ToString(), sipPacket.MessageLine.Substring(sipPacket.RequestMethod.ToString().Length).Trim());

                        if (sipPacket.From != null && sipPacket.From.Length > 0)
                        {
                            sourceHost.AddNumberedExtraDetail("SIP User", this.ExtractSipAddressFromHeader(sipPacket.From));
                        }

                        if (sipPacket.Contact?.Length > 0)
                        {
                            sourceHost.AddNumberedExtraDetail("SIP User", this.ExtractSipAddressFromHeader(sipPacket.Contact));
                        }

                        //if (sipPacket.MessageLine.StartsWith(INVITE)) {
                        if (sipPacket.RequestMethod == SipPacket.RequestMethods.INVITE)
                        {
                            string to   = null;
                            string from = null;
                            if (sipPacket.To != null && sipPacket.To.Length > 0)
                            {
                                destinationHost.AddNumberedExtraDetail("SIP User", this.ExtractSipAddressFromHeader(sipPacket.To));
                            }

                            if (ft != null && to != null && from != null && !String.IsNullOrEmpty(sipPacket.CallID))
                            {
                                nvc.Add("From", sipPacket.From);
                                nvc.Add("To", sipPacket.To);
                                nvc.Add("Call-ID", sipPacket.CallID);
                            }
                        }
                        else if (sipPacket.RequestMethod == SipPacket.RequestMethods.MESSAGE)
                        {
                            if (sipPacket.ContentLength > 0 && sipPacket.ContentType.StartsWith("text/plain", StringComparison.OrdinalIgnoreCase))
                            {
                                string message = Encoding.UTF8.GetString(sipPacket.ParentFrame.Data, sipPacket.MessageBodyStartIndex, sipPacket.ContentLength);
                                //sipPacket.ParentFrame.Data. sipPacket.MessageBodyStartIndex
                                string to     = this.ExtractSipAddressFromHeader(sipPacket.To);
                                string from   = this.ExtractSipAddressFromHeader(sipPacket.From);
                                string callId = sipPacket.CallID;

                                if (message?.Length > 0)
                                {
                                    if (callId == null || callId.Length == 0)
                                    {
                                        callId = message;
                                    }
                                    this.MainPacketHandler.OnMessageDetected(new Events.MessageEventArgs(ApplicationLayerProtocol.Sip, sourceHost, destinationHost, sipPacket.ParentFrame.FrameNumber, sipPacket.ParentFrame.Timestamp, from, to, callId, message, sipPacket.HeaderFields, sipPacket.PacketLength));
                                }
                            }
                        }
                    }
                    nvc.Add(sipPacket.HeaderFields);
                    //Extract SIP headers like "X-msisdn" and "X-user-id" as explained by Sandro Gauci here: https://www.rtcsec.com/2020/09/01-smuggling-sip-headers-ftw/
                    foreach (string interestingSipHeader in sipPacket.HeaderFields.AllKeys.Where(k => k.Trim().StartsWith("X-", StringComparison.InvariantCultureIgnoreCase)))
                    {
                        sourceHost.AddNumberedExtraDetail("SIP header: " + interestingSipHeader, sipPacket.HeaderFields[interestingSipHeader]);
                    }

                    if (ft != null && nvc?.Count > 0)
                    {
                        this.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(sipPacket.ParentFrame.FrameNumber, ft, true, nvc, sipPacket.ParentFrame.Timestamp, "SIP session " + ft.ToString()));
                    }
                    if (!String.IsNullOrEmpty(sipPacket.UserAgent))
                    {
                        sourceHost.AddHttpUserAgentBanner(sipPacket.UserAgent);
                    }
                    if (sipPacket.SDP != null)
                    {
                        if (sipPacket.SDP.Port != null && sipPacket.SDP.IP != null && sipPacket.CallID != null && ft != null)
                        {
                            lock (callEndPoints) {
                                Tuple <System.Net.IPAddress, ushort, FiveTuple> endPoint = new Tuple <System.Net.IPAddress, ushort, FiveTuple>(sipPacket.SDP.IP, sipPacket.SDP.Port.Value, ft);
                                if (this.callEndPoints.ContainsKey(sipPacket.CallID))
                                {
                                    Tuple <System.Net.IPAddress, ushort, FiveTuple> matchedTuple = null;
                                    foreach (var previousEndPoint in this.callEndPoints[sipPacket.CallID])
                                    {
                                        if (previousEndPoint.Item3.EqualsIgnoreDirection(ft))
                                        {
                                            //Tuple<System.Net.IPAddress, ushort, FiveTuple> previousEndPoint = ;
                                            if (!(previousEndPoint.Item1.Equals(endPoint.Item1) && previousEndPoint.Item2.Equals(endPoint.Item2)))
                                            {
                                                //this.callEndPoints.Remove(sipPacket.CallID);
                                                matchedTuple = previousEndPoint;
                                                if (sipPacket.From != null && sipPacket.To != null)
                                                {
                                                    this.MainPacketHandler.OnVoipCallDetected(sipPacket.SDP.IP, sipPacket.SDP.Port.Value, previousEndPoint.Item1, previousEndPoint.Item2, sipPacket.CallID, this.ExtractSipAddressFromHeader(sipPacket.From), this.ExtractSipAddressFromHeader(sipPacket.To));
                                                }
                                                break;
                                            }
                                        }
                                    }
                                    if (matchedTuple == null)
                                    {
                                        this.callEndPoints[sipPacket.CallID].Add(endPoint);
                                    }
                                    if (matchedTuple != null)
                                    {
                                        this.callEndPoints[sipPacket.CallID].Remove(matchedTuple);
                                    }
                                }
                                else
                                {
                                    this.callEndPoints.Add(sipPacket.CallID, new List <Tuple <System.Net.IPAddress, ushort, FiveTuple> >()
                                    {
                                        endPoint
                                    });
                                }
                            }
                        }
                    }
                    parsedBytes += sipPacket.PacketLength;
                }
            }
            return(parsedBytes);
        }
        public int ExtractData(NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable <PacketParser.Packets.AbstractPacket> packetList)
        {
            //Packets.UdpPacket udpPacket = null;
            int parsedBytes = 0;

            Packets.ITransportLayerPacket transportLayerPacket = null;
            FiveTuple ft = null;

            foreach (Packets.AbstractPacket p in packetList)
            {
                if (p is Packets.ITransportLayerPacket)
                {
                    transportLayerPacket = (Packets.ITransportLayerPacket)p;
                    if (transportLayerPacket is Packets.UdpPacket)
                    {
                        ft = new FiveTuple(sourceHost, transportLayerPacket.SourcePort, destinationHost, transportLayerPacket.DestinationPort, FiveTuple.TransportProtocol.UDP);
                    }
                    else if (transportLayerPacket is Packets.TcpPacket)
                    {
                        ft = new FiveTuple(sourceHost, transportLayerPacket.SourcePort, destinationHost, transportLayerPacket.DestinationPort, FiveTuple.TransportProtocol.TCP);
                    }
                }
                if (p.GetType() == typeof(Packets.SipPacket))
                {
                    Packets.SipPacket sipPacket = (Packets.SipPacket)p;
                    if (sipPacket.MessageLine.StartsWith(INVITE))
                    {
                        string to   = null;
                        string from = null;
                        if (sipPacket.To != null && sipPacket.To.Length > 0)
                        {
                            to = sipPacket.To;
                            if (to.Contains(";"))
                            {
                                to = to.Substring(0, to.IndexOf(';'));
                            }
                            destinationHost.AddNumberedExtraDetail("SIP User", to);
                            //destinationHost.ExtraDetailsList["SIP User"]=to;
                        }
                        if (sipPacket.From != null && sipPacket.From.Length > 0)
                        {
                            from = sipPacket.From;
                            if (from.Contains(";"))
                            {
                                from = from.Substring(0, from.IndexOf(';'));
                            }
                            //destinationHost.AddNumberedExtraDetail("SIP User", from);
                            sourceHost.AddNumberedExtraDetail("SIP User", from);
                            //sourceHost.ExtraDetailsList["SIP User"]=from;
                        }
                        if (ft != null && to != null && from != null && !String.IsNullOrEmpty(sipPacket.CallID))
                        {
                            System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection {
                                { "From", sipPacket.From },
                                { "To", sipPacket.To },
                                { "Call-ID", sipPacket.CallID }
                            };
                            this.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(sipPacket.ParentFrame.FrameNumber, ft, true, nvc, sipPacket.ParentFrame.Timestamp, "SIP session " + ft.ToString()));
                        }
                    }
                    if (!String.IsNullOrEmpty(sipPacket.UserAgent))
                    {
                        sourceHost.AddHttpUserAgentBanner(sipPacket.UserAgent);
                    }
                    if (sipPacket.SDP != null)
                    {
                        if (sipPacket.SDP.Port != null && sipPacket.SDP.IP != null && sipPacket.CallID != null && ft != null)
                        {
                            lock (callEndPoints) {
                                Tuple <System.Net.IPAddress, ushort, FiveTuple> endPoint = new Tuple <System.Net.IPAddress, ushort, FiveTuple>(sipPacket.SDP.IP, sipPacket.SDP.Port.Value, ft);
                                if (this.callEndPoints.ContainsKey(sipPacket.CallID))
                                {
                                    Tuple <System.Net.IPAddress, ushort, FiveTuple> matchedTuple = null;
                                    foreach (var previousEndPoint in this.callEndPoints[sipPacket.CallID])
                                    {
                                        if (previousEndPoint.Item3.EqualsIgnoreDirection(ft))
                                        {
                                            //Tuple<System.Net.IPAddress, ushort, FiveTuple> previousEndPoint = ;
                                            if (!(previousEndPoint.Item1.Equals(endPoint.Item1) && previousEndPoint.Item2.Equals(endPoint.Item2)))
                                            {
                                                //this.callEndPoints.Remove(sipPacket.CallID);
                                                matchedTuple = previousEndPoint;
                                                if (sipPacket.From != null && sipPacket.To != null)
                                                {
                                                    this.MainPacketHandler.OnVoipCallDetected(sipPacket.SDP.IP, sipPacket.SDP.Port.Value, previousEndPoint.Item1, previousEndPoint.Item2, sipPacket.CallID, sipPacket.From, sipPacket.To);

                                                    if (ft != null)
                                                    {
                                                    }
                                                }
                                                break;
                                            }
                                        }
                                    }
                                    if (matchedTuple == null)
                                    {
                                        this.callEndPoints[sipPacket.CallID].Add(endPoint);
                                    }
                                    if (matchedTuple != null)
                                    {
                                        this.callEndPoints[sipPacket.CallID].Remove(matchedTuple);
                                    }
                                }
                                else
                                {
                                    this.callEndPoints.Add(sipPacket.CallID, new List <Tuple <System.Net.IPAddress, ushort, FiveTuple> >()
                                    {
                                        endPoint
                                    });
                                }
                            }
                        }
                    }
                    parsedBytes += sipPacket.PacketLength;
                }
            }
            return(parsedBytes);
        }
Пример #4
0
        public void ExtractData(ref NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable <PacketParser.Packets.AbstractPacket> packetList)
        {
            //Packets.UdpPacket udpPacket = null;
            Packets.ITransportLayerPacket transportLayerPacket = null;
            FiveTuple ft = null;

            foreach (Packets.AbstractPacket p in packetList)
            {
                /*
                 * Packets.IIPPacket ipPacket;
                 * if (p is Packets.IIPPacket) {
                 *  ipPacket = p as Packets.IIPPacket;
                 * }
                 */

                if (p is Packets.ITransportLayerPacket)
                {
                    transportLayerPacket = (Packets.ITransportLayerPacket)p;
                    if (transportLayerPacket is Packets.UdpPacket)
                    {
                        ft = new FiveTuple(sourceHost, transportLayerPacket.SourcePort, destinationHost, transportLayerPacket.DestinationPort, FiveTuple.TransportProtocol.UDP);
                    }
                    else if (transportLayerPacket is Packets.TcpPacket)
                    {
                        ft = new FiveTuple(sourceHost, transportLayerPacket.SourcePort, destinationHost, transportLayerPacket.DestinationPort, FiveTuple.TransportProtocol.TCP);
                    }
                }
                if (p.GetType() == typeof(Packets.SipPacket))
                {
                    Packets.SipPacket sipPacket = (Packets.SipPacket)p;
                    if (sipPacket.MessageLine.StartsWith(INVITE))
                    {
                        string to   = null;
                        string from = null;
                        if (sipPacket.To != null && sipPacket.To.Length > 0)
                        {
                            to = sipPacket.To;
                            if (to.Contains(";"))
                            {
                                to = to.Substring(0, to.IndexOf(';'));
                            }
                            destinationHost.AddNumberedExtraDetail("SIP User", to);
                            //destinationHost.ExtraDetailsList["SIP User"]=to;
                        }
                        if (sipPacket.From != null && sipPacket.From.Length > 0)
                        {
                            from = sipPacket.From;
                            if (from.Contains(";"))
                            {
                                from = from.Substring(0, from.IndexOf(';'));
                            }
                            //destinationHost.AddNumberedExtraDetail("SIP User", from);
                            sourceHost.AddNumberedExtraDetail("SIP User", from);
                            //sourceHost.ExtraDetailsList["SIP User"]=from;
                        }
                        if (ft != null && to != null && from != null && !String.IsNullOrEmpty(sipPacket.CallID))
                        {
                            System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection {
                                { "From", sipPacket.From },
                                { "To", sipPacket.To },
                                { "Call-ID", sipPacket.CallID }
                            };
                            this.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(sipPacket.ParentFrame.FrameNumber, ft, true, nvc, sipPacket.ParentFrame.Timestamp, "SIP session " + ft.ToString()));
                        }
                    }
                    if (!String.IsNullOrEmpty(sipPacket.UserAgent))
                    {
                        sourceHost.AddHttpUserAgentBanner(sipPacket.UserAgent);
                    }
                    if (sipPacket.SDP != null)
                    {
                        if (sipPacket.SDP.Port != null && sipPacket.SDP.IP != null && sipPacket.CallID != null && ft != null)
                        {
                            lock (callEndPoints) {
                                Tuple <System.Net.IPAddress, ushort, FiveTuple> endPoint = new Tuple <System.Net.IPAddress, ushort, FiveTuple>(sipPacket.SDP.IP, sipPacket.SDP.Port.Value, ft);
                                if (this.callEndPoints.ContainsKey(sipPacket.CallID))
                                {
                                    Tuple <System.Net.IPAddress, ushort, FiveTuple> matchedTuple = null;
                                    foreach (var previousEndPoint in this.callEndPoints[sipPacket.CallID])
                                    {
                                        if (previousEndPoint.Item3.EqualsIgnoreDirection(ft))
                                        {
                                            //Tuple<System.Net.IPAddress, ushort, FiveTuple> previousEndPoint = ;
                                            if (!(previousEndPoint.Item1.Equals(endPoint.Item1) && previousEndPoint.Item2.Equals(endPoint.Item2)))
                                            {
                                                //this.callEndPoints.Remove(sipPacket.CallID);
                                                matchedTuple = previousEndPoint;
                                                if (sipPacket.From != null && sipPacket.To != null)
                                                {
                                                    this.MainPacketHandler.OnVoipCallDetected(sipPacket.SDP.IP, sipPacket.SDP.Port.Value, previousEndPoint.Item1, previousEndPoint.Item2, sipPacket.CallID, sipPacket.From, sipPacket.To);

                                                    if (ft != null)
                                                    {
                                                    }
                                                }
                                                break;
                                            }
                                        }
                                    }
                                    if (matchedTuple == null)
                                    {
                                        this.callEndPoints[sipPacket.CallID].Add(endPoint);
                                    }
                                    if (matchedTuple != null)
                                    {
                                        this.callEndPoints[sipPacket.CallID].Remove(matchedTuple);
                                    }
                                }
                                else
                                {
                                    this.callEndPoints.Add(sipPacket.CallID, new List <Tuple <System.Net.IPAddress, ushort, FiveTuple> >()
                                    {
                                        endPoint
                                    });
                                }
                            }

                            /*
                             * //check if we have a reverse tuple
                             * Tuple<System.Net.IPAddress, System.Net.IPAddress> reverseIpPair = new Tuple<System.Net.IPAddress, System.Net.IPAddress>(destinationHost.IPAddress, sourceHost.IPAddress);
                             *
                             * TODO: Använd CALL ID istället som unik nyckel!
                             *
                             * lock (this.endPointCandidates) {
                             *  if (this.endPointCandidates.ContainsKey(reverseIpPair)) {
                             *      ushort reversePort = this.endPointCandidates[reverseIpPair];
                             *      this.endPointCandidates.Remove(reverseIpPair);
                             *
                             *      if (this.udpPayloadProtocolFinder != null && !String.IsNullOrEmpty(sipPacket.SDP.Protocol) && sipPacket.SDP.Protocol.StartsWith("RTP", StringComparison.InvariantCultureIgnoreCase))
                             *          this.udpPayloadProtocolFinder.SetPayload(sourceHost.IPAddress, sipPacket.SDP.Port.Value, destinationHost.IPAddress, reversePort, ApplicationLayerProtocol.Rtp);//this might come in too late because the UDP packet has probably already been parsed by now.
                             *      if(sipPacket.From != null && sipPacket.To != null) {
                             *          FiveTuple fiveTuple = new FiveTuple(sourceHost, sipPacket.SDP.Port.Value, destinationHost, reversePort, FiveTuple.TransportProtocol.UDP);
                             *          this.MainPacketHandler.OnVoipCallDetected(fiveTuple, sipPacket.From, sipPacket.To);
                             *          System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection();
                             *          nvc.Add("From", sipPacket.From);
                             *          nvc.Add("To", sipPacket.To);
                             *          this.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(sipPacket.ParentFrame.FrameNumber, fiveTuple, true, nvc, sipPacket.ParentFrame.Timestamp, "SIP setup of call " + fiveTuple.ToString()));
                             *      }
                             *
                             *  }
                             *  else {
                             *      Tuple<System.Net.IPAddress, System.Net.IPAddress> ipPair = new Tuple<System.Net.IPAddress, System.Net.IPAddress>(sourceHost.IPAddress, destinationHost.IPAddress);
                             *      if (this.endPointCandidates.ContainsKey(ipPair))
                             *          this.endPointCandidates[ipPair] = sipPacket.SDP.Port.Value;
                             *      else
                             *          this.endPointCandidates.Add(ipPair, sipPacket.SDP.Port.Value);
                             *  }
                             * }
                             */
                        }

                        //rtpPacketHandler.NewRtpEndPoints.Enqueue(new Tuple<System.Net.IPAddress, System.Net.IPAddress, ushort>(destinationHost.IPAddress, sourceHost.IPAddress, sipPacket.SDP.Port.Value));
                    }
                }
            }
        }