Esempio n. 1
0
        private void ExtractSmbData(NetworkTcpSession tcpSession, bool transferIsClientToServer, Packets.TcpPacket tcpPacket, Packets.SmbPacket.AbstractSmbCommand smbCommandPacket, PacketHandler mainPacketHandler)
        {
            NetworkHost sourceHost, destinationHost;

            if (transferIsClientToServer)
            {
                sourceHost      = tcpSession.Flow.FiveTuple.ClientHost;
                destinationHost = tcpSession.Flow.FiveTuple.ServerHost;
            }
            else
            {
                sourceHost      = tcpSession.Flow.FiveTuple.ServerHost;
                destinationHost = tcpSession.Flow.FiveTuple.ClientHost;
            }
            string smbSessionId;

            if (smbCommandPacket.ParentCifsPacket.FlagsResponse)
            {
                smbSessionId = SmbSession.GetSmbSessionId(sourceHost.IPAddress, tcpPacket.SourcePort, destinationHost.IPAddress, tcpPacket.DestinationPort);
            }
            else
            {
                smbSessionId = SmbSession.GetSmbSessionId(destinationHost.IPAddress, tcpPacket.DestinationPort, sourceHost.IPAddress, tcpPacket.SourcePort);
            }


            if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.NegotiateProtocolRequest))
            {
                Packets.SmbPacket.NegotiateProtocolRequest request = (Packets.SmbPacket.NegotiateProtocolRequest)smbCommandPacket;
                sourceHost.AcceptedSmbDialectsList = request.DialectList;
            }
            else if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.NegotiateProtocolResponse))
            {
                Packets.SmbPacket.NegotiateProtocolResponse reply = (Packets.SmbPacket.NegotiateProtocolResponse)smbCommandPacket;
                if (destinationHost.AcceptedSmbDialectsList != null && destinationHost.AcceptedSmbDialectsList.Count > reply.DialectIndex)
                {
                    sourceHost.PreferredSmbDialect = destinationHost.AcceptedSmbDialectsList[reply.DialectIndex];
                }
                //sourceHost.ExtraDetailsList.Add("Preferred SMB dialect", destinationHost.AcceptedSmbDialectsList[reply.DialectIndex]);
            }
            else if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.TreeConnectAndXRequest))
            {
                Packets.SmbPacket.TreeConnectAndXRequest request = (Packets.SmbPacket.TreeConnectAndXRequest)smbCommandPacket;
                if (request.ShareName != null && request.ShareName.Length > 0)
                {
                    destinationHost.AddNumberedExtraDetail("SMB File Share", request.ShareName);

                    System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection();
                    parameters.Add("SMB Tree Connect AndX Request " + request.ParentCifsPacket.MultiplexId.ToString(), request.ShareName);
                    mainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(smbCommandPacket.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parameters, smbCommandPacket.ParentFrame.Timestamp, "SMB Tree Connect AndX Request"));

                    SmbSession smbSession;
                    if (this.smbSessionPopularityList.ContainsKey(smbSessionId))
                    {
                        smbSession = this.smbSessionPopularityList[smbSessionId];
                    }
                    else
                    {
                        smbSession = new SmbSession(destinationHost.IPAddress, tcpPacket.DestinationPort, sourceHost.IPAddress, tcpPacket.SourcePort);
                        this.smbSessionPopularityList.Add(smbSessionId, smbSession);
                    }
                    smbSession.AddTreeConnectAndXRequestPath(smbCommandPacket.ParentCifsPacket.UserId, smbCommandPacket.ParentCifsPacket.MultiplexId, request.ShareName);
                }
            }
            else if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.TreeConnectAndXResponse))
            {
                SmbSession smbSession;
                if (this.smbSessionPopularityList.ContainsKey(smbSessionId))
                {
                    smbSession = this.smbSessionPopularityList[smbSessionId];
                }
                else
                {
                    smbSession = new SmbSession(sourceHost.IPAddress, tcpPacket.SourcePort, destinationHost.IPAddress, tcpPacket.DestinationPort);
                    this.smbSessionPopularityList.Add(smbSessionId, smbSession);
                }
                smbSession.StoreTreeConnectAndXRequestPathForTree(smbCommandPacket.ParentCifsPacket.UserId, smbCommandPacket.ParentCifsPacket.MultiplexId, smbCommandPacket.ParentCifsPacket.TreeId);
            }
            else if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.SetupAndXRequest))
            {
                Packets.SmbPacket.SetupAndXRequest request = (Packets.SmbPacket.SetupAndXRequest)smbCommandPacket;
                if (request.NativeLanManager != null && request.NativeLanManager.Length > 0)
                {
                    if (sourceHost.ExtraDetailsList.ContainsKey("SMB Native LAN Manager"))
                    {
                        sourceHost.ExtraDetailsList["SMB Native LAN Manager"] = request.NativeLanManager;
                    }
                    else
                    {
                        sourceHost.ExtraDetailsList.Add("SMB Native LAN Manager", request.NativeLanManager);
                    }
                }

                if (request.NativeOs != null && request.NativeOs.Length > 0)
                {
                    if (sourceHost.ExtraDetailsList.ContainsKey("SMB Native OS"))
                    {
                        sourceHost.ExtraDetailsList["SMB Native OS"] = request.NativeOs;
                    }
                    else
                    {
                        sourceHost.ExtraDetailsList.Add("SMB Native OS", request.NativeOs);
                    }
                }

                if (request.PrimaryDomain != null && request.PrimaryDomain.Length > 0)
                {
                    sourceHost.AddDomainName(request.PrimaryDomain);
                }
                if (request.AccountName != null && request.AccountName.Length > 0)
                {
                    NetworkCredential nCredential = new NetworkCredential(sourceHost, destinationHost, smbCommandPacket.PacketTypeDescription, request.AccountName, request.ParentFrame.Timestamp);
                    if (request.AccountPassword != null && request.AccountPassword.Length > 0)
                    {
                        nCredential.Password = request.AccountPassword;
                    }
                    mainPacketHandler.AddCredential(nCredential);
                }
            }
            else if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.SetupAndXResponse))
            {
                Packets.SmbPacket.SetupAndXResponse response = (Packets.SmbPacket.SetupAndXResponse)smbCommandPacket;
                if (response.NativeLanManager != null && response.NativeLanManager.Length > 0)
                {
                    if (sourceHost.ExtraDetailsList.ContainsKey("SMB Native LAN Manager"))
                    {
                        sourceHost.ExtraDetailsList["SMB Native LAN Manager"] = response.NativeLanManager;
                    }
                    else
                    {
                        sourceHost.ExtraDetailsList.Add("SMB Native LAN Manager", response.NativeLanManager);
                    }
                }

                if (response.NativeOs != null && response.NativeOs.Length > 0)
                {
                    if (sourceHost.ExtraDetailsList.ContainsKey("SMB Native OS"))
                    {
                        sourceHost.ExtraDetailsList["SMB Native OS"] = response.NativeOs;
                    }
                    else
                    {
                        sourceHost.ExtraDetailsList.Add("SMB Native OS", response.NativeOs);
                    }
                }
            }
            else if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.NTCreateAndXRequest))
            {
                Packets.SmbPacket.NTCreateAndXRequest request = (Packets.SmbPacket.NTCreateAndXRequest)smbCommandPacket;
                string filename, filePath;

                if (request.Filename.EndsWith("\0"))
                {
                    filename = request.Filename.Remove(request.Filename.Length - 1);
                }
                else
                {
                    filename = request.Filename;
                }

                //print raw filename on parameters tab
                System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection();
                parameters.Add("SMB NT Create AndX Request " + request.ParentCifsPacket.MultiplexId.ToString(), filename);
                base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(request.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parameters, request.ParentFrame.Timestamp, "SMB NTCreateAndXRequest"));

                SmbSession smbSession;
                if (this.smbSessionPopularityList.ContainsKey(smbSessionId))
                {
                    smbSession = this.smbSessionPopularityList[smbSessionId];
                }
                else
                {
                    smbSession = new SmbSession(destinationHost.IPAddress, tcpPacket.DestinationPort, sourceHost.IPAddress, tcpPacket.SourcePort);
                    this.smbSessionPopularityList.Add(smbSessionId, smbSession);
                }

                string treePath = smbSession.GetPathForTree(smbCommandPacket.ParentCifsPacket.TreeId);
                if (treePath == null)
                {
                    filePath = "";
                }
                else
                {
                    filePath = treePath + System.IO.Path.DirectorySeparatorChar;
                }

                if (System.IO.Path.DirectorySeparatorChar != '\\' && filename.Contains("\\"))
                {
                    filename.Replace('\\', System.IO.Path.DirectorySeparatorChar);
                }

                if (filename.Contains(System.IO.Path.DirectorySeparatorChar.ToString()))
                {
                    filePath += filename.Substring(0, filename.LastIndexOf(System.IO.Path.DirectorySeparatorChar.ToString()));
                    filename  = filename.Substring(filename.LastIndexOf(System.IO.Path.DirectorySeparatorChar.ToString()) + 1);
                }
                else
                {
                    filePath += System.IO.Path.DirectorySeparatorChar.ToString();
                }

                try {
                    FileTransfer.FileStreamAssembler assembler = new FileTransfer.FileStreamAssembler(mainPacketHandler.FileStreamAssemblerList, tcpSession.Flow.FiveTuple, !transferIsClientToServer, FileTransfer.FileStreamTypes.SMB, filename, filePath, filePath + filename, smbCommandPacket.ParentFrame.FrameNumber, smbCommandPacket.ParentFrame.Timestamp);
                    smbSession.AddFileStreamAssembler(assembler, request.ParentCifsPacket.TreeId, request.ParentCifsPacket.MultiplexId, request.ParentCifsPacket.ProcessId);
                }
                catch (Exception e) {
                    MainPacketHandler.OnAnomalyDetected("Error creating assembler for SMB file transfer: " + e.Message);
                }
            }
            //else if(!smbCommandPacket.ParentCifsPacket.FlagsResponse && mainPacketHandler.FileStreamAssemblerList.ContainsAssembler(destinationHost, tcpPacket.DestinationPort, sourceHost, tcpPacket.SourcePort, true)) {
            else if (!smbCommandPacket.ParentCifsPacket.FlagsResponse && this.smbSessionPopularityList.ContainsKey(smbSessionId))
            {
                //Request
                if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.CloseRequest) && smbSessionPopularityList.ContainsKey(smbSessionId))
                {
                    SmbSession smbSession = this.smbSessionPopularityList[smbSessionId];
                    Packets.SmbPacket.CloseRequest closeRequest = (Packets.SmbPacket.CloseRequest)smbCommandPacket;
                    ushort fileId = closeRequest.FileId;
                    //FileTransfer.FileStreamAssembler assemblerToClose;
                    if (smbSession.ContainsFileId(closeRequest.ParentCifsPacket.TreeId, closeRequest.ParentCifsPacket.MultiplexId, closeRequest.ParentCifsPacket.ProcessId, fileId))
                    {
                        FileTransfer.FileStreamAssembler assemblerToClose = smbSession.GetFileStreamAssembler(closeRequest.ParentCifsPacket.TreeId, closeRequest.ParentCifsPacket.MultiplexId, closeRequest.ParentCifsPacket.ProcessId, fileId);
                        if (assemblerToClose != null && assemblerToClose.AssembledByteCount >= assemblerToClose.FileContentLength)
                        {
                            assemblerToClose.FinishAssembling();
                        }
                        FileTransfer.FileSegmentAssembler segmentAssemblerToClose = smbSession.GetFileSegmentAssembler(closeRequest.ParentCifsPacket.TreeId, closeRequest.ParentCifsPacket.MultiplexId, closeRequest.ParentCifsPacket.ProcessId, fileId);
                        if (segmentAssemblerToClose != null)
                        {
                            segmentAssemblerToClose.Close();
                        }

                        smbSession.RemoveFileStreamAssembler(closeRequest.ParentCifsPacket.TreeId, closeRequest.ParentCifsPacket.MultiplexId, closeRequest.ParentCifsPacket.ProcessId, fileId, false);

                        //TODO: remove the following line (added for debugging purpose 2011-04-25)
                        //assemblerToClose.FinishAssembling();

                        if (mainPacketHandler.FileStreamAssemblerList.ContainsAssembler(assemblerToClose))
                        {
                            mainPacketHandler.FileStreamAssemblerList.Remove(assemblerToClose, true);
                        }
                        else
                        {
                            assemblerToClose.Clear();
                        }
                    }
                }
                else if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.ReadAndXRequest) && smbSessionPopularityList.ContainsKey(smbSessionId))
                {
                    SmbSession smbSession = this.smbSessionPopularityList[smbSessionId];
                    //Packets.CifsPacket.ReadAndXRequest request=this.smbSessionPopularityList[smbSessionId];
                    Packets.SmbPacket.ReadAndXRequest readRequest = (Packets.SmbPacket.ReadAndXRequest)smbCommandPacket;
                    ushort fileId = readRequest.FileId;
                    smbSession.Touch(readRequest.ParentCifsPacket.TreeId, readRequest.ParentCifsPacket.MultiplexId, readRequest.ParentCifsPacket.ProcessId, fileId);
                }
                else if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.WriteAndXRequest))
                {
                    SmbSession smbSession = this.smbSessionPopularityList[smbSessionId];
                    Packets.SmbPacket.WriteAndXRequest request          = (Packets.SmbPacket.WriteAndXRequest)smbCommandPacket;
                    FileTransfer.FileSegmentAssembler  segmentAssembler = smbSession.GetFileSegmentAssembler(request.ParentCifsPacket.TreeId, request.ParentCifsPacket.MultiplexId, request.ParentCifsPacket.ProcessId, request.FileId);
                    if (segmentAssembler == null)
                    {
                        string outputDir = System.IO.Path.GetDirectoryName(mainPacketHandler.OutputDirectory);
                        FileTransfer.FileStreamAssembler tmpAssembler = smbSession.GetFileStreamAssembler(request.ParentCifsPacket.TreeId, request.ParentCifsPacket.MultiplexId, request.ParentCifsPacket.ProcessId, request.FileId);
                        if (tmpAssembler != null)
                        {
                            string filePath = tmpAssembler.FileLocation;
                            if (filePath.Length == 0 || filePath.EndsWith("/"))
                            {
                                filePath += tmpAssembler.Filename;
                            }
                            else
                            {
                                filePath += "/" + tmpAssembler.Filename;
                            }

                            segmentAssembler = new FileTransfer.FileSegmentAssembler(outputDir, tcpSession, false, filePath, tcpSession.ToString() + "SMB" + request.FileId.ToString(), mainPacketHandler.FileStreamAssemblerList, null, FileTransfer.FileStreamTypes.SMB, "SMB Write " + tmpAssembler.Details, null);
                            smbSession.AddFileSegmentAssembler(segmentAssembler, request.FileId);
                        }
                    }

                    if (segmentAssembler != null)
                    {
                        segmentAssembler.AddData(request.WriteOffset, request.GetFileData(), request.ParentFrame);
                    }
                }
            }
            else if (smbCommandPacket.ParentCifsPacket.FlagsResponse && this.smbSessionPopularityList.ContainsKey(smbSessionId))
            {
                //Response
                SmbSession smbSession = this.smbSessionPopularityList[smbSessionId];

                //FileTransfer.FileStreamAssembler assembler=mainPacketHandler.FileStreamAssemblerList.GetAssembler(sourceHost, tcpPacket.SourcePort, destinationHost, tcpPacket.DestinationPort, true);

                if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.NTCreateAndXResponse))
                {
                    Packets.SmbPacket.NTCreateAndXResponse response = (Packets.SmbPacket.NTCreateAndXResponse)smbCommandPacket;
                    ushort fileId     = response.FileId;
                    int    fileLength = (int)response.EndOfFile;//yes, I know I will not be able to store big files now... but an int as length is really enough!

                    //tag the requested file with the fileId
                    FileTransfer.FileStreamAssembler assembler = smbSession.GetLastReferencedFileStreamAssembler(response.ParentCifsPacket.TreeId, response.ParentCifsPacket.MultiplexId, response.ParentCifsPacket.ProcessId);
                    smbSession.RemoveLastReferencedAssembler(response.ParentCifsPacket.TreeId, response.ParentCifsPacket.MultiplexId, response.ParentCifsPacket.ProcessId);



                    if (assembler != null)
                    {
                        //Add file ID as extended ID in order to differentiate between parallell file transfers on disk cache
                        assembler.ExtendedFileId = "Id" + fileId.ToString("X4"); //2011-04-18

                        smbSession.AddFileStreamAssembler(assembler, response.ParentCifsPacket.TreeId, response.ParentCifsPacket.MultiplexId, response.ParentCifsPacket.ProcessId, response.FileId);

                        assembler.FileContentLength = fileLength;
                    }
                }
                else if (smbCommandPacket.GetType() == typeof(Packets.SmbPacket.ReadAndXResponse))
                {
                    Packets.SmbPacket.ReadAndXResponse response = (Packets.SmbPacket.ReadAndXResponse)smbCommandPacket;
                    //move the assembler to the real FileStreamAssemblerList!
                    FileTransfer.FileStreamAssembler assembler = smbSession.GetLastReferencedFileStreamAssembler(response.ParentCifsPacket.TreeId, response.ParentCifsPacket.MultiplexId, response.ParentCifsPacket.ProcessId);
                    if (assembler == null)
                    {
                        base.MainPacketHandler.OnAnomalyDetected("Unable to find assembler for frame " + smbCommandPacket.ParentFrame.FrameNumber + " : " + smbCommandPacket.ToString());
                    }
                    else if (assembler != null)
                    {
                        /* Removed 2011-04-25
                         * if(!mainPacketHandler.FileStreamAssemblerList.ContainsAssembler(assembler))
                         *  mainPacketHandler.FileStreamAssemblerList.Add(assembler);
                         * */

                        assembler.FileSegmentRemainingBytes += response.DataLength;//setting this one so that it can receive more bytes
                        if (!assembler.IsActive)
                        {
                            System.Diagnostics.Debug.Assert(assembler.ExtendedFileId != null && assembler.ExtendedFileId != "", "No FileID set for SMB file transfer!");

                            if (!assembler.TryActivate())
                            {
                                if (!response.ParentCifsPacket.ParentFrame.QuickParse)
                                {
                                    response.ParentCifsPacket.ParentFrame.Errors.Add(new Frame.Error(response.ParentCifsPacket.ParentFrame, response.PacketStartIndex, response.PacketEndIndex, "Unable to activate file stream assembler for " + assembler.FileLocation + "/" + assembler.Filename));
                                }
                            }
                            else if (assembler.IsActive)
                            {
                                assembler.AddData(response.GetFileData(), tcpPacket.SequenceNumber);
                            }
                        }

                        /* Removed 2011-04-25
                         * if(!assembler.IsActive) {//see if the file is fully assembled or if something else went wrong...
                         *  smbSession.RemoveLastReferencedAssembler(response.ParentCifsPacket.TreeId, response.ParentCifsPacket.MultiplexId, response.ParentCifsPacket.ProcessId);
                         * }
                         * */
                    }
                }
            }
        }
Esempio n. 2
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>
        public bool ExtractHttpData(Packets.HttpPacket httpPacket, Packets.TcpPacket tcpPacket, FiveTuple fiveTuple, bool transferIsClientToServer, PacketHandler mainPacketHandler)
        {
            NetworkHost sourceHost, destinationHost;

            if (transferIsClientToServer)
            {
                sourceHost      = fiveTuple.ClientHost;
                destinationHost = fiveTuple.ServerHost;
            }
            else
            {
                sourceHost      = fiveTuple.ServerHost;
                destinationHost = fiveTuple.ClientHost;
            }

            //A HTTP cookie can be set by both client and server
            System.Collections.Specialized.NameValueCollection cookieParams = null;
            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, "");
                    }
                }
                NetworkHost client, server;
                if (httpPacket.MessageTypeIsRequest)
                {
                    client = sourceHost;
                    server = destinationHost;
                }
                else
                {
                    client = destinationHost;
                    server = sourceHost;
                }
                NetworkCredential inCookieCredential = NetworkCredential.GetNetworkCredential(cookieParams, client, server, "HTTP Cookie parameter", httpPacket.ParentFrame.Timestamp);
                if (inCookieCredential != null)
                {
                    mainPacketHandler.AddCredential(inCookieCredential);
                }

                mainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(tcpPacket.ParentFrame.FrameNumber, fiveTuple, transferIsClientToServer, cookieParams, httpPacket.ParentFrame.Timestamp, "HTTP Cookie"));
                NetworkCredential credential = new NetworkCredential(client, server, "HTTP Cookie", httpPacket.Cookie, "N/A", httpPacket.ParentFrame.Timestamp);
                mainPacketHandler.AddCredential(credential);
            }

            if (httpPacket.MessageTypeIsRequest)
            {
                //HTTP request
                {
                    System.Collections.Specialized.NameValueCollection httpRequestNvc = new System.Collections.Specialized.NameValueCollection();
                    httpRequestNvc.Add(httpPacket.RequestMethod.ToString(), httpPacket.RequestedFileName);
                    base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(httpPacket.ParentFrame.FrameNumber, fiveTuple, transferIsClientToServer, httpRequestNvc, httpPacket.ParentFrame.Timestamp, "HTTP Request"));
                }


                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.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);

                    System.Collections.Specialized.NameValueCollection httpHeaders = HttpPacketHandler.ParseHeaders(httpPacket, ignoredHeaderNames);


                    //mainPacketHandler.OnParametersDetected
                    base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(httpPacket.ParentFrame.FrameNumber, fiveTuple, transferIsClientToServer, 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, fiveTuple, transferIsClientToServer, 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 && !this.ExtensionMimeTypeCombosMatches(filename))
                    {
                        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 {
                        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, fiveTuple, !transferIsClientToServer, FileTransfer.FileStreamTypes.HttpGetNormal, filename, fileLocation, fileDetails, httpPacket.ParentFrame.FrameNumber, httpPacket.ParentFrame.Timestamp, httpPacket.RequestedHost);
                        //mainPacketHandler.FileStreamAssemblerList.Add(assembler);
                        mainPacketHandler.FileStreamAssemblerList.AddOrEnqueue(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", StringComparison.InvariantCultureIgnoreCase))
                        {
                            FileTransfer.FileStreamAssembler assembler = null;
                            try {
                                //see if there is an old assembler that needs to be removed
                                if (mainPacketHandler.FileStreamAssemblerList.ContainsAssembler(fiveTuple, transferIsClientToServer))
                                {
                                    FileTransfer.FileStreamAssembler oldAssembler = mainPacketHandler.FileStreamAssemblerList.GetAssembler(fiveTuple, transferIsClientToServer);
                                    if (oldAssembler.IsActive && oldAssembler.AssembledByteCount > 0)
                                    {
                                        //I'll assume that the file transfer was OK
                                        assembler.FinishAssembling();
                                    }
                                    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
                                {
                                    int multipartIndex = httpPacket.ContentType.IndexOf("multipart/form-data", StringComparison.InvariantCultureIgnoreCase);
                                    if (multipartIndex >= 0)
                                    {
                                        int boundaryIndex = httpPacket.ContentType.IndexOf("boundary=", multipartIndex, StringComparison.InvariantCultureIgnoreCase);
                                        if (boundaryIndex > 0)
                                        {
                                            mimeBoundary = httpPacket.ContentType.Substring(boundaryIndex + 9);
                                        }
                                    }
                                }

                                assembler = new FileTransfer.FileStreamAssembler(mainPacketHandler.FileStreamAssemblerList, fiveTuple, transferIsClientToServer, 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);

                                            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, fiveTuple, transferIsClientToServer, tcpPacket.ParentFrame.Timestamp, httpPacket.ParentFrame.FrameNumber, ApplicationLayerProtocol.Http, cookieParams);
                            }
                        }
                    }
                }
            }
            else  //reply
            {
                try
                {
                    System.Collections.Specialized.NameValueCollection httpResponseNvc = new System.Collections.Specialized.NameValueCollection();
                    httpResponseNvc.Add("HTTP Response Status Code", httpPacket.StatusCode + " " + httpPacket.StatusMessage);
                    base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(httpPacket.ParentFrame.FrameNumber, fiveTuple, transferIsClientToServer, httpResponseNvc, httpPacket.ParentFrame.Timestamp, "HTTP Response"));

                    System.Collections.Specialized.NameValueCollection httpHeaders = HttpPacketHandler.ParseHeaders(httpPacket);
                    base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(httpPacket.ParentFrame.FrameNumber, fiveTuple, transferIsClientToServer, httpHeaders, httpPacket.ParentFrame.Timestamp, "HTTP Header"));
                }
                catch { };
                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(fiveTuple, transferIsClientToServer))
                {
                    FileTransfer.FileStreamAssembler assembler = mainPacketHandler.FileStreamAssemblerList.GetAssembler(fiveTuple, transferIsClientToServer);

                    //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.StatusCode != null && httpPacket.StatusCode.Trim().StartsWith("1"))
                    {
                        //just ignore this response, probably a "HTTP/1.1 100 Continue"
                    }
                    if (httpPacket.StatusCode != null && httpPacket.StatusCode.Trim().StartsWith("204"))
                    {
                        //HTTP/1.1 204 No Content
                        mainPacketHandler.FileStreamAssemblerList.Remove(assembler, true);
                    }
                    else if (httpPacket.StatusCode != null && !httpPacket.StatusCode.Trim().StartsWith("2") && httpPacket.ContentLength <= 0 && httpPacket.TransferEncoding == null)
                    {
                        mainPacketHandler.FileStreamAssemblerList.Remove(assembler, true);
                    }
                    else
                    {
                        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.ContentRange != null)
                            {
                                assembler.ContentRange = httpPacket.ContentRange;

                                /*
                                 * if (httpPacket.ContentRange.Total > httpPacket.ContentRange.End + 1)
                                 *  assembler.Filename = "part-" + httpPacket.ContentRange.Start.ToString() + "-" + assembler.Filename;
                                 */
                            }

                            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 mimeExtension = Utils.StringManglerUtil.GetExtension(httpPacket.ContentType);

                                /*
                                 * string extension=httpPacket.ContentType.Substring(httpPacket.ContentType.IndexOf('/')+1);
                                 * if(extension.Contains(";"))
                                 *  extension=extension.Substring(0, extension.IndexOf(";"));
                                 * */



                                if (mimeExtension.Length > 0 && !assembler.Filename.EndsWith("." + mimeExtension, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    //string assemblerExtension = Utils.StringManglerUtil.GetExtension(assembler.Filename);
                                    if (this.ExtensionMimeTypeCombosMatches(assembler.Filename, mimeExtension))
                                    {
                                        mimeExtension = null;
                                    }

                                    /*
                                     * foreach (KeyValuePair<string, string> extMime in this.extensionMimeTypeCombos) {
                                     *  if (assembler.Filename.EndsWith(extMime.Key, StringComparison.InvariantCultureIgnoreCase) && extMime.Value.Equals(mimeExtension, StringComparison.InvariantCultureIgnoreCase)) {
                                     *      mimeExtension = null;
                                     *      break;
                                     *  }
                                     * }
                                     */

                                    if (mimeExtension != null)  //append the content type as extension
                                    {
                                        if (this.extensionReplacements.ContainsKey(mimeExtension))
                                        {
                                            assembler.Filename = assembler.Filename + "." + this.extensionReplacements[mimeExtension];
                                        }
                                        else
                                        {
                                            assembler.Filename = assembler.Filename + "." + mimeExtension;
                                        }
                                    }
                                }
                            }

                            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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(true);
        }