//public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable<Packets.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; * }*/ Packets.TcpPacket tcpPacket = null; Packets.FtpPacket ftpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } else if (p.GetType() == typeof(Packets.FtpPacket)) { ftpPacket = (Packets.FtpPacket)p; } } FtpSession ftpSession = null;//we can only have one FtpSession per packet... //bool returnValue=false; int parsedBytes = 0; if (tcpSession.SynPacketReceived && tcpSession.SynAckPacketReceived) { //start by checking if this is an incoming file transfer through FTP if (!tcpSession.SessionEstablished) { //we now have an upcoming session //see if it matches the pending FTP data sessions if (this.pendingFileTransferList.ContainsKey(PendingFileTransfer.GetKey(tcpSession.ClientHost, tcpSession.ClientTcpPort, tcpSession.ServerHost, tcpSession.ServerTcpPort))) { PendingFileTransfer pending = this.pendingFileTransferList[PendingFileTransfer.GetKey(tcpSession.ClientHost, tcpSession.ClientTcpPort, tcpSession.ServerHost, tcpSession.ServerTcpPort)]; pending.FileTransferSessionEstablished = true; ftpSession = pending.FtpControlSession; //returnValue=true;//we managed to get some data out of this! parsedBytes = tcpPacket.PayloadDataLength; } //see if the client port was unknown else if (this.pendingFileTransferList.ContainsKey(PendingFileTransfer.GetKey(tcpSession.ClientHost, null, tcpSession.ServerHost, tcpSession.ServerTcpPort))) { PendingFileTransfer pending = this.pendingFileTransferList[PendingFileTransfer.GetKey(tcpSession.ClientHost, null, tcpSession.ServerHost, tcpSession.ServerTcpPort)]; this.pendingFileTransferList.Remove(pending.GetKey()); pending.DataSessionClientPort = tcpSession.ClientTcpPort;//the Key will now be changed! pending.FileTransferSessionEstablished = true; this.pendingFileTransferList.Add(pending.GetKey(), pending); ftpSession = pending.FtpControlSession; //returnValue=true; parsedBytes = tcpPacket.PayloadDataLength; } }//end check for new FTP DATA sessions else if (tcpPacket != null && tcpPacket.FlagBits.Fin) { //check if there is an FTP data session being closed if (this.MainPacketHandler.FileStreamAssemblerList.ContainsAssembler(tcpSession.Flow.FiveTuple, transferIsClientToServer, true, PacketParser.FileTransfer.FileStreamTypes.FTP)) { PacketParser.FileTransfer.FileStreamAssembler assembler = this.MainPacketHandler.FileStreamAssemblerList.GetAssembler(tcpSession.Flow.FiveTuple, transferIsClientToServer); if (assembler.FileContentLength == -1 && assembler.FileSegmentRemainingBytes == -1) { //TODO: see if all data has been received or if the FIN arrived before the final data packet assembler.FinishAssembling(); } } } } if (ftpPacket != null && tcpPacket != null) { //returnValue=true; parsedBytes = ftpPacket.PacketLength; if (ftpSessionList.ContainsKey(tcpSession)) { ftpSession = ftpSessionList[tcpSession]; } else { ftpSession = new FtpSession(tcpSession.ClientHost, tcpSession.ServerHost); this.ftpSessionList.Add(tcpSession, ftpSession); } /* * 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; * } */ if (ftpPacket.ClientToServer) { if (ftpPacket.RequestCommand != null) { if (ftpPacket.RequestArgument != null) { System.Collections.Specialized.NameValueCollection tmpCol = new System.Collections.Specialized.NameValueCollection(); tmpCol.Add(ftpPacket.RequestCommand, ftpPacket.RequestArgument); base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(ftpPacket.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, tmpCol, ftpPacket.ParentFrame.Timestamp, "FTP Request")); } if (ftpPacket.RequestCommand.ToUpper() == "USER")//username { ftpSession.Username = ftpPacket.RequestArgument; } else if (ftpPacket.RequestCommand.ToUpper() == "PASS")//password { ftpSession.Password = ftpPacket.RequestArgument; if (ftpSession.Username != null && ftpSession.Password != null) { base.MainPacketHandler.AddCredential(new NetworkCredential(tcpSession.ClientHost, tcpSession.ServerHost, ftpPacket.PacketTypeDescription, ftpSession.Username, ftpSession.Password, ftpPacket.ParentFrame.Timestamp)); } } else if (ftpPacket.RequestCommand.ToUpper() == "PORT") { ushort clientListeningOnPort; if (TryGetPort(ftpPacket.RequestArgument, out clientListeningOnPort)) { //ftpSession.ActiveMode=true; //ftpSession.ClientDataListenerTcpPort=this.GetPort(ftpPacket.RequestArgument); //ftpSession.PendingFileTransfer=new PendingFileTransfer(ftpSession.ServerHost, (ushort)20, ftpSession.ClientHost, clientListeningOnPort, false, ftpSession); ftpSession.PendingFileTransfer = new PendingFileTransfer(ftpSession.ServerHost, null, ftpSession.ClientHost, clientListeningOnPort, false, ftpSession); if (this.pendingFileTransferList.ContainsKey(ftpSession.PendingFileTransfer.GetKey())) { this.pendingFileTransferList.Remove(ftpSession.PendingFileTransfer.GetKey()); } this.pendingFileTransferList.Add(ftpSession.PendingFileTransfer.GetKey(), ftpSession.PendingFileTransfer); } } else if (ftpPacket.RequestCommand.ToUpper() == "STOR")//file upload (client -> server) //set filename and file direction { if (ftpSession.PendingFileTransfer != null) { ftpSession.PendingFileTransfer.Filename = ftpPacket.RequestArgument; ftpSession.PendingFileTransfer.FileDirectionIsDataSessionServerToDataSessionClient = !ftpSession.PendingFileTransfer.DataSessionIsPassive; ftpSession.PendingFileTransfer.Details = ftpPacket.RequestCommand + " " + ftpPacket.RequestArgument; } else { //ftpPacket.ParentFrame.Errors.Add(new Frame.Error(ftpPacket.ParentFrame, ftpPacket.PacketStartIndex, ftpPacket.PacketEndIndex, "STOR command without a pending ftp data session")); this.MainPacketHandler.OnAnomalyDetected("STOR command without a pending ftp data session. Frame: " + ftpPacket.ParentFrame.ToString(), ftpPacket.ParentFrame.Timestamp); //System.Diagnostics.Debugger.Break();//this should not occur! } } else if (ftpPacket.RequestCommand.ToUpper() == "RETR")//file download (server -> client) { if (ftpSession.PendingFileTransfer != null) { ftpSession.PendingFileTransfer.Filename = ftpPacket.RequestArgument; ftpSession.PendingFileTransfer.FileDirectionIsDataSessionServerToDataSessionClient = ftpSession.PendingFileTransfer.DataSessionIsPassive; ftpSession.PendingFileTransfer.Details = ftpPacket.RequestCommand + " " + ftpPacket.RequestArgument; } else { //System.Diagnostics.Debugger.Break();//this should not iccur //ftpPacket.ParentFrame.Errors.Add(new Frame.Error(ftpPacket.ParentFrame, ftpPacket.PacketStartIndex, ftpPacket.PacketEndIndex, "RETR command without a pending ftp data session")); this.MainPacketHandler.OnAnomalyDetected("RETR command without a pending ftp data session. Frame: " + ftpPacket.ParentFrame.ToString(), ftpPacket.ParentFrame.Timestamp); } } else if (ftpPacket.RequestCommand.ToUpper() == "SIZE") { ftpSession.PendingSizeRequestFileName = ftpPacket.RequestArgument; } } } else //server to client packet { if (ftpPacket.ResponseCode != 0 && ftpPacket.ResponseArgument != null) { System.Collections.Specialized.NameValueCollection tmpCol = new System.Collections.Specialized.NameValueCollection(); tmpCol.Add(ftpPacket.ResponseCode.ToString(), ftpPacket.ResponseArgument); MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(ftpPacket.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, tmpCol, ftpPacket.ParentFrame.Timestamp, "FTP Response")); //look for an FTP banner if (ftpPacket.ResponseCode == 220 && ftpPacket.ResponseArgument.ToLower().Contains("ftp")) { tcpSession.Flow.FiveTuple.ServerHost.AddFtpServerBanner(ftpPacket.ResponseArgument, tcpPacket.SourcePort); } } if (ftpPacket.ResponseCode == 213 && ftpSession.PendingSizeRequestFileName != null)//File size response { int fileSize; if (Int32.TryParse(ftpPacket.ResponseArgument, out fileSize)) { ftpSession.FileSizes[ftpSession.PendingSizeRequestFileName] = fileSize; } //ftpSession.FileSizes.Add(ftpSession.PendingSizeRequestFileName, fileSize); ftpSession.PendingSizeRequestFileName = null; } if (ftpPacket.ResponseCode == 226)//File receive OK //close file stream assembler? { } else if (ftpPacket.ResponseCode == 227) //Entering Passive Mode - Response to client "PASV" command //From: http://cr.yp.to/ftp/retr.html //Many servers put different strings before h1 and after p2. //I recommend that clients use the following strategy to parse the //response line: look for the first digit after the initial space; //look for the fourth comma after that digit; read two (possibly negative) //integers, separated by a comma; the TCP port number is p1*256+p2, //where p1 is the first integer modulo 256 and p2 is the second integer //modulo 256. //it is probably simpler to do this with RegEx, but this is simple enough so I wont bother with RegEx for now... { char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; string ipAndPort = ftpPacket.ResponseArgument.Substring(ftpPacket.ResponseArgument.IndexOfAny(digits)); //string ipAndPort=ftpPacket.ResponseArgument.Substring(ftpPacket.ResponseArgument.IndexOf('(')+1); ipAndPort = ipAndPort.Substring(0, ipAndPort.LastIndexOfAny(digits) + 1); //ipAndPort=ipAndPort.Substring(0, ipAndPort.IndexOf(')')); ushort serverListeningOnPort; if (this.TryGetPort(ipAndPort, out serverListeningOnPort)) { ftpSession.PendingFileTransfer = new PendingFileTransfer(ftpSession.ClientHost, null, ftpSession.ServerHost, serverListeningOnPort, true, ftpSession); if (this.pendingFileTransferList.ContainsKey(ftpSession.PendingFileTransfer.GetKey())) { this.pendingFileTransferList.Remove(ftpSession.PendingFileTransfer.GetKey()); } this.pendingFileTransferList.Add(ftpSession.PendingFileTransfer.GetKey(), ftpSession.PendingFileTransfer); } } else if (ftpPacket.ResponseCode == 230)//Login successful //ftpSession.=ftpPacket.RequestArgument; { if (ftpSession.Username != null && ftpSession.Password != null) { base.MainPacketHandler.AddCredential(new NetworkCredential(tcpSession.ClientHost, tcpSession.ServerHost, ftpPacket.PacketTypeDescription, ftpSession.Username, ftpSession.Password, true, ftpPacket.ParentFrame.Timestamp)); } } else if (ftpPacket.ResponseCode == 234) //server response to an 'AUTH TLS' command rfc4217 and rfc2228 /** * If the server is willing to accept the named security mechanism, * and does not require any security data, it must respond with reply * code 234. **/ //Unfortunately we haven't stored the request, so we can't know if the client was asking for TLS or some other security measure { if (ftpPacket.ResponseArgument.Contains("TLS") || ftpPacket.ResponseArgument.Contains("SSL")) { tcpSession.ProtocolFinder.SetConfirmedApplicationLayerProtocol(ApplicationLayerProtocol.Ssl, false); } } }//end server to client } if (ftpSession != null && ftpSession.PendingFileTransfer != null) { //I guess returnValue is already set to true by now, but I'll do it again just to be sure... if (parsedBytes == 0) { parsedBytes = tcpPacket.PayloadDataLength; } //returnValue=true; PendingFileTransfer pending = ftpSession.PendingFileTransfer; //see if the pending file transfer could be transformed into a real file stream assembler if (pending.FileTransferSessionEstablished && pending.FileDirectionIsDataSessionServerToDataSessionClient != null && pending.DataSessionClientPort != null) { //Server->Client ? FileTransfer.FileStreamAssembler.FileAssmeblyRootLocation fileAssemblyLocation; if ((ftpSession.ServerHost == pending.DataSessionServer) == pending.FileDirectionIsDataSessionServerToDataSessionClient.Value) { fileAssemblyLocation = FileTransfer.FileStreamAssembler.FileAssmeblyRootLocation.source; } else { fileAssemblyLocation = FileTransfer.FileStreamAssembler.FileAssmeblyRootLocation.destination; } FileTransfer.FileStreamAssembler assembler = new FileTransfer.FileStreamAssembler(MainPacketHandler.FileStreamAssemblerList, pending.GetFiveTuple(), !pending.FileDirectionIsDataSessionServerToDataSessionClient.Value, FileTransfer.FileStreamTypes.FTP, pending.Filename, "/", pending.Details, tcpPacket.ParentFrame.FrameNumber, tcpPacket.ParentFrame.Timestamp, fileAssemblyLocation); string fileCompletePath = ""; if (assembler.Filename != null && assembler.FileLocation != null) { fileCompletePath = assembler.FileLocation + "/" + assembler.Filename; } if (ftpSession.FileSizes.ContainsKey(fileCompletePath)) { assembler.FileContentLength = ftpSession.FileSizes[fileCompletePath]; assembler.FileSegmentRemainingBytes = ftpSession.FileSizes[fileCompletePath]; } else { //-1 is set instead of null if Content-Length is not defined assembler.FileContentLength = -1; assembler.FileSegmentRemainingBytes = -1; } if (assembler.TryActivate()) { MainPacketHandler.FileStreamAssemblerList.Add(assembler); } //assembler.Activate(); //the file transfer is no longer pending since the assembler is started! pendingFileTransferList.Remove(pending.GetKey()); ftpSession.PendingFileTransfer = null; } } return(parsedBytes); }
//public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable<Packets.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; } //bool successfulExtraction=false; int successfullyExtractedBytes = 0; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.NtlmSspPacket)) { Packets.NtlmSspPacket ntlmPacket = (Packets.NtlmSspPacket)p; if (ntlmPacket.NtlmChallenge != null) { if (ntlmChallengeList.ContainsKey(tcpSession.GetHashCode())) { ntlmChallengeList[tcpSession.GetHashCode()] = ntlmPacket.NtlmChallenge; } else { ntlmChallengeList.Add(tcpSession.GetHashCode(), ntlmPacket.NtlmChallenge); } } if (ntlmPacket.DomainName != null) { sourceHost.AddDomainName(ntlmPacket.DomainName); } if (ntlmPacket.HostName != null) { sourceHost.AddHostName(ntlmPacket.HostName); } if (ntlmPacket.UserName != null) { if (ntlmPacket.UserName.EndsWith("$")) //hostname { sourceHost.AddHostName(ntlmPacket.UserName.TrimEnd(new[] { '$' })); } else { sourceHost.AddNumberedExtraDetail("NTLM Username ", ntlmPacket.UserName); } string lanManagerHashInfo = null; if (ntlmPacket.LanManagerResponse != null) { lanManagerHashInfo = "LAN Manager Response: " + ntlmPacket.LanManagerResponse; } if (ntlmPacket.NtlmResponse != null) { if (lanManagerHashInfo == null) { lanManagerHashInfo = ""; } else { lanManagerHashInfo = lanManagerHashInfo + " - "; } lanManagerHashInfo = lanManagerHashInfo + "NTLM Response: " + ntlmPacket.NtlmResponse; } if (lanManagerHashInfo == null) { base.MainPacketHandler.AddCredential(new NetworkCredential(sourceHost, destinationHost, "NTLMSSP", ntlmPacket.UserName, ntlmPacket.ParentFrame.Timestamp)); } else { if (ntlmChallengeList.ContainsKey(tcpSession.GetHashCode())) { lanManagerHashInfo = "NTLM Challenge: " + ntlmChallengeList[tcpSession.GetHashCode()] + " - " + lanManagerHashInfo; } if (ntlmPacket.DomainName == null) { base.MainPacketHandler.AddCredential(new NetworkCredential(sourceHost, destinationHost, "NTLMSSP", ntlmPacket.UserName, lanManagerHashInfo, ntlmPacket.ParentFrame.Timestamp)); } else { base.MainPacketHandler.AddCredential(new NetworkCredential(sourceHost, destinationHost, "NTLMSSP", ntlmPacket.DomainName + "\\" + ntlmPacket.UserName, lanManagerHashInfo, ntlmPacket.ParentFrame.Timestamp)); } } } successfullyExtractedBytes += ntlmPacket.ParentFrame.Data.Length;//it's OK to return a larger value that what was parsed } } return(successfullyExtractedBytes); }
//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; * }*/ Packets.ImapPacket imapPacket = null; Packets.TcpPacket tcpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } else if (p.GetType() == typeof(Packets.ImapPacket)) { imapPacket = (Packets.ImapPacket)p; } } if (tcpPacket != null && (tcpPacket.SourcePort == 220 || tcpPacket.SourcePort == 143) && this.lastCommand.ContainsKey(tcpSession) && this.lastCommand[tcpSession] == ImapPacket.ClientCommand.UID && this.serverToClientEmailReassemblers.ContainsKey(tcpSession)) { return(this.ExtractEmail(tcpSession, tcpPacket, tcpPacket.PacketStartIndex + tcpPacket.DataOffsetByteCount, tcpPacket.PayloadDataLength)); } else if (tcpPacket != null && (tcpPacket.DestinationPort == 220 || tcpPacket.DestinationPort == 143) && this.lastCommand.ContainsKey(tcpSession) && this.lastCommand[tcpSession] == ImapPacket.ClientCommand.APPEND && this.clientToServerEmailReassemblers.ContainsKey(tcpSession)) { return(this.ExtractEmail(tcpSession, tcpPacket, tcpPacket.PacketStartIndex + tcpPacket.DataOffsetByteCount, tcpPacket.PayloadDataLength)); } else if (tcpPacket != null && imapPacket != null) { if (imapPacket.ClientToServer) { if (imapPacket.Command != null) { if (lastCommand.ContainsKey(tcpSession)) { lastCommand[tcpSession] = imapPacket.Command.Value; } else { lastCommand.Add(tcpSession, imapPacket.Command.Value); } if (imapPacket.FullRequestOrResponseLine != null && imapPacket.FullRequestOrResponseLine.Length > 0) { System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection(); parameters.Add(imapPacket.Command.Value.ToString(), imapPacket.FullRequestOrResponseLine); base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(imapPacket.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parameters, imapPacket.ParentFrame.Timestamp, "IMAP Client Command")); } //remove any old email reassemblers since we have now received a new command if (this.serverToClientEmailReassemblers.ContainsKey(tcpSession)) { this.serverToClientEmailReassemblers[tcpSession].Close(); this.serverToClientEmailReassemblers.Remove(tcpSession);//we will need to create a new reassembler } if (imapPacket.Command == ImapPacket.ClientCommand.APPEND) { //an email is being uploaded to the server if (imapPacket.BodyLength > 0) { int emailBytes = this.ExtractEmail(tcpSession, tcpPacket, imapPacket.PacketStartIndex + imapPacket.ParsedBytesCount, imapPacket.PacketLength - imapPacket.ParsedBytesCount, imapPacket.BodyLength, true); imapPacket.ParsedBytesCount += emailBytes; } } else if (imapPacket.Command == ImapPacket.ClientCommand.LOGIN) { string[] args = imapPacket.FullRequestOrResponseLine.Split(new char[] { ' ' }); char[] quoteChars = new char[] { '\'', '"' }; //a001 LOGIN SMITH SESAME if (args.Length > 3) { string username = args[2].Trim(quoteChars); string password = args[3].Trim(quoteChars); NetworkCredential cred = new NetworkCredential(tcpSession.ClientHost, tcpSession.ServerHost, "IMAP", username, password, imapPacket.ParentFrame.Timestamp); //base.MainPacketHandler.OnCredentialDetected(new Events.CredentialEventArgs(cred)); base.MainPacketHandler.AddCredential(cred); } } } else if (lastCommand.ContainsKey(tcpSession) && lastCommand[tcpSession] == ImapPacket.ClientCommand.AUTHENTICATE) { if (imapPacket.FullRequestOrResponseLine != null && imapPacket.FullRequestOrResponseLine.Length > 0) { string base64 = imapPacket.FullRequestOrResponseLine; NetworkCredential cred = SmtpPacketHandler.ExtractBase64EncodedAuthPlainCredential(base64, imapPacket.ParentFrame, tcpSession, ApplicationLayerProtocol.Imap); if (cred != null) { //base.MainPacketHandler.OnCredentialDetected(new Events.CredentialEventArgs(cred)); base.MainPacketHandler.AddCredential(cred); if (imapPacket.ParsedBytesCount == 0) { imapPacket.ParsedBytesCount = base64.Length + 2;//add CRLF } } } } } else //server to client { if (imapPacket.Result != null && imapPacket.FullRequestOrResponseLine != null && imapPacket.FullRequestOrResponseLine.Length > 0) { System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection(); parameters.Add(imapPacket.Result.Value.ToString(), imapPacket.FullRequestOrResponseLine); base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(imapPacket.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parameters, imapPacket.ParentFrame.Timestamp, "IMAP Server Response")); } if (lastCommand.ContainsKey(tcpSession) && (lastCommand[tcpSession] == ImapPacket.ClientCommand.FETCH || lastCommand[tcpSession] == ImapPacket.ClientCommand.UID)) { if (imapPacket.Command != null && imapPacket.FullRequestOrResponseLine != null && imapPacket.FullRequestOrResponseLine.Length > 0) { System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection(); parameters.Add(imapPacket.Command.Value.ToString(), imapPacket.FullRequestOrResponseLine); base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(imapPacket.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parameters, imapPacket.ParentFrame.Timestamp, "IMAP Untagged Response")); } //the server might push an email here if (imapPacket.BodyLength > 0) { int emailBytes = this.ExtractEmail(tcpSession, tcpPacket, imapPacket.PacketStartIndex + imapPacket.ParsedBytesCount, imapPacket.PacketLength - imapPacket.ParsedBytesCount, imapPacket.BodyLength, false); if (imapPacket.ParenthesesDiff > 0 && imapPacket.ParsedBytesCount + emailBytes < imapPacket.PacketLength) { //we might have a trailing line that closes the parenthesis, let's read that one too int index = imapPacket.PacketStartIndex + imapPacket.ParsedBytesCount + emailBytes; string trailingLine = Utils.ByteConverter.ReadLine(imapPacket.ParentFrame.Data, ref index); int trailingParenthesesDiff = trailingLine.Split('(').Length - trailingLine.Split(')').Length; if (imapPacket.ParenthesesDiff + trailingParenthesesDiff == 0) { return(index - imapPacket.PacketStartIndex); } else { return(imapPacket.ParsedBytesCount + emailBytes); } } else { return(imapPacket.ParsedBytesCount + emailBytes); } } } else if (lastCommand.ContainsKey(tcpSession) && (lastCommand[tcpSession] == ImapPacket.ClientCommand.STARTTLS)) { if (imapPacket.Result == ImapPacket.ServerResult.OK) { //1 OK Begin TLS negotiation now //do the same protocol switch trick as in SocksPacketHandler //tcpSession.ProtocolFinder = new TcpPortProtocolFinder(tcpSession.ClientHost, tcpSession.ServerHost, tcpSession.ClientTcpPort, tcpSession.ServerTcpPort, tcpPacket.ParentFrame.FrameNumber, tcpPacket.ParentFrame.Timestamp, base.MainPacketHandler); tcpSession.ProtocolFinder.SetConfirmedApplicationLayerProtocol(ApplicationLayerProtocol.Ssl, false); } } } return(imapPacket.ParsedBytesCount); } else { return(0); } }
public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable <Packets.AbstractPacket> packetList) { //bool successfulExtraction=false; int successfullyExtractedBytes = 0; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.NtlmSspPacket)) { Packets.NtlmSspPacket ntlmPacket = (Packets.NtlmSspPacket)p; if (ntlmPacket.NtlmChallenge != null) { if (ntlmChallengeList.ContainsKey(tcpSession.GetHashCode())) { ntlmChallengeList[tcpSession.GetHashCode()] = ntlmPacket.NtlmChallenge; } else { ntlmChallengeList.Add(tcpSession.GetHashCode(), ntlmPacket.NtlmChallenge); } } if (ntlmPacket.DomainName != null) { sourceHost.AddDomainName(ntlmPacket.DomainName); } if (ntlmPacket.HostName != null) { sourceHost.AddHostName(ntlmPacket.HostName); } if (ntlmPacket.UserName != null) { if (!sourceHost.ExtraDetailsList.ContainsKey("NTLM Username " + ntlmPacket.UserName)) { sourceHost.ExtraDetailsList.Add("NTLM Username " + ntlmPacket.UserName, ntlmPacket.UserName); } string lanManagerHashInfo = null; if (ntlmPacket.LanManagerResponse != null) { lanManagerHashInfo = "LAN Manager Response: " + ntlmPacket.LanManagerResponse; } if (ntlmPacket.NtlmResponse != null) { if (lanManagerHashInfo == null) { lanManagerHashInfo = ""; } else { lanManagerHashInfo = lanManagerHashInfo + " - "; } lanManagerHashInfo = lanManagerHashInfo + "NTLM Response: " + ntlmPacket.NtlmResponse; } if (lanManagerHashInfo == null) { base.MainPacketHandler.AddCredential(new NetworkCredential(sourceHost, destinationHost, "NTLMSSP", ntlmPacket.UserName, ntlmPacket.ParentFrame.Timestamp)); } else { if (ntlmChallengeList.ContainsKey(tcpSession.GetHashCode())) { lanManagerHashInfo = "NTLM Challenge: " + ntlmChallengeList[tcpSession.GetHashCode()] + " - " + lanManagerHashInfo; } base.MainPacketHandler.AddCredential(new NetworkCredential(sourceHost, destinationHost, "NTLMSSP", ntlmPacket.UserName, lanManagerHashInfo, ntlmPacket.ParentFrame.Timestamp)); } } successfullyExtractedBytes += ntlmPacket.ParentFrame.Data.Length;//it's OK to return a larger value that what was parsed } } return(successfullyExtractedBytes); }
//public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable<Packets.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; } //bool successfulExtraction=false; int successfullyExtractedBytes = 0; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.NtlmSspPacket)) { Packets.NtlmSspPacket ntlmPacket = (Packets.NtlmSspPacket)p; if (ntlmPacket.NtlmChallenge != null) { if (ntlmChallengeList.ContainsKey(tcpSession.GetHashCode())) { ntlmChallengeList[tcpSession.GetHashCode()] = ntlmPacket.NtlmChallenge; } else { ntlmChallengeList.Add(tcpSession.GetHashCode(), ntlmPacket.NtlmChallenge); } } if (ntlmPacket.DomainName != null) { sourceHost.AddDomainName(ntlmPacket.DomainName); } if (ntlmPacket.HostName != null) { sourceHost.AddHostName(ntlmPacket.HostName, ntlmPacket.PacketTypeDescription); } if (ntlmPacket.UserName != null) { if (ntlmPacket.UserName.EndsWith("$")) //hostname { sourceHost.AddHostName(ntlmPacket.UserName.TrimEnd(new[] { '$' }), ntlmPacket.PacketTypeDescription); } else { sourceHost.AddNumberedExtraDetail("NTLM Username ", ntlmPacket.UserName); } string lanManagerHashInfo = null; if (ntlmPacket.LanManagerResponse != null) { lanManagerHashInfo = "LAN Manager Response: " + ntlmPacket.LanManagerResponse; if (ntlmPacket.LanManagerResponse.Length >= 16) { //$LM$a9c604d244c4e99d string lmHash = ntlmPacket.LanManagerResponse.Substring(0, 16); if (lmHash.Trim(new[] { '0' }).Length > 0) { base.MainPacketHandler.AddCredential(new NetworkCredential(sourceHost, destinationHost, "NTLMSSP", ntlmPacket.DomainName + "\\" + ntlmPacket.UserName, "$LM$" + lmHash, ntlmPacket.ParentFrame.Timestamp)); } } } if (ntlmPacket.NtlmResponse != null) { if (lanManagerHashInfo == null) { lanManagerHashInfo = ""; } else { lanManagerHashInfo = lanManagerHashInfo + " - "; } lanManagerHashInfo = lanManagerHashInfo + "NTLM Response: " + ntlmPacket.NtlmResponse; } if (lanManagerHashInfo == null) { base.MainPacketHandler.AddCredential(new NetworkCredential(sourceHost, destinationHost, "NTLMSSP", ntlmPacket.UserName, ntlmPacket.ParentFrame.Timestamp)); } else { string ntlmChallenge = null; if (ntlmChallengeList.ContainsKey(tcpSession.GetHashCode())) { ntlmChallenge = ntlmChallengeList[tcpSession.GetHashCode()]; lanManagerHashInfo = "NTLM Challenge: " + ntlmChallenge + " - " + lanManagerHashInfo; } if (ntlmPacket.DomainName == null) { base.MainPacketHandler.AddCredential(new NetworkCredential(sourceHost, destinationHost, "NTLMSSP", ntlmPacket.UserName, lanManagerHashInfo, ntlmPacket.ParentFrame.Timestamp)); } else { base.MainPacketHandler.AddCredential(new NetworkCredential(sourceHost, destinationHost, "NTLMSSP", ntlmPacket.DomainName + "\\" + ntlmPacket.UserName, lanManagerHashInfo, ntlmPacket.ParentFrame.Timestamp)); } if (ntlmChallenge != null && ntlmPacket.NtlmResponse != null) { string johnHash = null; if (ntlmPacket.NtlmResponse.Length == 48) //24 bytes of binary data => NTLMv1 //example: $NETNTLM$1122334455667788$B2B2220790F40C88BCFF347C652F67A7C4A70D3BEBD70233 { johnHash = "$NETNTLM$" + ntlmChallenge + "$" + ntlmPacket.NtlmResponse; } else if (ntlmPacket.NtlmResponse.Length > 48) //NTLMv2 //example: $NETNTLMv2$NTLMV2TESTWORKGROUP$1122334455667788$07659A550D5E9D02996DFD95C87EC1D5$0101000000000000006CF6385B74CA01B3610B02D99732DD000000000200120057004F0052004B00470052004F00550050000100200044004100540041002E00420049004E0043002D0053004500430055005200490000000000 { StringBuilder johnHashSB = new StringBuilder("$NETNTLMv2$"); if (ntlmPacket.DomainName != null) { johnHashSB.Append(ntlmPacket.DomainName); } johnHashSB.Append("$"); johnHashSB.Append(ntlmChallenge); johnHashSB.Append("$"); johnHashSB.Append(ntlmPacket.NtlmResponse.Substring(0, 32)); //NTProofStr johnHashSB.Append("$"); johnHashSB.Append(ntlmPacket.NtlmResponse.Substring(32)); //NTLMv2 response, minus NTProofStr johnHash = johnHashSB.ToString(); } if (johnHash != null) { base.MainPacketHandler.AddCredential(new NetworkCredential(sourceHost, destinationHost, "NTLMSSP", ntlmPacket.DomainName + "\\" + ntlmPacket.UserName, johnHash, ntlmPacket.ParentFrame.Timestamp)); } } } } successfullyExtractedBytes += ntlmPacket.ParentFrame.Data.Length;//it's OK to return a larger value that what was parsed } } return(successfullyExtractedBytes); }