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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



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

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

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

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

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

                        /* Removed 2011-04-25
                         * if(!assembler.IsActive) {//see if the file is fully assembled or if something else went wrong...
                         *  smbSession.RemoveLastReferencedAssembler(response.ParentCifsPacket.TreeId, response.ParentCifsPacket.MultiplexId, response.ParentCifsPacket.ProcessId);
                         * }
                         * */
                    }
                }
            }
        }
        //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);
        }
        private void ExtractData(ref NetworkHost sourceHost, NetworkHost destinationHost, Packets.DhcpPacket dhcpPacket)
        {
            if (dhcpPacket.OpCode == Packets.DhcpPacket.OpCodeValue.BootRequest && (sourceHost.MacAddress == null || dhcpPacket.ClientMacAddress != sourceHost.MacAddress))
            {
                sourceHost.MacAddress = dhcpPacket.ClientMacAddress;
            }
            else if (dhcpPacket.OpCode == Packets.DhcpPacket.OpCodeValue.BootReply && (destinationHost.MacAddress == null || dhcpPacket.ClientMacAddress != destinationHost.MacAddress))
            {
                destinationHost.MacAddress = dhcpPacket.ClientMacAddress;
            }

            if (dhcpPacket.OpCode == Packets.DhcpPacket.OpCodeValue.BootReply && (dhcpPacket.GatewayIpAddress != null && dhcpPacket.GatewayIpAddress != System.Net.IPAddress.None && dhcpPacket.GatewayIpAddress.Address > 0))
            {
                destinationHost.ExtraDetailsList["Default Gateway"] = dhcpPacket.GatewayIpAddress.ToString();
            }


            System.Collections.Specialized.NameValueCollection optionParameterList = new System.Collections.Specialized.NameValueCollection();
            //now check all the DHCP options
            //byte dhcpMessageType=0x00;//1=Discover, 2=Offer, 3=Request, 5=Ack, 8=Inform
            foreach (Packets.DhcpPacket.Option option in dhcpPacket.OptionList)
            {
                //TODO: Add option to Parameters list



                if (option.OptionCode == 12)//hostname
                {
                    string hostname = Utils.ByteConverter.ReadString(option.OptionValue);
                    sourceHost.AddHostName(hostname);
                    optionParameterList.Add("DHCP Option 12 Hostname", hostname);
                }
                else if (option.OptionCode == 15)//Domain Name
                {
                    string domain = Utils.ByteConverter.ReadString(option.OptionValue);
                    sourceHost.AddDomainName(domain);
                    optionParameterList.Add("DHCP Option 15 Domain", domain);
                }
                else if (option.OptionCode == 50)        //requested IP address
                {
                    if (dhcpPacket.DhcpMessageType == 3) //Must be a DHCP Request
                    {
                        System.Net.IPAddress requestedIpAddress = new System.Net.IPAddress(option.OptionValue);
                        if (sourceHost.IPAddress != requestedIpAddress)
                        {
                            if (!base.MainPacketHandler.NetworkHostList.ContainsIP(requestedIpAddress))
                            {
                                NetworkHost clonedHost = new NetworkHost(requestedIpAddress);
                                clonedHost.MacAddress = sourceHost.MacAddress;
                                //foreach(string hostname in sourceHost.HostNameList)
                                //    clonedHost.AddHostName(hostname);
                                lock (base.MainPacketHandler.NetworkHostList)
                                    base.MainPacketHandler.NetworkHostList.Add(clonedHost);
                                //now change the host to the cloned one (and hope it works out...)
                                sourceHost = clonedHost;
                            }
                            else
                            {
                                sourceHost = base.MainPacketHandler.NetworkHostList.GetNetworkHost(requestedIpAddress);
                                if (dhcpPacket.OpCode == Packets.DhcpPacket.OpCodeValue.BootRequest && (sourceHost.MacAddress == null || dhcpPacket.ClientMacAddress != sourceHost.MacAddress))
                                {
                                    sourceHost.MacAddress = dhcpPacket.ClientMacAddress;
                                }
                            }
                        }
                        if (sourceHost.MacAddress != null && previousIpList.ContainsKey(sourceHost.MacAddress.ToString()))
                        {
                            //if(previousIpList.ContainsKey(sourceHost.MacAddress.ToString())) {
                            sourceHost.AddNumberedExtraDetail("Previous IP", previousIpList[sourceHost.MacAddress.ToString()].ToString());
                            //sourceHost.ExtraDetailsList["Previous IP"]=previousIpList[sourceHost.MacAddress.ToString()].ToString();
                            previousIpList.Remove(sourceHost.MacAddress.ToString());
                        }
                    }
                    else if (dhcpPacket.DhcpMessageType == 1)//DHCP discover
                    //see which IP address the client hade previously
                    //They normally requests the same IP as they hade before...
                    {
                        System.Net.IPAddress requestedIpAddress = new System.Net.IPAddress(option.OptionValue);
                        this.previousIpList[sourceHost.MacAddress.ToString()] = requestedIpAddress;
                    }
                }

                /*
                 * else if(option.OptionCode==53) {//DHCP message type
                 * if(option.OptionValue!=null && option.OptionValue.Length==1)
                 *  dhcpMessageType=option.OptionValue[0];
                 * }/*/
                else if (option.OptionCode == 60)//vendor class identifier
                {
                    string vendorCode = Utils.ByteConverter.ReadString(option.OptionValue);
                    sourceHost.AddDhcpVendorCode(vendorCode);
                    optionParameterList.Add("DHCP Option 60 Vendor Code", vendorCode);
                }
                else if (option.OptionCode == 81)  //Client Fully Qualified Domain Name
                {
                    string domain = Utils.ByteConverter.ReadString(option.OptionValue, 3, option.OptionValue.Length - 3);
                    sourceHost.AddHostName(domain);
                    optionParameterList.Add("DHCP Option 81 Domain", domain);
                }
                else if (option.OptionCode == 125)  //V-I Vendor-specific Information http://tools.ietf.org/html/rfc3925
                {
                    uint enterpriceNumber = Utils.ByteConverter.ToUInt32(option.OptionValue, 0);
                    optionParameterList.Add("DHCP Option 125 Enterprise Number", enterpriceNumber.ToString());
                    byte dataLen = option.OptionValue[4];
                    if (dataLen > 0 && option.OptionValue.Length >= 5 + dataLen)
                    {
                        string optionData = Utils.ByteConverter.ReadString(option.OptionValue, 5, dataLen);
                        optionParameterList.Add("DHCP Option 125 Data", optionData);
                    }
                }
                else
                {
                    string optionValueString = Utils.ByteConverter.ReadString(option.OptionValue);
                    if (!System.Text.RegularExpressions.Regex.IsMatch(optionValueString, @"[^\u0020-\u007E]"))
                    {
                        optionParameterList.Add("DHCP Option " + option.OptionCode.ToString(), optionValueString);
                    }
                }
            }
            if (optionParameterList.Count > 0)
            {
                //try to get the udp packet
                string sourcePort      = "UNKNOWN";
                string destinationPort = "UNKNOWN";
                foreach (Packets.AbstractPacket p in dhcpPacket.ParentFrame.PacketList)
                {
                    if (p.GetType() == typeof(Packets.UdpPacket))
                    {
                        Packets.UdpPacket udpPacket = (Packets.UdpPacket)p;
                        sourcePort      = "UDP " + udpPacket.SourcePort;
                        destinationPort = "UDP " + udpPacket.DestinationPort;
                        break;
                    }
                }
                Events.ParametersEventArgs ea = new Events.ParametersEventArgs(dhcpPacket.ParentFrame.FrameNumber, sourceHost, destinationHost, sourcePort, destinationPort, optionParameterList, dhcpPacket.ParentFrame.Timestamp, "DHCP Option");
                MainPacketHandler.OnParametersDetected(ea);
            }
        }
示例#4
0
        public void ExtractData(ref NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable <Packets.AbstractPacket> packetList)
        {
            Packets.DnsPacket             dnsPacket            = null;
            Packets.IIPPacket             ipPacket             = null;
            Packets.ITransportLayerPacket transportLayerPacket = null;

            foreach (Packets.AbstractPacket p in packetList)
            {
                if (p.GetType() == typeof(Packets.DnsPacket))
                {
                    dnsPacket = (Packets.DnsPacket)p;
                }
                else if (p is Packets.IIPPacket)
                {
                    ipPacket = (Packets.IIPPacket)p;
                }

                /*else if(p.GetType()==typeof(Packets.IPv6Packet))
                 *  ipv6Packet=(Packets.IPv6Packet)p;*/
                else if (p is Packets.ITransportLayerPacket tlp)
                {
                    transportLayerPacket = tlp;
                }
            }

            if (dnsPacket != null)
            {
                //ExtractDnsData(dnsPacket);
                if (dnsPacket.Flags.Response)
                {
                    System.Collections.Specialized.NameValueCollection cNamePointers = new System.Collections.Specialized.NameValueCollection();
                    if (dnsPacket.AnswerRecords != null && dnsPacket.AnswerRecords.Length > 0)
                    {
                        foreach (Packets.DnsPacket.ResourceRecord r in dnsPacket.AnswerRecords)
                        {
                            if (r.IP != null)
                            {
                                if (!base.MainPacketHandler.NetworkHostList.ContainsIP(r.IP))
                                {
                                    NetworkHost host = new NetworkHost(r.IP);
                                    host.AddHostName(r.DNS, dnsPacket.PacketTypeDescription);
                                    lock (base.MainPacketHandler.NetworkHostList)
                                        base.MainPacketHandler.NetworkHostList.Add(host);
                                    MainPacketHandler.OnNetworkHostDetected(new Events.NetworkHostEventArgs(host));
                                    //base.MainPacketHandler.ParentForm.ShowDetectedHost(host);
                                }
                                else
                                {
                                    base.MainPacketHandler.NetworkHostList.GetNetworkHost(r.IP).AddHostName(r.DNS, dnsPacket.PacketTypeDescription);
                                }
                                if (cNamePointers[r.DNS] != null)
                                {
                                    base.MainPacketHandler.NetworkHostList.GetNetworkHost(r.IP).AddHostName(cNamePointers[r.DNS], dnsPacket.PacketTypeDescription);
                                }
                            }
                            else if (r.Type == (ushort)Packets.DnsPacket.RRTypes.CNAME)
                            {
                                cNamePointers.Add(r.PrimaryName, r.DNS);
                            }


                            MainPacketHandler.OnDnsRecordDetected(new Events.DnsRecordEventArgs(r, sourceHost, destinationHost, ipPacket, transportLayerPacket));
                            //base.MainPacketHandler.ParentForm.ShowDnsRecord(r, sourceHost, destinationHost, ipPakcet, udpPacket);
                        }
                    }
                    else
                    {
                        //display the flags instead
                        //TODO : MainPacketHandler.OnDnsRecordDetected(new Events.DnsRecordEventArgs(
                        if (dnsPacket.QueriedDnsName != null && dnsPacket.QueriedDnsName.Length > 0)
                        {
                            MainPacketHandler.OnDnsRecordDetected(new Events.DnsRecordEventArgs(new Packets.DnsPacket.ResponseWithErrorCode(dnsPacket), sourceHost, destinationHost, ipPacket, transportLayerPacket));
                        }
                    }
                }
                else  //DNS request
                {
                    if (dnsPacket.QueriedDnsName != null && dnsPacket.QueriedDnsName.Length > 0)
                    {
                        sourceHost.AddQueriedDnsName(dnsPacket.QueriedDnsName);
                    }
                }
            }
        }
示例#5
0
        public void ExtractData(ref NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable <Packets.AbstractPacket> packetList)
        {
            Packets.UdpPacket  udpPacket  = null;
            Packets.TftpPacket tftpPacket = null;

            foreach (Packets.AbstractPacket p in packetList)
            {
                if (p.GetType() == typeof(Packets.UdpPacket))
                {
                    udpPacket = (Packets.UdpPacket)p;
                }
                else if (p.GetType() == typeof(Packets.TftpPacket))
                {
                    tftpPacket = (Packets.TftpPacket)p;
                }
            }

            if (udpPacket != null)
            {
                FileTransfer.FileStreamAssembler assembler;
                if (TryGetTftpFileStreamAssembler(out assembler, base.MainPacketHandler.FileStreamAssemblerList, sourceHost, udpPacket.SourcePort, destinationHost, udpPacket.DestinationPort) || (tftpPacket != null && TryCreateNewAssembler(out assembler, base.MainPacketHandler.FileStreamAssemblerList, tftpPacket, sourceHost, udpPacket.SourcePort, destinationHost)))
                {
                    //we have an assembler!
                    string sessionId = this.GetTftpSessionId(sourceHost, udpPacket.SourcePort, destinationHost, udpPacket.DestinationPort);
                    ushort blksize   = 512;//default
                    if (this.tftpSessionBlksizeList.ContainsKey(sessionId))
                    {
                        blksize = this.tftpSessionBlksizeList[sessionId];
                    }
                    //but we might not have a TFTP packet since it is likely to run over a random port
                    if (tftpPacket == null || tftpPacket.Blksize != blksize)
                    {
                        try {
                            tftpPacket = new Packets.TftpPacket(udpPacket.ParentFrame, udpPacket.PacketStartIndex + 8, udpPacket.PacketEndIndex, blksize);//this is not very pretty since the UDP header length is hardcoded to be 8.
                            if (tftpPacket.Blksize != blksize)
                            {
                                if (this.tftpSessionBlksizeList.ContainsKey(sessionId))
                                {
                                    this.tftpSessionBlksizeList[sessionId] = tftpPacket.Blksize;
                                }
                                else
                                {
                                    this.tftpSessionBlksizeList.Add(sessionId, tftpPacket.Blksize);
                                }
                            }
                        }
                        catch (Exception e) {
                            if (assembler != null)
                            {
                                MainPacketHandler.OnAnomalyDetected("Error parsing TFTP packet: " + e.Message, udpPacket.ParentFrame.Timestamp);
                            }
                        }
                    }
                    //see if we have an tftp pakcet and parse its file data
                    if (tftpPacket != null)
                    {
                        ExtractFileData(assembler, base.MainPacketHandler.FileStreamAssemblerList, sourceHost, udpPacket.SourcePort, destinationHost, udpPacket.DestinationPort, tftpPacket);
                    }
                }
            }//end if udpPacket
        }
示例#6
0
        public int ExtractData(NetworkTcpSession tcpSession, bool transferIsClientToServer, IEnumerable <PacketParser.Packets.AbstractPacket> packetList)
        {
            Packets.Pop3Packet pop3Packet = 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.Pop3Packet))
                {
                    pop3Packet = (Packets.Pop3Packet)p;
                }
            }
            if (tcpPacket != null && tcpPacket.SourcePort == 110 && this.pop3LastCommand.ContainsKey(tcpSession) && this.pop3LastCommand[tcpSession] == Pop3Packet.ClientCommand.RETR && this.emailReassemblers.ContainsKey(tcpSession))
            {
                return(this.ExtractEmail(tcpSession, tcpPacket, tcpPacket.PacketStartIndex + tcpPacket.DataOffsetByteCount, tcpPacket.PayloadDataLength));
            }
            else if (pop3Packet != null && tcpPacket != null)
            {
                if (pop3Packet.PacketHeaderIsComplete)
                {
                    int bytesParsedAfterHeader = 0;

                    if (pop3Packet.FullRequestOrResponseLine != null && pop3Packet.FullRequestOrResponseLine.Length > 0)
                    {
                        System.Collections.Specialized.NameValueCollection parms = new System.Collections.Specialized.NameValueCollection();
                        string command = pop3Packet.GetCommandOrResponse();
                        parms.Add(command, pop3Packet.GetCommandOrResponseArguments());

                        if (pop3Packet.ClientToServer)
                        {
                            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;
                            }

                            base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(pop3Packet.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parms, pop3Packet.ParentFrame.Timestamp, "POP3 Command"));
                            //See if there are additional lines after the command



                            if (Enum.IsDefined(typeof(Pop3Packet.ClientCommand), command.ToUpper()))
                            {
                                Pop3Packet.ClientCommand clientCommand = (Pop3Packet.ClientCommand)Enum.Parse(typeof(Pop3Packet.ClientCommand), command.ToUpper());

                                //remove any old email reassemblers since we have now received a new command
                                if (this.emailReassemblers.ContainsKey(tcpSession))
                                {
                                    this.emailReassemblers[tcpSession].Close();
                                    this.emailReassemblers.Remove(tcpSession);//we will need to create a new reassembler
                                }

                                /**
                                 * https://tools.ietf.org/html/rfc1939
                                 * If an argument was given and the POP3 server issues a
                                 * positive response with a line containing information for
                                 * that message.
                                 * If no argument was given and the POP3 server issues a
                                 * positive response, then the response given is multi-line.
                                 **/

                                if (clientCommand == Pop3Packet.ClientCommand.LIST && pop3Packet.FullRequestOrResponseLine.Length > 5)
                                {
                                    clientCommand = Pop3Packet.ClientCommand.LIST_WITH_ARGS;
                                }
                                else if (clientCommand == Pop3Packet.ClientCommand.UIDL && pop3Packet.FullRequestOrResponseLine.Length > 5)
                                {
                                    clientCommand = Pop3Packet.ClientCommand.UIDL_WITH_ARGS;
                                }

                                if (clientCommand == Pop3Packet.ClientCommand.USER)
                                {
                                    if (pop3Packet.GetCommandOrResponseArguments().Length > 0)
                                    {
                                        NetworkCredential credential = new NetworkCredential(sourceHost, destinationHost, "POP3", pop3Packet.GetCommandOrResponseArguments(), pop3Packet.ParentFrame.Timestamp);
                                        //this.pop3Credentials.Add(tcpSession, credential);
                                        this.updateCredential(credential, tcpSession);
                                    }
                                }
                                else if (clientCommand == Pop3Packet.ClientCommand.PASS)
                                {
                                    if (this.pop3Credentials.ContainsKey(tcpSession))
                                    {
                                        NetworkCredential credential = this.pop3Credentials[tcpSession];
                                        credential.Password = pop3Packet.GetCommandOrResponseArguments();
                                        //this.MainPacketHandler.OnCredentialDetected(new Events.CredentialEventArgs(credential));
                                        this.MainPacketHandler.AddCredential(credential);
                                    }
                                }
                                else if (clientCommand == Pop3Packet.ClientCommand.AUTH)
                                {
                                    string authArgs = pop3Packet.GetCommandOrResponseArguments();
                                    if (authArgs.StartsWith("PLAIN", StringComparison.InvariantCultureIgnoreCase))
                                    {
                                        clientCommand = Pop3Packet.ClientCommand.AUTH_PLAIN;

                                        if (authArgs.Trim().Length > 5)
                                        {
                                            //we have an in-line credential
                                            //AUTH PLAIN dGVzdAB0ZXN0AHRlc3RwYXNz
                                            //dGVzdAB0ZXN0AHRlc3RwYXNz  == "test\0test\0pass"
                                            string emailAndPassword = authArgs.Substring(5).TrimStart();
                                            this.extractBase64EncodedEmailAndPassword(emailAndPassword, pop3Packet.ParentFrame, tcpSession);
                                        }
                                    }
                                }
                                else if (clientCommand == Pop3Packet.ClientCommand.APOP)
                                {
                                    //username is cleartext
                                    //password is MD5(nonce+password)

                                    /**
                                     * S: +OK POP3 server ready <*****@*****.**>
                                     * C: APOP mrose c4c9334bac560ecc979e58001b3e22fb
                                     * S: +OK maildrop has 1 message (369 octets)
                                     **/
                                    string userAndHash = pop3Packet.GetCommandOrResponseArguments();
                                    userAndHash = userAndHash.Trim();
                                    int spaceIndex = userAndHash.IndexOf(' ');
                                    if (spaceIndex > 0 && spaceIndex < userAndHash.Length - 1)
                                    {
                                        string            user = userAndHash.Substring(0, spaceIndex).Trim();
                                        string            hash = userAndHash.Substring(spaceIndex).Trim();
                                        NetworkCredential cred = new NetworkCredential(tcpSession.ClientHost, tcpSession.ServerHost, "POP3", user, "APOP hash: " + hash, pop3Packet.ParentFrame.Timestamp);
                                        //MainPacketHandler.OnCredentialDetected(new Events.CredentialEventArgs(cred));
                                        MainPacketHandler.AddCredential(cred);
                                    }
                                }
                                else if (clientCommand == Pop3Packet.ClientCommand.RETR)
                                {
                                    //clear all previous server-to-client data in case there is still some trailing data from the previous command that hasn't been parsed yet
                                    int bytesInStream = tcpSession.ServerToClientTcpDataStream.CountBytesToRead();
                                    if (bytesInStream > 0)
                                    {
                                        tcpSession.ServerToClientTcpDataStream.RemoveData(bytesInStream);
                                    }
                                }

                                if (this.pop3LastCommand.ContainsKey(tcpSession))
                                {
                                    this.pop3LastCommand[tcpSession] = clientCommand;
                                }
                                else
                                {
                                    this.pop3LastCommand.Add(tcpSession, clientCommand);
                                }
                            }
                            else
                            {
                                //unknown command. We might be seing a multi-line command
                                //Check for last command
                                if (this.pop3LastCommand.ContainsKey(tcpSession))
                                {
                                    if (this.pop3LastCommand[tcpSession] == Pop3Packet.ClientCommand.AUTH_PLAIN)
                                    {
                                        /**
                                         * C: AUTH PLAIN
                                         * S: +
                                         * C: dGVzdAB0ZXN0AHRlc3Q=
                                         **/
                                        /**
                                         * Client: AUTH PLAIN
                                         * Server: +
                                         * Client: bmFtZUBleGFtcGxlLmNvbU15UGFzc3dvcmQK
                                         * Server: +OK mailbox "*****@*****.**" has 30 messages (1115683 octets) H migmx127
                                         **/
                                        this.extractBase64EncodedEmailAndPassword(pop3Packet.FullRequestOrResponseLine, tcpPacket.ParentFrame, tcpSession);
                                        //TODO parsa ovanstående i en ny funktion
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (pop3Packet.GetCommandOrResponse() == Pop3Packet.RESPONSE_OK)
                            {
                                if (this.pop3LastCommand.ContainsKey(tcpSession))
                                {
                                    //consume all multi-line responses here
                                    if (this.pop3LastCommand[tcpSession] == Pop3Packet.ClientCommand.LIST_WITH_ARGS)
                                    {
                                        foreach (string s in pop3Packet.ReadResponseLines())
                                        {
                                            //do nothing... just make sure all lines are read
                                        }
                                    }
                                    else if (this.pop3LastCommand[tcpSession] == Pop3Packet.ClientCommand.RETR)
                                    {
                                        /*
                                         * Utils.StreamReassembler reassembler;
                                         * if (this.emailReassemblers.ContainsKey(tcpSession))
                                         *  reassembler = this.emailReassemblers[tcpSession];
                                         * else
                                         *  reassembler = new Utils.StreamReassembler(Pop3Packet.MULTILINE_RESPONSE_TERMINATOR, 0);
                                         *
                                         * foreach (string line in pop3Packet.ReadResponseLines()) {
                                         *  reassembler.AddData(line);
                                         *  if (reassembler.TerminatorFound)
                                         *      break;
                                         * }
                                         * if(reassembler.TerminatorFound) {
                                         *  Mime.Email email = new Mime.Email(reassembler.DataStream, base.MainPacketHandler, tcpPacket, sourceHost, destinationHost, tcpSession, ApplicationLayerProtocol.Pop3);
                                         * }
                                         */
                                        bytesParsedAfterHeader += this.ExtractEmail(tcpSession, tcpPacket, pop3Packet);
                                    }
                                    else if (this.pop3LastCommand[tcpSession] == Pop3Packet.ClientCommand.TOP)
                                    {
                                        foreach (string s in pop3Packet.ReadResponseLines())
                                        {
                                            //do nothing... just make sure all lines are read
                                        }
                                    }
                                    if (this.pop3LastCommand[tcpSession] == Pop3Packet.ClientCommand.UIDL_WITH_ARGS)
                                    {
                                        foreach (string s in pop3Packet.ReadResponseLines())
                                        {
                                            //do nothing... just make sure all lines are read
                                        }
                                    }
                                    else if (pop3Packet.ParsedBytesCount < pop3Packet.PacketEndIndex - pop3Packet.PacketStartIndex + 1)
                                    {
                                        foreach (string s in pop3Packet.ReadResponseLines())
                                        {
                                            //do nothing... just make sure all lines are read
                                        }
                                    }


                                    //parse single line details from responses here
                                }
                                else if (pop3Packet.PacketHeaderIsComplete)
                                {
                                    if (pop3Packet.GetCommandOrResponseArguments().Length > 0)
                                    {
                                        tcpSession.Flow.FiveTuple.ServerHost.AddNumberedExtraDetail("POP3 Banner", pop3Packet.GetCommandOrResponseArguments());
                                    }
                                }
                                if (pop3Packet.PacketHeaderIsComplete)
                                {
                                    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;
                                    }
                                    base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(pop3Packet.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parms, pop3Packet.ParentFrame.Timestamp, "POP3 Response"));
                                }
                            }
                        }
                    }
                    return(pop3Packet.ParsedBytesCount + bytesParsedAfterHeader);
                }

                else if (!pop3Packet.ClientToServer) //invalid response received from Server
                {
                    if (this.pop3LastCommand.ContainsKey(tcpSession) && this.pop3LastCommand[tcpSession] == Pop3Packet.ClientCommand.RETR)
                    {
                        //reassemble a segment of an email here
                        return(pop3Packet.ParsedBytesCount + this.ExtractEmail(tcpSession, tcpPacket, pop3Packet));
                    }
                    else if (pop3Packet.ParentFrame.Data[pop3Packet.PacketStartIndex] == '+')
                    {
                        //special handling of responses like "+ " for AUTH PLAIN to indicate that more data is expected from the client
                        int    index = pop3Packet.PacketStartIndex;
                        string line  = Utils.ByteConverter.ReadLine(pop3Packet.ParentFrame.Data, ref index);
                        return(index - pop3Packet.PacketStartIndex);
                    }
                    else
                    {
                        return(0);
                    }
                }
                else
                {
                    return(0);
                }
            }
            else
            {
                return(0);
            }
        }
示例#7
0
        //public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable<AbstractPacket> packetList) {
        public int ExtractData(NetworkTcpSession tcpSession, bool transferIsClientToServer, IEnumerable <PacketParser.Packets.AbstractPacket> packetList)
        {
            Packets.SocksPacket socksPacket = 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.SocksPacket))
                {
                    socksPacket = (Packets.SocksPacket)p;
                }
            }
            if (socksPacket != null && tcpPacket != null)
            {
                string paramName = "SOCKS";
                if (socksPacket.ClientToServer)
                {
                    if (socksPacket.CommandOrReply == 1)
                    {
                        paramName += " Connect";
                        if (!this.socksConnectIpPorts.ContainsKey(tcpSession))
                        {
                            if (socksPacket.IpAddress != null)
                            {
                                this.socksConnectIpPorts.Add(tcpSession, new KeyValuePair <System.Net.IPAddress, ushort>(socksPacket.IpAddress, socksPacket.Port));
                            }
                            else
                            {
                                this.socksConnectIpPorts.Add(tcpSession, new KeyValuePair <System.Net.IPAddress, ushort>(tcpSession.ClientHost.IPAddress, socksPacket.Port));
                            }
                        }
                    }
                    else if (socksPacket.CommandOrReply == 2)
                    {
                        paramName += " Bind";
                    }
                    else if (socksPacket.CommandOrReply == 3)
                    {
                        paramName += " DNS Associate";
                    }

                    if (socksPacket.Username != null && socksPacket.Password != null)
                    {
                        //base.MainPacketHandler.OnCredentialDetected(new Events.CredentialEventArgs(new NetworkCredential(tcpSession.ClientHost, tcpSession.ServerHost, "SOCKS", socksPacket.Username, socksPacket.Password, socksPacket.ParentFrame.Timestamp)));
                        base.MainPacketHandler.AddCredential(new NetworkCredential(tcpSession.ClientHost, tcpSession.ServerHost, "SOCKS", socksPacket.Username, socksPacket.Password, socksPacket.ParentFrame.Timestamp));
                    }
                }
                else
                {
                    if (socksPacket.CommandOrReply == 0)
                    {
                        paramName += " Bind Succeeded";
                        if (this.socksConnectIpPorts.ContainsKey(tcpSession))
                        {
                            KeyValuePair <System.Net.IPAddress, ushort> target = this.socksConnectIpPorts[tcpSession];
                            ushort      serverPort = target.Value;
                            NetworkHost serverHost;
                            if (base.MainPacketHandler.NetworkHostList.ContainsIP(target.Key))
                            {
                                serverHost = base.MainPacketHandler.NetworkHostList.GetNetworkHost(target.Key);
                            }
                            else
                            {
                                serverHost = tcpSession.ClientHost;
                            }

                            tcpSession.ProtocolFinder = new TcpPortProtocolFinder(tcpSession.Flow, tcpPacket.ParentFrame.FrameNumber, base.MainPacketHandler, serverHost, serverPort);
                        }
                    }
                    else if (socksPacket.CommandOrReply == 1)
                    {
                        paramName += " General SOCKS server failure";
                    }
                    else if (socksPacket.CommandOrReply == 2)
                    {
                        paramName += " Connection not allowed by ruleset";
                    }
                    else if (socksPacket.CommandOrReply == 3)
                    {
                        paramName += " Network unreachable";
                    }
                    else if (socksPacket.CommandOrReply == 4)
                    {
                        paramName += " Host unreachable";
                    }
                    else if (socksPacket.CommandOrReply == 5)
                    {
                        paramName += " Connection refused";
                    }
                    else if (socksPacket.CommandOrReply == 6)
                    {
                        paramName += " TTL expired";
                    }
                    else if (socksPacket.CommandOrReply == 7)
                    {
                        paramName += " Command not supported";
                    }
                    else if (socksPacket.CommandOrReply == 8)
                    {
                        paramName += " Address type not supported";
                    }
                }

                if (socksPacket.ATyp == SocksPacket.ATYP.DOMAINNAME)
                {
                    System.Collections.Specialized.NameValueCollection parms = new System.Collections.Specialized.NameValueCollection();
                    parms.Add(paramName, socksPacket.DomainName + ":" + socksPacket.Port.ToString());
                    MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(socksPacket.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parms, socksPacket.ParentFrame.Timestamp, "SOCKS Connection"));
                }
                else if (socksPacket.ATyp == SocksPacket.ATYP.IPv4 || socksPacket.ATyp == SocksPacket.ATYP.IPv6)
                {
                    System.Collections.Specialized.NameValueCollection parms = new System.Collections.Specialized.NameValueCollection();
                    parms.Add(paramName, socksPacket.IpAddress.ToString() + ":" + socksPacket.Port.ToString());
                    MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(socksPacket.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parms, socksPacket.ParentFrame.Timestamp, "SOCKS Connection"));
                }
            }
            if (socksPacket != null)
            {
                return(socksPacket.ParsedBytesCount);
            }
            else
            {
                return(0);
            }
        }