Пример #1
0
        private int ExtractEmail(NetworkTcpSession tcpSession, TcpPacket tcpPacket, int emailStartIndex, int length)
        {
            Utils.StreamReassembler reassembler;
            if (this.emailReassemblers.ContainsKey(tcpSession))
            {
                reassembler = this.emailReassemblers[tcpSession];
            }
            else
            {
                reassembler = new Utils.StreamReassembler(Pop3Packet.MULTILINE_RESPONSE_TERMINATOR, 2);//include the first 2 bytes of the terminator to get a CR-LF at the end of the extracted data
                this.emailReassemblers.Add(tcpSession, reassembler);
            }

            //add all data after the POP3 response header (after +OK or +ERR)
            int addedBytes = reassembler.AddData(tcpPacket.ParentFrame.Data, emailStartIndex, length);

            if (reassembler.TerminatorFound)
            {
                //I'm assuming the email is going from server to client
                Mime.Email email = new Mime.Email(reassembler.DataStream, base.MainPacketHandler, tcpPacket, false, tcpSession, ApplicationLayerProtocol.Pop3, FileTransfer.FileStreamAssembler.FileAssmeblyRootLocation.source);
                //remove the last command since we don't wanna reassemble any more for this RETR command
                if (this.pop3LastCommand.ContainsKey(tcpSession))
                {
                    this.pop3LastCommand.Remove(tcpSession);
                }
                this.emailReassemblers.Remove(tcpSession);
            }
            return(addedBytes);
        }
Пример #2
0
        //public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable<PacketParser.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;
             * }*/
            SmtpSession smtpSession;

            if (this.smtpSessionList.ContainsKey(tcpSession))
            {
                smtpSession = this.smtpSessionList[tcpSession];
            }
            else
            {
                smtpSession = new SmtpSession();
                this.smtpSessionList.Add(tcpSession, smtpSession);
            }

            Packets.TcpPacket  tcpPacket  = null;
            Packets.SmtpPacket smtpPacket = null;

            foreach (Packets.AbstractPacket p in packetList)
            {
                if (p.GetType() == typeof(Packets.TcpPacket))
                {
                    tcpPacket = (Packets.TcpPacket)p;
                }
                else if (p.GetType() == typeof(Packets.SmtpPacket))
                {
                    smtpPacket = (Packets.SmtpPacket)p;
                }
            }



            if (smtpPacket != null)
            {
                if (smtpPacket.ClientToServer)
                {
                    if (smtpSession.State == SmtpSession.SmtpState.Username)
                    {
                        string base64Username = smtpPacket.ReadLine().Trim();

                        try {
                            byte[] usernameBytes = System.Convert.FromBase64String(base64Username);
                            smtpSession.Username = System.Text.ASCIIEncoding.ASCII.GetString(usernameBytes);
                        }
                        catch (FormatException e) { }
                    }
                    else if (smtpSession.State == SmtpSession.SmtpState.Password)
                    {
                        string base64Password = smtpPacket.ReadLine().Trim();
                        try {
                            byte[] passwordBytes = System.Convert.FromBase64String(base64Password);
                            smtpSession.Password = System.Text.ASCIIEncoding.ASCII.GetString(passwordBytes);
                        }
                        catch (FormatException e) { }
                    }
                    else if (smtpSession.State == SmtpSession.SmtpState.Data)
                    {
                        //write data to file until we receive "\n.\n" could also be \r\n.\r\n
                        smtpSession.AddData(smtpPacket.ParentFrame.Data, smtpPacket.PacketStartIndex, smtpPacket.PacketLength);
                        //check if state has transitioned over to footer
                        if (smtpSession.State == SmtpSession.SmtpState.Footer)
                        {
                            Mime.Email email = new Mime.Email(smtpSession.DataStream, base.MainPacketHandler, tcpPacket, transferIsClientToServer, tcpSession, ApplicationLayerProtocol.Smtp, FileTransfer.FileStreamAssembler.FileAssmeblyRootLocation.destination);
                        }
                    }
                    else
                    {
                        foreach (KeyValuePair <string, string> requestCommandAndArgument in smtpPacket.RequestCommandsAndArguments)
                        {
                            if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.HELO.ToString(), StringComparison.InvariantCultureIgnoreCase))
                            {
                                string clientDomain = requestCommandAndArgument.Value;
                            }
                            else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.EHLO.ToString(), StringComparison.InvariantCultureIgnoreCase))
                            {
                                string clientDomain = requestCommandAndArgument.Value;
                            }
                            else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.AUTH.ToString(), StringComparison.InvariantCultureIgnoreCase))
                            {
                                if (requestCommandAndArgument.Value.Trim().StartsWith("LOGIN", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    //if (requestCommandAndArgument.Value.ToUpper().Contains("LOGIN")) {
                                    smtpSession.State = SmtpSession.SmtpState.AuthLogin;
                                    //SMTP clients sometimes send the email address right away like this: "AUTH LOGIN aGVqaG9wcEBpbnRlcm5ldC5zZQ=="
                                    if (requestCommandAndArgument.Value.Length > "LOGIN ".Length)
                                    {
                                        try {
                                            string base64Username = requestCommandAndArgument.Value.Substring("LOGIN ".Length).Trim();
                                            byte[] usernameBytes  = System.Convert.FromBase64String(base64Username);
                                            smtpSession.Username = System.Text.ASCIIEncoding.ASCII.GetString(usernameBytes);
                                        }
                                        catch (ArgumentException) { }
                                    }
                                }
                                else if (requestCommandAndArgument.Value.Trim().StartsWith("PLAIN", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    //AUTH PLAIN <base64-encoded username and password>
                                    smtpSession.State = SmtpSession.SmtpState.AuthLogin;
                                    //SMTP clients sometimes send the email address right away like this: "AUTH LOGIN aGVqaG9wcEBpbnRlcm5ldC5zZQ=="
                                    if (requestCommandAndArgument.Value.Length > "PLAIN ".Length)
                                    {
                                        try {
                                            string            base64 = requestCommandAndArgument.Value.Substring("PLAIN ".Length).Trim();
                                            NetworkCredential cred   = SmtpPacketHandler.ExtractBase64EncodedAuthPlainCredential(base64, smtpPacket.ParentFrame, tcpSession, ApplicationLayerProtocol.Smtp);
                                            if (cred != null)
                                            {
                                                //this.MainPacketHandler.OnCredentialDetected(new Events.CredentialEventArgs(cred));
                                                this.MainPacketHandler.AddCredential(cred);
                                            }
                                        }
                                        catch (ArgumentException) { }
                                    }
                                }
                            }
                            else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.MAIL.ToString(), StringComparison.InvariantCultureIgnoreCase))
                            {
                                if (requestCommandAndArgument.Value.StartsWith("FROM", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    int colonIndex = requestCommandAndArgument.Value.IndexOf(':');
                                    if (colonIndex > 0 && requestCommandAndArgument.Value.Length > colonIndex + 1)
                                    {
                                        smtpSession.MailFrom = requestCommandAndArgument.Value.Substring(colonIndex + 1).Trim();
                                    }
                                }
                            }
                            else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.RCPT.ToString(), StringComparison.InvariantCultureIgnoreCase))
                            {
                                if (requestCommandAndArgument.Value.StartsWith("TO", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    int colonIndex = requestCommandAndArgument.Value.IndexOf(':');
                                    if (colonIndex > 0 && requestCommandAndArgument.Value.Length > colonIndex + 1)
                                    {
                                        smtpSession.AddRecipient(requestCommandAndArgument.Value.Substring(colonIndex + 1).Trim());
                                    }
                                }
                            }
                            else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.DATA.ToString(), StringComparison.InvariantCultureIgnoreCase))
                            {
                                smtpSession.State = SmtpSession.SmtpState.Data;
                            }
                            else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.STARTTLS.ToString(), StringComparison.InvariantCultureIgnoreCase))
                            {
                                smtpSession.State = SmtpSession.SmtpState.StartTlsRequested;
                            }
                        }
                    }
                }
                else  //server to client
                {
                    foreach (KeyValuePair <int, string> replyCodeAndArgument in smtpPacket.Replies)
                    {
                        if (replyCodeAndArgument.Key == 334)  //AUTH LOGIN
                        {
                            if (replyCodeAndArgument.Value.Equals("VXNlcm5hbWU6"))
                            {
                                smtpSession.State = SmtpSession.SmtpState.Username;
                            }
                            else if (replyCodeAndArgument.Value.Equals("UGFzc3dvcmQ6"))
                            {
                                smtpSession.State = SmtpSession.SmtpState.Password;
                            }
                        }
                        else if (replyCodeAndArgument.Key == 235)  //AUTHENTICATION SUCCESSFUL
                        {
                            base.MainPacketHandler.AddCredential(new NetworkCredential(tcpSession.ClientHost, tcpSession.ServerHost, smtpPacket.PacketTypeDescription, smtpSession.Username, smtpSession.Password, smtpPacket.ParentFrame.Timestamp));
                            smtpSession.State = SmtpSession.SmtpState.Authenticated;
                        }
                        else if (replyCodeAndArgument.Key >= 500) //error
                        {
                            smtpSession.State = SmtpSession.SmtpState.None;
                        }
                        else if (replyCodeAndArgument.Key == 354) //DATA "Start mail input; end with <CRLF>.<CRLF>"
                        {
                            smtpSession.State = SmtpSession.SmtpState.Data;
                        }
                        else if (replyCodeAndArgument.Key == 250)   //"Requested mail action okay, completed"
                        {
                            if (smtpSession.State == SmtpSession.SmtpState.Footer)
                            {
                                //smtpSession.DataStream.Seek(0, System.IO.SeekOrigin.Begin);
                                smtpSession.DataStream = new System.IO.MemoryStream();
                                //System.Diagnostics.Debugger.Break();
                            }
                            smtpSession.State = SmtpSession.SmtpState.None;//Added in order to reset state when multiple SMTP sessions are sent within the same TCP session
                        }
                        else if (replyCodeAndArgument.Key == 220)
                        {
                            if (smtpSession.State == SmtpSession.SmtpState.StartTlsRequested)
                            {
                                tcpSession.ProtocolFinder.SetConfirmedApplicationLayerProtocol(ApplicationLayerProtocol.Ssl, false);
                            }
                        }
                    }
                }
                //There was a SMTP packet, so treat this as a sucsessfull extraction
                return(tcpPacket.PayloadDataLength);
            }
            else //smtpPacket == null
            {
                return(0);
            }
        }
        private int ExtractEmail(NetworkTcpSession tcpSession, TcpPacket tcpPacket, int emailStartIndex, int length, int totalLength = 0, bool clientToServer = false)
        {
            System.IO.MemoryStream reassembler;
            if (this.serverToClientEmailReassemblers.ContainsKey(tcpSession))
            {
                reassembler    = this.serverToClientEmailReassemblers[tcpSession];
                clientToServer = false;
            }
            else if (this.clientToServerEmailReassemblers.ContainsKey(tcpSession))
            {
                reassembler    = this.clientToServerEmailReassemblers[tcpSession];
                clientToServer = true;
            }
            else if (totalLength > 0)
            {
                //reassembler = new Utils.StreamReassembler(Pop3Packet.MULTILINE_RESPONSE_TERMINATOR, 2);//include the first 2 bytes of the terminator to get a CR-LF at the end of the extracted data
                reassembler = new System.IO.MemoryStream(totalLength);
                if (clientToServer)
                {
                    this.clientToServerEmailReassemblers.Add(tcpSession, reassembler);
                }
                else
                {
                    this.serverToClientEmailReassemblers.Add(tcpSession, reassembler);
                }
            }
            else
            {
                return(0);
            }

            if (reassembler.Capacity < reassembler.Position + length)
            {
                length = (int)(reassembler.Capacity - reassembler.Position);
            }

            reassembler.Write(tcpPacket.ParentFrame.Data, emailStartIndex, length);
            if (reassembler.Position == reassembler.Capacity)
            {
                FileTransfer.FileStreamAssembler.FileAssmeblyRootLocation assemblyLocation;
                if (clientToServer)
                {
                    assemblyLocation = FileTransfer.FileStreamAssembler.FileAssmeblyRootLocation.destination;
                }
                else
                {
                    assemblyLocation = FileTransfer.FileStreamAssembler.FileAssmeblyRootLocation.source;
                    //remove the last command since we don't wanna reassemble any more for this command
                    if (this.lastCommand.ContainsKey(tcpSession))
                    {
                        this.lastCommand.Remove(tcpSession);
                    }
                }

                Mime.Email email = new Mime.Email(reassembler, base.MainPacketHandler, tcpPacket, clientToServer, tcpSession, ApplicationLayerProtocol.Imap, assemblyLocation);

                /*
                 * if (clientToServer) {
                 *  email = new Mime.Email(reassembler, base.MainPacketHandler, tcpPacket, tcpSession.ClientHost, tcpSession.ServerHost, tcpSession, ApplicationLayerProtocol.Imap, !clientToServer);
                 *  this.clientToServerEmailReassemblers.Remove(tcpSession);
                 * }
                 * else {
                 *  email = new Mime.Email(reassembler, base.MainPacketHandler, tcpPacket, tcpSession.ServerHost, tcpSession.ClientHost, tcpSession, ApplicationLayerProtocol.Imap, !clientToServer);
                 *  this.serverToClientEmailReassemblers.Remove(tcpSession);
                 *  //remove the last command since we don't wanna reassemble any more for this command
                 *  if (this.lastCommand.ContainsKey(tcpSession))
                 *      this.lastCommand.Remove(tcpSession);
                 * }
                 */
            }
            return(length);
        }