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); * } * */ } } } }
/// <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); }