private FileTransfer.FileSegmentAssembler GetOrCreateAssembler(NetworkTcpSession tcpSession, bool fileTransferIsClientToServer, Guid fileId, OP_CODE smb2Command) { string uniqueFileId = GetUniqueGuid(tcpSession, fileId); FileTransfer.FileSegmentAssembler assembler = null; if (!this.fileSegmentAssemblerList.ContainsKey(uniqueFileId)) { if (this.fileIdFilenameMap.ContainsKey(uniqueFileId)) { assembler = new FileTransfer.FileSegmentAssembler(this.fileOutputDirectory, tcpSession, fileTransferIsClientToServer, this.fileIdFilenameMap[uniqueFileId], uniqueFileId, base.MainPacketHandler.FileStreamAssemblerList, this.fileSegmentAssemblerList, FileTransfer.FileStreamTypes.SMB2, "SMB2 " + Enum.GetName(typeof(OP_CODE), smb2Command) + " " + fileId.ToString() + " \"" + this.fileIdFilenameMap[uniqueFileId] + "\"", null); this.fileSegmentAssemblerList.Add(uniqueFileId, assembler); } } else { assembler = this.fileSegmentAssemblerList[uniqueFileId]; } return(assembler); }
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); * } * */ } } } }
internal void AddFileSegmentAssembler(FileTransfer.FileSegmentAssembler assembler, ushort fileId) { this.fileIdSegmentAssemblerList.Add(fileId, assembler); }
private void FileIdSegmentAssemblerList_PopularityLost(ushort key, FileTransfer.FileSegmentAssembler value) { value.Close(); }
//public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable<AbstractPacket> packetList) { public int ExtractData(NetworkTcpSession tcpSession, bool transferIsClientToServer, IEnumerable <PacketParser.Packets.AbstractPacket> packetList) { 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; } foreach (Packets.AbstractPacket p in packetList) { if (p is Packets.Smb2Packet.Smb2TreeConnectRequest) { Packets.Smb2Packet.Smb2TreeConnectRequest treeConnectRequest = (Packets.Smb2Packet.Smb2TreeConnectRequest)p; this.requestCache.Add(GetUniqueMessageId(tcpSession, treeConnectRequest.Smb2Packet.MessageID), treeConnectRequest); destinationHost.AddNumberedExtraDetail("SMB File Share", treeConnectRequest.ShareName); System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection(); parameters.Add("SMB2 Connect Request " + treeConnectRequest.Smb2Packet.MessageID, treeConnectRequest.ShareName); base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(p.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parameters, p.ParentFrame.Timestamp, "SMB2 Tree Connect Request")); } else if (p is Packets.Smb2Packet.Smb2TreeConnectResponse) { Packets.Smb2Packet.Smb2TreeConnectResponse treeConnectResponse = (Packets.Smb2Packet.Smb2TreeConnectResponse)p; string requestId = GetUniqueMessageId(tcpSession, treeConnectResponse.Smb2Packet.MessageID); if (treeConnectResponse.Smb2Packet.NtStatus == Smb2Packet.NT_STATUS_SUCCESS && this.requestCache.ContainsKey(requestId)) { Packets.Smb2Packet.Smb2TreeConnectRequest treeConnectRequest = (Packets.Smb2Packet.Smb2TreeConnectRequest) this.requestCache[requestId]; System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection(); parameters.Add("SMB2 Connect " + treeConnectRequest.Smb2Packet.MessageID.ToString() + " Successful (Tree Id: 0x" + treeConnectResponse.Smb2Packet.TreeId.ToString("x8") + ")", treeConnectRequest.ShareName); base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(p.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parameters, p.ParentFrame.Timestamp, "SMB2 Tree Connect Response")); } } else if (p is Packets.Smb2Packet.Smb2CreateRequest) { Packets.Smb2Packet.Smb2CreateRequest createRequest = (Packets.Smb2Packet.Smb2CreateRequest)p; this.requestCache.Add(GetUniqueMessageId(tcpSession, createRequest.Smb2Packet.MessageID), createRequest); } else if (p is Packets.Smb2Packet.Smb2CreateResponse) { Packets.Smb2Packet.Smb2CreateResponse createResponse = (Packets.Smb2Packet.Smb2CreateResponse)p; if (createResponse.IsValidCreateResponse) { Guid fileId = createResponse.FileID; //get request string requestId = GetUniqueMessageId(tcpSession, createResponse.Smb2Packet.MessageID); if (this.requestCache.ContainsKey(requestId)) { #if DEBUG System.Diagnostics.Debug.Assert(this.requestCache[requestId] is Packets.Smb2Packet.Smb2CreateRequest, "Wrong SMB2 request type for Message ID " + requestId + "!"); #endif Packets.Smb2Packet.Smb2CreateRequest createRequest = (Packets.Smb2Packet.Smb2CreateRequest) this.requestCache[requestId]; string filename = createRequest.FileName; if (filename != null && filename.Length > 0) { string uniqueFileId = GetUniqueGuid(tcpSession, fileId); this.fileIdFilenameMap.Add(uniqueFileId, filename); System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection(); //parameters.Add(fileId.ToString(), filename); parameters.Add(filename, "File ID: " + fileId.ToString()); base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(p.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parameters, p.ParentFrame.Timestamp, "SMB2 Create Response")); } } } } else if (p is Packets.Smb2Packet.Smb2ReadRequest) { Packets.Smb2Packet.Smb2ReadRequest readRequest = (Packets.Smb2Packet.Smb2ReadRequest)p; this.requestCache.Add(GetUniqueMessageId(tcpSession, readRequest.Smb2Packet.MessageID), readRequest); } else if (p is Packets.Smb2Packet.Smb2ReadResponse) { Packets.Smb2Packet.Smb2ReadResponse readResponse = (Packets.Smb2Packet.Smb2ReadResponse)p; //get request string requestId = GetUniqueMessageId(tcpSession, readResponse.Smb2Packet.MessageID); if (this.requestCache.ContainsKey(requestId)) { #if DEBUG System.Diagnostics.Debug.Assert(this.requestCache[requestId] is Packets.Smb2Packet.Smb2ReadRequest, "Wrong SMB2 request type for Message ID " + requestId + "!"); #endif Packets.Smb2Packet.Smb2ReadRequest readRequest = (Packets.Smb2Packet.Smb2ReadRequest) this.requestCache[requestId]; Guid fileId = readRequest.FileId; FileTransfer.FileSegmentAssembler assembler = this.GetOrCreateAssembler(tcpSession, false, fileId, OP_CODE.Read); if (assembler != null) { assembler.AddData(readRequest.FileOffset, readResponse.FileData, p.ParentFrame); } } } else if (p is Packets.Smb2Packet.Smb2WriteRequest) { Packets.Smb2Packet.Smb2WriteRequest writeRequest = (Packets.Smb2Packet.Smb2WriteRequest)p; Guid fileId = writeRequest.FileID; long fileOffset = writeRequest.FileOffset; byte[] fileData = writeRequest.FileData; //this.requestCache.Add(GetUniqueMessageId(tcpSession, writeRequest.Smb2Packet.MessageID), writeRequest); //TODO get fileSegmentAssembler and add data FileTransfer.FileSegmentAssembler assembler = this.GetOrCreateAssembler(tcpSession, true, fileId, OP_CODE.Write); if (assembler != null) { assembler.AddData(fileOffset, fileData, p.ParentFrame); } } else if (p is Packets.Smb2Packet.Smb2SetInfoRequest) { Packets.Smb2Packet.Smb2SetInfoRequest setInfoRequest = (Packets.Smb2Packet.Smb2SetInfoRequest)p; if (setInfoRequest.EndOfFile != null && setInfoRequest.EndOfFile > 0) { Guid fileId = setInfoRequest.FileID; FileTransfer.FileSegmentAssembler assembler = this.GetOrCreateAssembler(tcpSession, true, fileId, OP_CODE.SetInfo); assembler.FileSize = setInfoRequest.EndOfFile.Value; } } else if (p is Smb2CloseRequest) { Smb2CloseRequest closeRequest = (Smb2CloseRequest)p; //Guid fileId = closeRequest.FileID; //ulong messageId = closeRequest.Smb2Packet.MessageID; this.requestCache.Add(GetUniqueMessageId(tcpSession, closeRequest.Smb2Packet.MessageID), closeRequest); } else if (p is Smb2CloseResponse) { Smb2CloseResponse closeResponse = (Smb2CloseResponse)p; //get request string requestId = GetUniqueMessageId(tcpSession, closeResponse.Smb2Packet.MessageID); if (this.requestCache.ContainsKey(requestId)) { #if DEBUG System.Diagnostics.Debug.Assert(this.requestCache[requestId] is Packets.Smb2Packet.Smb2CloseRequest, "Wrong SMB2 request type for Message ID " + requestId + "!"); #endif Packets.Smb2Packet.Smb2CloseRequest closeRequest = (Packets.Smb2Packet.Smb2CloseRequest) this.requestCache[requestId]; Guid fileId = closeRequest.FileID; //ulong messageId = closeRequest.Smb2Packet.MessageID; long fileSize = closeResponse.EndOfFile; string uniqueFileId = GetUniqueGuid(tcpSession, fileId); if (this.fileSegmentAssemblerList.ContainsKey(uniqueFileId)) { FileTransfer.FileSegmentAssembler assmebler = this.fileSegmentAssemblerList[uniqueFileId]; assmebler.FileSize = fileSize; assmebler.AssembleAndClose(); } } } else if (p is Smb2FindRequest) { Smb2FindRequest findRequest = (Smb2FindRequest)p; this.requestCache.Add(GetUniqueMessageId(tcpSession, findRequest.Smb2Packet.MessageID), findRequest); System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection(); parameters.Add("SMB2 Search Pattern", findRequest.SearchPattern); base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(p.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parameters, p.ParentFrame.Timestamp, "SMB2 Find Request")); } else if (p is Smb2FindResponse) { Smb2FindResponse findResponse = (Smb2FindResponse)p; Smb2FindRequest findRequest = null; string requestId = GetUniqueMessageId(tcpSession, findResponse.Smb2Packet.MessageID); if (this.requestCache.ContainsKey(requestId)) { findRequest = (Smb2FindRequest)this.requestCache[requestId]; } System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection(); foreach (Smb2FileInfo fi in findResponse.FileInfoList) { if (fi.Data.Length > 0) { if (findRequest != null && findRequest.InfoLevel == (byte)Smb2Packet.Smb2FindRequest.InfoLevelEnum.NAME_INFO) { Packets.Smb2Packet.Smb2FileNameInfo nameInfoResponse = new Smb2FileNameInfo(fi.Data, 0, fi.Data.Length, findRequest.InfoLevel); parameters.Add("Search result for \"" + findRequest.SearchPattern + "\"", nameInfoResponse.Filename); } else if (findRequest != null && (findRequest.InfoLevel == (byte)Smb2Packet.Smb2FindRequest.InfoLevelEnum.BOTH_DIRECTORY_INFO || findRequest.InfoLevel == (byte)Smb2Packet.Smb2FindRequest.InfoLevelEnum.ID_BOTH_DIRECTORY_INFO)) { Packets.Smb2Packet.Smb2FileBothDirectoryInfo nameInfoResponse = new Smb2FileBothDirectoryInfo(fi.Data, 0, fi.Data.Length, findRequest.InfoLevel); parameters.Add("Search result for \"" + findRequest.SearchPattern + "\"", nameInfoResponse.Filename); parameters.Add(nameInfoResponse.Filename, "Created: " + nameInfoResponse.Created.ToString()); parameters.Add(nameInfoResponse.Filename, "Modified: " + nameInfoResponse.Modified.ToString()); parameters.Add(nameInfoResponse.Filename, "Accessed: " + nameInfoResponse.Accessed.ToString()); //parameters.Add(nameInfoResponse.Filename, "Modified: " + nameInfoResponse.AttributeChanged.ToString()); } else { //we don't have the findRequest so we don't know what data type the responses are or how to format them //A likely guess is that we're seeing a response of type NAME_INFO, but this isn't very crucial info, //so it's better to just ignore this response. } } } if (parameters.Count > 0) { base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(p.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parameters, p.ParentFrame.Timestamp, "SMB2 File Info")); } } } return(0);//NetBiosSessionServicePacketHandler will return the # parsed bytes anyway. }