Пример #1
0
        private IEnumerable <PmFrameBase> FindFragments(PmFrameBase firstFrame, out Int64 extractedBytes)
        {
            // _log.Info(String.Format("Located IPv4 fragmented frame {0}", firstFrame));

            extractedBytes = 0;
            var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            var limit = 2 * 60 * 1000; // max difference in timestamps of two IPv4 fragments

            //Select framew with the same Ipv4FIdentification
            var list = from frame in this.L4Conversation.L3Conversation.NonL4Frames
                       //CaptureProcessor.CaptureProcessor.GetRealFramesEnumerable()
                       where frame.Ipv4FIdentification == firstFrame.Ipv4FIdentification
                       orderby frame.Ipv4FragmentOffset
                       select frame;

            //IOrderedEnumerable<PmFrameBase> list = from frame in _currentFlow.RealFrames
            //                                    where frame.Ipv4FIdentification == firstFrame.Ipv4FIdentification
            //                                    orderby frame.Ipv4FragmentOffset
            //                                    select frame;

            //List of ordered fragments
            var fragmentList = new List <PmFrameBase>
            {
                firstFrame
            };

            //Process of defragmentation
            var expectedOffset = (Int64)Math.Ceiling((firstFrame.IncludedLength - (firstFrame.L7Offset - firstFrame.L2Offset)) / (Double)8) + 1;

            while (true)
            {
                var currentFrameList = list.Where(frame => frame.Ipv4FragmentOffset == expectedOffset);
                if (!currentFrameList.Any())
                {
                    return(null);
                }
                var bestFrame =
                    currentFrameList.Aggregate(
                        (curmin, x) =>
                        (curmin == null || Math.Abs((x.TimeStamp - firstFrame.TimeStamp).TotalMilliseconds) < (curmin.TimeStamp - epoch).TotalMilliseconds? x : curmin));
                if (Math.Abs((bestFrame.TimeStamp - firstFrame.TimeStamp).TotalMilliseconds) > limit)
                {
                    return(null);
                }
                fragmentList.Add(bestFrame);

                if (bestFrame.Ipv4FMf == false)
                {
                    extractedBytes = expectedOffset * 8 + bestFrame.L7PayloadLength - 8; //8 - UDP header size
                    break;
                }

                expectedOffset += (Int64)Math.Ceiling(bestFrame.L7PayloadLength / (Double)8);
            }

            //foreach(var frame in fragmentList) { this.L4Conversation.L3Conversation.NonL4Frames.Remove(frame); } //todo! release references to already used frames


            return(fragmentList);
        }
Пример #2
0
        /// <summary>
        ///     Prints whole TCPD Packet Header inforamtion of one frame record
        /// </summary>
        /// <param name="fr">Target frame</param>
        internal void PrintTcpdPacketHeaderRecord(PmFrameBase fr)
        {
            Int64 tsSec;
            Int64 tsUsec;
            Int64 inclLen;
            Int64 origLen;

            Byte[] frameData;

            this.GetTcpdPckPacketHeaderRecord(fr, out tsSec, out tsUsec, out inclLen, out origLen, out frameData);

            "Time span in seconds.useconds> {0}.{1}".PrintInfoEol(tsSec, tsUsec);
            "Converted time> {0}".PrintInfoEol(ConvertUnixTimeToDate(ConvertTcpdToUnixTime((Int32)tsSec, (Int32)tsUsec)).ToString("dd/MM/yyyy HH:mm:ss.FFFFFFF"));

            "Included frame length> ".PrintInfoEol();
            if (inclLen > this._snaplen)
            {
                PmConsolePrinter.PrintError(inclLen.ToString(CultureInfo.InvariantCulture));
            }
            else
            {
                Console.WriteLine("{0}", inclLen);
            }

            "Original frame length> {0}".PrintInfoEol(origLen);
            "Frame data> {0}".PrintInfoEol(frameData);
        }
Пример #3
0
        private void AwaitEncryptedMessage(Byte[] l7Data, PmFrameBase pdu)
        {
            if (l7Data[0] == Record)
            {
                // record protocol
                this._state = this.Decrypter.DoDecryption(l7Data, pdu, ref this._decryptedBytes)? SslSessionState.DataExchange : SslSessionState.Intermezzo;
            }
            else if (l7Data[0] == Handshake)
            {
                // tls handshaking protocol
                // renegotiation
                // TODO could be Finished?
                this._msgUnderReview--;
                // TODO isn't renegotiation encrypted??
                this._state = SslSessionState.NegotiationInit;
            }
            else if (l7Data[0] == ChangeCipherSpec && l7Data.Length > 6) // ChangeCipherSpec message has 6 bytes
            {
                // 'Finished' is in this pdu - TODO can be in next pdu?
                var finished = new Byte[l7Data.Length - 6];
                Array.Copy(l7Data, 6, finished, 0, finished.Length);
                this.Decrypter.DoDecryption(finished, pdu, ref this._decryptedBytes);
                this._decryptedBytes = null;

                this._state = SslSessionState.Intermezzo;
            }
            else if (l7Data[0] == Alert)
            {
                // alert protocol
                // ignore
                this._state = SslSessionState.Intermezzo;
            }
            // else something wrong
        }
Пример #4
0
        /* /// <summary>
         * /// Reads frame data starting on 16B in TCPD Packet Header
         * /// </summary>
         * /// <param name="binreader">Binary reader with opened PCAP file</param>
         * /// <param name="offset">Starting offset of target frame in TCPD PCAP file</param>
         * /// <param name="frameLength">Frame size representing number of bytes to read</param>
         * /// <returns>Byte array filled with binary frame data</returns>
         * private byte[] GetTCPDPckFrameData(PmFrame fr)
         * {
         *  //binreader.BaseStream.Position = offset + 16;
         *  BinReader.BaseStream.Seek(fr.FrameOffset + 16, SeekOrigin.Begin);
         *  return BinReader.ReadBytes((int)fr.IncludedLength);
         * }*/

        /// <summary>
        ///     Fills output with appropriate variables from TCPD Packet Header
        /// </summary>
        /// <param name="fr">Target frame</param>
        /// <param name="tsSec">Number of units since beginning of UNIX epoch in seconds</param>
        /// <param name="tsUsec">Number of units since beginning of UNIX epoch in microseconds</param>
        /// <param name="inclLen">Frame length of frame data presented in TCP PCAP File</param>
        /// <param name="origLen">Original frame length as it was received by computer's NIC</param>
        /// <param name="frameData">Binary frame data of inclLen size</param>
        private void GetTcpdPckPacketHeaderRecord(PmFrameBase fr, out Int64 tsSec, out Int64 tsUsec, out Int64 inclLen, out Int64 origLen, out Byte[] frameData)
        {
            tsSec   = this.GetTcpdPckTimestampSeconds(fr.FrameOffset);
            tsUsec  = this.GetTcpdPckTimestampUseconds(fr.FrameOffset);
            inclLen = this.GetTcpdPckIncludedLength(fr.FrameOffset);
            origLen = this.GetTcpdPckOriginalLength(fr.FrameOffset);
            // frameData = GetTCPDPckFrameData(fr);
            frameData = fr.L2Data();
        }
Пример #5
0
        private void AwaitFinishedMessage(Byte[] l7Data, PmFrameBase pdu)
        {
            if (l7Data[0] == Handshake && l7Data[1] == Ssl3VerMajor)
            {
                this.Decrypter.DoDecryption(l7Data, pdu, ref this._decryptedBytes);
                this._decryptedBytes = null;

                this._state = SslSessionState.Intermezzo;
            }
        }
Пример #6
0
        private void AwaitClientKeyExchange(Byte[] l7Data, PmFrameBase pdu)
        {
            if (l7Data[0] == Handshake && l7Data[1] == Ssl3VerMajor && l7Data[5] == ClientKeyExchange)
            {
                this.Decrypter.ClientDirection = pdu.SrcAddress.GetAddressBytes();
                this.Decrypter.KeyDecrypter.ParseClientKeyExchange(l7Data);
                var preMaster = this.Decrypter.KeyDecrypter.DecryptKey();

                // use premaster to get ciphering key
                var master = this.Decrypter.Prf(preMaster, "master secret", this.Decrypter.ClientRnd, this.Decrypter.ServerRnd, 48, l7Data[2]);

                // Save Master key for current session
                SessionsMasterKeys.Add(this._currentSessionID, master);


                var keyBlock = this.Decrypter.Prf(master, "key expansion", this.Decrypter.ServerRnd, this.Decrypter.ClientRnd,
                                                  this.Decrypter.DataDecrypter.MacKeyLength * 2 + this.Decrypter.DataDecrypter.KeyLength * 2 + this.Decrypter.DataDecrypter.IvLength * 2, l7Data[2]);

                this.Decrypter.ClientHMacKey = new Byte[this.Decrypter.DataDecrypter.MacKeyLength];
                this.Decrypter.ServerHMacKey = new Byte[this.Decrypter.DataDecrypter.MacKeyLength];

                Array.Copy(keyBlock, 0, this.Decrypter.ClientHMacKey, 0, this.Decrypter.DataDecrypter.MacKeyLength);
                Array.Copy(keyBlock, this.Decrypter.DataDecrypter.MacKeyLength, this.Decrypter.ServerHMacKey, 0, this.Decrypter.DataDecrypter.MacKeyLength);

                // Only part of key_block is used to encrypt data
                this.Decrypter.DataDecrypter.Init(keyBlock);

                // Look for finished - sent immediately after change cipher spec
                var totalLen = 0;
                do
                {
                    var t = new Byte[2];
                    Array.Copy(l7Data, 3, t, 0, 2);
                    Array.Reverse(t);
                    totalLen += 5;
                    totalLen += BitConverter.ToInt16(t, 0);
                } while(totalLen < l7Data.Length && l7Data[totalLen] != ChangeCipherSpec);

                if (totalLen < l7Data.Length)
                {
                    // 'Finished' is in this pdu
                    totalLen += 6; // ChangeCipherSpec message has 6 bytes
                    var finished = new Byte[l7Data.Length - totalLen];
                    Array.Copy(l7Data, totalLen, finished, 0, finished.Length);
                    this.Decrypter.DoDecryption(finished, pdu, ref this._decryptedBytes);
                    this._decryptedBytes = null;

                    this._state = SslSessionState.Intermezzo;
                }
                else
                {
                    this._state = SslSessionState.NegotiationChangeCipherSpec;
                }
            }
        }
Пример #7
0
        public String GetAppTagShort(IEnumerable <PmCaptureBase> captures, PmFrameBase frame)
        {
            var capture = captures.FirstOrDefault(c => c is PmCaptureMnm) as PmCaptureMnm;
            var byProtocolPortNumber = this.GetFromProtocolPortNumber(frame.SrcPort, frame.DstPort);
            var captureAppTag        = String.Empty;

            if (capture != null)
            {
                captureAppTag = capture.GetApplicationTag(frame.SourceEndPoint, frame.DestinationEndPoint);
            }
            return(this.FormatAppTag(byProtocolPortNumber, frame.IpProtocol, frame.DestinationEndPoint.Port, captureAppTag));
        }
Пример #8
0
 public GsePacket(
     [Required] GseHeader header,
     [Required] byte[] pdu,
     int?crc32,
     PacketType type,
     [Required] PmFrameBase lastFrame)
 {
     this.Header    = header;
     this.PDU       = pdu;
     this.Crc32     = crc32;
     this.Type      = type;
     this.LastFrame = lastFrame;
 }
Пример #9
0
        public DaRFlowDirection DeterminFrameDirection(PmFrameBase frame)
        {
            if (this._firstFrame == null)
            {
                this._firstFrame = this.Frames.FirstOrDefault()?.Frame;
            }
            if (this._firstFrame == null)
            {
                return(DaRFlowDirection.non);
            }

            return(frame.SourceEndPoint.Equals(this._firstFrame.SourceEndPoint) ? DaRFlowDirection.up : DaRFlowDirection.down);
        }
Пример #10
0
 public void AddFrame(PmFrameBase frame)
 {
     frame.OrderingKey = this.NextFrameOrderingKey++;
     if (!this.UnorderedFrameList.Any())
     {
         this.UnorderedFrameList.Add(frame);
         this.BaseFlow.AddL7PDU(this);
     }
     else
     {
         this.UnorderedFrameList.Add(frame);
     }
     frame.L7Pdu = this;
 }
Пример #11
0
        public IEnumerable <L7Conversation> ProcessPmFrame(PmFrameBase frame)
        {
            switch (this.L4Conversation.DeterminFrameDirection(frame))
            {
            case DaRFlowDirection.up:
                return(this.UpFlowUDPFlowTracker.ProcessPmFrame(frame));

            case DaRFlowDirection.down:
                return(this.DownFlowUDPFlowTracker.ProcessPmFrame(frame));

            case DaRFlowDirection.non:
            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #12
0
 public IEnumerable <L7Conversation> ProcessPmFrame(PmFrameBase frame)
 {
     lock (this.UDPFlowReassembler)
     {
         IEnumerable <L7Conversation> l7Conversations = null;
         if (this.CurrentUDPFlow.LastSeen == null || frame.TimeStamp.Subtract((DateTime)this.CurrentUDPFlow.LastSeen).Duration() < this._udpSessionAliveTimeout)
         {
         }
         else
         {
             this.ProcessCurrentUDPFlow();
             this.CurrentUDPFlow = new FramesFirstSeenSortedCollection();
             l7Conversations     = this.FlowStore.PairFlowsAndCreateAndAddConversations();
         }
         this.CurrentUDPFlow.Add(frame);
         return(l7Conversations);
     }
 }
        /// <summary>
        ///     Write Enhanced pcket block to output file based on specified frame.
        ///     Interface will one of the virtual interfaces from vIfaces dictionary
        ///     according to frame link type.
        /// </summary>
        private UInt32 WriteEnhancedPacketBlock(BinaryWriter binWriter, PmFrameBase frame, Dictionary <PmLinkType, PcapNgInterface> vIfaces)
        {
            var frameData = frame.L2Data();

            if (frameData == null)
            {
                return(0);
            }

            var enhancedPacketBlockLength = this.CountEnhancedPacketBlockBlockSize() + (UInt32)frameData.Length;

            var vIface = vIfaces[frame.PmLinkType];

            binWriter.Write((UInt32)0x00000006);
            binWriter.Write(enhancedPacketBlockLength);
            binWriter.Write((UInt32)vIface.InterfaceId);

            var timeStampValue = this.ConvertTimeStampToUint64(frame.TimeStamp);

            binWriter.Write((UInt32)(timeStampValue >> 32));
            binWriter.Write((UInt32)(timeStampValue & 0xFFFFFFFF));

            binWriter.Write(frame.IncludedLength);
            //binWriter.Write(frame.OriginalLength);
            frame.L2OffsetCaptureL4 = binWriter.Seek(0, SeekOrigin.Current);
            frame.L3OffsetCaptureL4 = frame.L2OffsetCaptureL4 + (frame.L3Offset - frame.L2Offset);
            frame.L4OffsetCaptureL4 = frame.L4Offset == -1? frame.L4Offset : (frame.L2OffsetCaptureL4 + (frame.L4Offset - frame.L2Offset));
            frame.L7OffsetCaptureL4 = frame.L7Offset == -1? frame.L7Offset : (frame.L2OffsetCaptureL4 + (frame.L7Offset - frame.L2Offset));
            frame.IsDoneUpdateOffsetsForCaptureL4 = true;
            binWriter.Write(frameData);

            var paddingLen = this.CountPadding((UInt32)frameData.Length);

            for (UInt32 i = 0; i < paddingLen; i++)
            {
                binWriter.Write((Byte)0x00);
            }

            binWriter.Write(enhancedPacketBlockLength);

            return(enhancedPacketBlockLength + paddingLen);
        }
Пример #14
0
 private void AwaitChangeCipherSpecMessage(Byte[] l7Data, PmFrameBase pdu)
 {
     if (l7Data[0] == ChangeCipherSpec && l7Data[1] == Ssl3VerMajor && l7Data[5] == ChangeCipherSpecMessage)
     {
         //1 byte for content type
         //2 bytes for protocol version
         //2 bytes for message length
         //1 byte for change cypher spec message
         if (l7Data.Length > 6) //If finished message follows directly after Change Cipher Spec
         {
             var l7FinishedMsg = new byte[l7Data.Length - 6];
             Array.Copy(l7Data, 6, l7FinishedMsg, 0, l7Data.Length - 6);
             this.AwaitFinishedMessage(l7FinishedMsg, pdu);
         }
         else
         {
             this._state = SslSessionState.NegotiationFinished;
         }
     }
 }
Пример #15
0
        public virtual void ProcessFrame(PmFrameBase frame)
        {
            if (this.IsStatisticOfConversation) //Base class l3conversation
            {
                var conversationStatistics = this._converation.SourceEndPoint.Address.Equals(frame.SourceEndPoint.Address)? this.UPFlowStatistic : this.DownFlowStatistic;
                conversationStatistics.ProcessFrame(frame);
                return;
            }

            this.Bytes += frame.IncludedLength;
            this.Frames++;
            if (frame.IsMalformed)
            {
                this.MalformedFrames++;
            }
            if (frame.TimeStamp < this.FirstSeen)
            {
                this.FirstSeen = frame.TimeStamp;
            }
            if (frame.TimeStamp > this.LastSeen)
            {
                this.LastSeen = frame.TimeStamp;
            }
        }
Пример #16
0
        public Boolean DoDecryption(Byte[] pdu, PmFrameBase frame, ref Byte[] decryptedBytes)
        {
            var source = frame.SrcAddress.GetAddressBytes();
            var bytes  = pdu;

            var hmac = new HMac(this.DataDecrypter.Digest);

            // get content type - protocol id
            var ct = new Byte[1];

            Array.Copy(bytes, 0, ct, 0, 1);

            // get version - tls version next two bytes
            var version = new Byte[2];

            Array.Copy(bytes, 1, version, 0, 2);

            // get data length
            var len = new Byte[2];

            Array.Copy(bytes, 3, len, 0, 2);

            Array.Reverse(len);
            Int32 dataLen = BitConverter.ToInt16(len, 0);

            // get data
            var data = new Byte[dataLen];

            // not whole data - continuation in next frame
            if (bytes.Length < dataLen + 5)
            {
                this.ContinuationData = new Byte[bytes.Length];
                Array.Copy(bytes, this.ContinuationData, this.ContinuationData.Length);
                return(false);
            }

            // more than enough data - new frame starts here
            if (bytes.Length > dataLen + 5)
            {
                this.ContinuationData = new Byte[bytes.Length - dataLen - 5];
                Array.Copy(bytes, dataLen + 5, this.ContinuationData, 0, this.ContinuationData.Length);
            }

            Array.Copy(bytes, 5, data, 0, dataLen);

            /* decryption */

            var sequenceNum = 0;

            Byte[] decrypted = null;

            try
            {
                switch (this.DataDecrypter.Mode)
                {
                case CipherMode.Cbc:
                    decrypted = this.BlockDecryption(source, data, hmac, out sequenceNum);
                    break;

                case CipherMode.Stream:
                    decrypted = this.StreamDecryption(source, data, hmac, out sequenceNum);
                    break;

                case CipherMode.Ccm:
                    return(false);

                case CipherMode.Gcm:
                    decrypted = this.AeadDecryption(source, data);
                    break;
                }
            }
            catch (InvalidCipherTextException e)
            {
                ("PDUDecryter : " + e.Message).PrintInfo();
                return(false);
            }


            /* check if decrypted data are correct */

            /* GCM has no mac */
            if (this.DataDecrypter.Mode == CipherMode.Gcm)
            {
                return(true);
            }

            var msgLen = decrypted.Length;

            // strip padding - if CBC
            if (this.DataDecrypter.Mode == CipherMode.Cbc)
            {
                var pad = decrypted[decrypted.Length - 1];
                msgLen -= pad + 1;
            }
            // strip mac
            msgLen -= this.DataDecrypter.Digest.GetDigestSize();

            if (msgLen < 1)
            {
                return(false);
            }

            var msg = new Byte[msgLen];

            Array.Copy(decrypted, msg, msgLen);

            var recvDigest = new Byte[this.DataDecrypter.Digest.GetDigestSize()];

            Array.Copy(decrypted, msgLen, recvDigest, 0, recvDigest.Length);

            var ignoreHmac = true;

            if (this.tls_hmac_check(sequenceNum, hmac, ct, version, msgLen, msg, recvDigest) || ignoreHmac)
            {
                Byte[] tmp = null;
                if (decryptedBytes != null)
                {
                    tmp = new Byte[decryptedBytes.Length];
                    Array.Copy(decryptedBytes, tmp, tmp.Length);
                    decryptedBytes = new Byte[tmp.Length + msg.Length];
                    Array.Copy(tmp, decryptedBytes, tmp.Length);
                    Array.Copy(msg, 0, decryptedBytes, tmp.Length, msg.Length);
                }
                else
                {
                    decryptedBytes = new Byte[msg.Length];
                    Array.Copy(msg, decryptedBytes, msg.Length);
                }


                return(true);
            }

            // If bad decrypted decrease sequence number
            if (Enumerable.SequenceEqual(source, this.ClientDirection))
            {
                this.DataDecrypter.DecreaseClientSeq();
            }
            else
            {
                this.DataDecrypter.DecreaseServerSeq();
            }
            return(false);
        }
Пример #17
0
        protected Boolean DecryptPdus()
        {
            if (!this.Pdus.Any())
            {
                return(false);
            }

            // decrypt next message
            for (this._msgUnderReview = 0; this._msgUnderReview < this.Pdus.Count(); this._msgUnderReview++)
            {
                //if (this._msgUnderReview == this._pdus.Count())
                //    return false;

                var pduElement = this.Pdus.ElementAt(this._msgUnderReview);
                this._processedPdus.Add(pduElement);
                for (var frameNum = 0; frameNum < pduElement.FrameList.Count(); frameNum++)
                {
                    //Console.WriteLine("Frame > "+frame.FrameIndex);

                    var frame = pduElement.FrameList.ElementAt(frameNum);
                    if (frame is PmFrameVirtualBlank)
                    {
                        continue;
                    }

                    var l7Data = new Byte[frame.PmPacket.SegmentPayloadLength];
                    Array.Copy(frame.L7Data(), 0, l7Data, 0, l7Data.Length);

                    if (this.Decrypter.ContinuationData != null && l7Data.Length != 0 && this._previousFrame != null)
                    {
                        // Check that the frame is in the same direction as previous in processing
                        // when continuation of data happend last decryption ended with false and state change to INTERMEZZO
                        if (Enumerable.SequenceEqual <byte>(frame.SourceEndPoint.Address.GetAddressBytes(), this._previousFrame.SourceEndPoint.Address.GetAddressBytes()))
                        {
                            var tmp = l7Data;
                            l7Data = new Byte[tmp.Length + this.Decrypter.ContinuationData.Length];
                            Array.Copy(this.Decrypter.ContinuationData, 0, l7Data, 0, this.Decrypter.ContinuationData.Length);
                            Array.Copy(tmp, 0, l7Data, this.Decrypter.ContinuationData.Length, tmp.Length);
                            this.Decrypter.ContinuationData = null;
                        }
                        else
                        {
                            // If not same direction try to decrypt what is left in _continuationData
                            this._msgUnderReview--;
                            frame  = this._previousFrame;
                            l7Data = new Byte[this.Decrypter.ContinuationData.Length];
                            Array.Copy(this.Decrypter.ContinuationData, 0, l7Data, 0, this.Decrypter.ContinuationData.Length);
                            this.Decrypter.ContinuationData = null;
                        }
                    }

                    // Here it is safe to set previous frame
                    this._previousFrame = frame;

                    try
                    {
                        switch (this._state)
                        {
                        case SslSessionState.NegotiationInit:
                            this.AwaitHelloMessages(l7Data, frame);
                            break;

                        case SslSessionState.Negotiation:
                            this.AwaitClientKeyExchange(l7Data, frame);
                            break;

                        case SslSessionState.NegotiationChangeCipherSpec:
                            this.AwaitChangeCipherSpecMessage(l7Data, frame);
                            break;

                        case SslSessionState.NegotiationFinished:
                            this.AwaitFinishedMessage(l7Data, frame);
                            break;

                        case SslSessionState.Intermezzo:
                            this.AwaitEncryptedMessage(l7Data, frame);
                            break;

                        case SslSessionState.DataExchange:
                            this.AwaitEncryptedMessage(l7Data, frame);
                            break;
                        }
                    }
                    catch (NullReferenceException e)
                    {
                        // No L7 data
                        PmConsolePrinter.PrintError("PDUDecrypter : " + e.Message + " : in frame " + frame.FrameIndex);
                    }
                    catch (NotImplementedException e)
                    {
                        ("PDUDecrypterCipher : " + e.Message).PrintInfo();
                        //return false;
                    }
                }

                if (this._decryptedBytes != null)
                {
                    //this.DataList.Add(new DecryptedData { Data = this._decryptedBytes, pdu = this._processedPdus.Last() });
                    this.DataList.Add(new DecryptedData
                    {
                        Data = this._decryptedBytes,
                        PDU  = this.Pdus.ElementAt(this._msgUnderReview)
                    });
                    this._decryptedBytes = null;
                    this.EndOfStream     = false;
                }
            }

            while (this.Decrypter.ContinuationData != null) //Process remaining data in buffer
            {
                var l7Data = new byte[this.Decrypter.ContinuationData.Length];
                Array.Copy(this.Decrypter.ContinuationData, l7Data, this.Decrypter.ContinuationData.Length);
                this.Decrypter.ContinuationData = null;
                try {
                    this.AwaitEncryptedMessage(l7Data, this._previousFrame);
                }
                catch (NullReferenceException e)
                {
                    // No L7 data
                    PmConsolePrinter.PrintError("PDUDecrypter : " + e.Message + " : in frame " + this._previousFrame.FrameIndex);
                }
                catch (NotImplementedException e)
                {
                    ("PDUDecrypterCipher : " + e.Message).PrintInfo();
                    //return false;
                }

                if (this._decryptedBytes != null)
                {
                    this.DataList.Add(new DecryptedData
                    {
                        Data = this._decryptedBytes,
                        PDU  = this._processedPdus.Last()
                    });
                }
                this._decryptedBytes = null;
                this.EndOfStream     = false;
            }

            this._dataDecrypted = true;

            return(true);
        }
Пример #18
0
        private void AwaitHelloMessages(Byte[] l7Data, PmFrameBase pdu)
        {
            // Get server hello message
            if (l7Data[0] == Handshake && l7Data[1] == Ssl3VerMajor && l7Data[5] == ServerHello)
            {
                this.Decrypter.ServerRnd = new Byte[32];

                Array.Copy(l7Data, 11, this.Decrypter.ServerRnd, 0, this.Decrypter.ServerRnd.Length);

                ConversationCipherSuite conversationCipherSuite;
                KeyDecrypter            keyDecrypter;
                DataDecrypter           dataDecrypter;

                this.Decrypter.ChangeCipherSuite(l7Data, out conversationCipherSuite);
                this._conversation.CipherSuite = conversationCipherSuite;

                CipherSuiteInitializer.PrepareDecryptingAlgorithms(this._conversation.Key.ServerPrivateKey, this._conversation.CipherSuite, out keyDecrypter, out dataDecrypter);

                this.Decrypter.KeyDecrypter  = keyDecrypter;
                this.Decrypter.DataDecrypter = dataDecrypter;

                // Get SSL Session ID and save it
                var sessionID = new Byte[32];
                Array.Copy(l7Data, 44, sessionID, 0, 32);
                Array.Copy(sessionID, this._currentSessionID, this._currentSessionID.Length);

                // Get ServerHello content length
                var serverHelloContentLengthBytes = new Byte[2];
                Array.Copy(l7Data, 3, serverHelloContentLengthBytes, 0, 2);
                Array.Reverse(serverHelloContentLengthBytes);
                var serverHelloContentLength = BitConverter.ToUInt16(serverHelloContentLengthBytes, 0);

                // Get total ServerHello length
                // ContentType(1B) Version(2B) Length(2B) Content
                var serverHelloLength = 1 + 2 + 2 + serverHelloContentLength;

                // Check whether there is something else after ServerHello message and whether it is ChangeCipherSpec message
                // If yes, session resumption is used
                if (serverHelloLength < l7Data.Length && l7Data[serverHelloLength + 0] == ChangeCipherSpec && SessionsMasterKeys.ContainsKey(sessionID))
                {
                    this.Decrypter.ClientDirection = pdu.DstAddress.GetAddressBytes();

                    // Load saved Master key for given Session ID
                    var master = SessionsMasterKeys[sessionID];


                    var keyBlock = this.Decrypter.Prf(master, "key expansion", this.Decrypter.ServerRnd, this.Decrypter.ClientRnd,
                                                      this.Decrypter.DataDecrypter.MacKeyLength * 2 + this.Decrypter.DataDecrypter.KeyLength * 2 + this.Decrypter.DataDecrypter.IvLength * 2, l7Data[2]);

                    this.Decrypter.ClientHMacKey = new Byte[this.Decrypter.DataDecrypter.MacKeyLength];
                    this.Decrypter.ServerHMacKey = new Byte[this.Decrypter.DataDecrypter.MacKeyLength];

                    Array.Copy(keyBlock, 0, this.Decrypter.ClientHMacKey, 0, this.Decrypter.DataDecrypter.MacKeyLength);
                    Array.Copy(keyBlock, this.Decrypter.DataDecrypter.MacKeyLength, this.Decrypter.ServerHMacKey, 0, this.Decrypter.DataDecrypter.MacKeyLength);

                    // Only part of key_block is used to encrypt data
                    this.Decrypter.DataDecrypter.Init(keyBlock);

                    var changeCipherSpecLength = 6;
                    if (serverHelloLength + changeCipherSpecLength < l7Data.Length)
                    {
                        var finishedOffset = serverHelloLength + changeCipherSpecLength;
                        var finished       = new Byte[l7Data.Length - finishedOffset];
                        Array.Copy(l7Data, finishedOffset, finished, 0, finished.Length);
                        this.Decrypter.DoDecryption(finished, pdu, ref this._decryptedBytes);
                        this._decryptedBytes = null;
                    }

                    this._state = SslSessionState.NegotiationChangeCipherSpec;
                }
                // Otherwise, new session is made
                else
                {
                    this._state = SslSessionState.Negotiation;
                }
            }
            else if (l7Data[0] == Handshake && l7Data[1] == Ssl3VerMajor && l7Data[5] == ClientHello)
            {
                // client hello - should be found before server hello message
                this.Decrypter.ClientRnd = new Byte[32];
                Array.Copy(l7Data, 11, this.Decrypter.ClientRnd, 0, this.Decrypter.ClientRnd.Length);
            }
        }
Пример #19
0
 public FrameVm(WindsorContainer applicationWindsorContainer, PmFrameBase model) : base(applicationWindsorContainer, model)
 {
     this.FwFrame      = model;
     this._initialized = true;
 }
Пример #20
0
 public DaRFlowDirection DeterminFrameDirection(PmFrameBase frame)
 {
     return(frame.DstPort == this.DestinationEndPointPort? DaRFlowDirection.up : DaRFlowDirection.down);
 }
Пример #21
0
 /// <summary> Adds a non data frame.</summary>
 /// <param name="frame"> The frame. </param>
 private void AddNonDataFrame(PmFrameBase frame) => this.CurrentTCPFlow.NonDataFrames.Add(frame);
Пример #22
0
        private void ProcessTcpSession(PmFrameBase synFrame)
        {
            var wasTCPSeqLoop = false;

            this.TCPFlowEnumerator = this.TCPSynOrderedFrames.GetEnumerator();

            //find first frame frame of session
            while (this.TCPFlowEnumerator.Current != synFrame)
            {
                if (!this.TCPFlowEnumerator.MoveNext())
                {
                    throw new InvalidOperationException("Init frame does not exists!");
                }
            }

            this.CurrentFrame   = this.TCPFlowEnumerator.Current;
            this.CurrentTCPFlow = this.FlowStore.CreateAndAddFlow(this.FlowDirection);
            this.LastTimestamp  = this.CurrentFrame.TimeStamp;

            this.CurrentPDU = null;

            //Init flow direction identifier
            if (this.CurrentFrame.TcpFSyn && !this.CurrentFrame.TcpFAck) //SYN packet
            {
                this.CurrentTCPFlow.FlowIdentifier = this.CurrentFrame.TcpSequenceNumber + 1;
            }
            else if (this.CurrentFrame.TcpFSyn && this.CurrentFrame.TcpFAck) //SYN+ACK packet
            {
                this.CurrentTCPFlow.FlowIdentifier = this.CurrentFrame.TcpAcknowledgementNumber;
            }


            if (this.CurrentFrame.TcpFSyn)
            {
                // while in a case that there are more retransmitted frames with SYN flag
                while (this.CurrentFrame != null && this.CurrentFrame.TcpFSyn && this.CurrentFrame.TcpSequenceNumber == synFrame.TcpSequenceNumber &&
                       this.CurrentFrame.TcpAcknowledgementNumber == synFrame.TcpAcknowledgementNumber)
                {
                    this.ExpectedSequenceNumber = (UInt32)this.CurrentFrame.TcpSequenceNumber + 1;
                    this.AddNonDataFrame();
                    this.NextFrame();
                }
                // in a case that there are captured only a SYN frames and not the rest of the session
                if (this.CurrentFrame == null)
                {
                    return;
                }
            }
            else
            {
                this.ExpectedSequenceNumber = (UInt32)this.CurrentFrame.TcpSequenceNumber;
            }

            while (this.TestTCPSessionEnd(ref wasTCPSeqLoop))
            {
                if (this.CurrentFrame.IsMalformed)
                {
                    this.AddNonDataFrame();
                    this.NextFrame();
                    continue;
                }
                if (this.CurrentFrame.TimeStamp.Subtract(this.LastTimestamp).Duration() > this.TCPSessionAliveTimeout)
                {
                    this.SkipFrame();
                    continue;
                }
                if (this.CurrentPDU == null)
                {
                    this.CurrentPDU = this.CurrentTCPFlow.CreateL7PDU();
                }

                var x = this.CurrentFrame.TcpSequenceNumber - this.ExpectedSequenceNumber;

                if (x > 0)
                {
                    this.TCPMissingSegment(x);
                }
                else if (x < 0)
                {
                    //in case that packet is TCPSyn retranssmit
                    //if (_currentFrame.TcpFSyn || _currentFrame.TcpFFin || _currentFrame.TcpFRst)
                    //{
                    //    NextFrame();
                    //    continue;
                    //}


                    // TCP keep live packet, TCP ACK
                    if (this.CurrentFrame.TcpFAck && (this.CurrentFrame.L7PayloadLength == -1 || this.CurrentFrame.L7PayloadLength == 1))
                    //if (x == -1 && _currentFrame.TcpFAck && (_currentFrame.L7PayloadLength == -1 || _currentFrame.L7PayloadLength == 1))
                    // && _currentFrame.L7PayloadLength == -1 //could be also  _currentFrame.L7PayloadLength == 1
                    {
                        this.AddNonDataFrame();
                        this.NextFrame(); //skip keepalive frame
                        continue;
                    }

                    ////TODO find what causes this
                    //if (_currentFrame.L7PayloadLength == -1)
                    //{
                    //    AddNonDataFrame();
                    //    NextFrame(); //skip keepalive frame
                    //    continue;
                    //}


                    //in case of retransmission, TCP Checksum must be computed
                    var parsedFrame = this.CurrentFrame.PmPacket;
                    if (parsedFrame.IsValidChecksum) // frame is valid, let's use it
                    {
                        //end of current TCP session
                        if (this.CurrentFrame.TcpFFin || this.CurrentFrame.TcpFRst)
                        {
                            this.FiNorRstProcess();
                            break;
                        }

                        if (!this.CurrentPDU.FrameList.Any() && // _currentPDU has no frames
                            this.CurrentTCPFlow.PDUs.Any())     // CurrentTCPFlow has some PDUs
                        {
                            this.CurrentPDU = this.CurrentTCPFlow.GetLastPDU();
                        }

                        if (this.CurrentPDU.FrameList.Any()) // _currentPDU has some frames
                        {
                            var lastPduFrame = this.CurrentPDU.FrameList.Last();


                            if (this.CurrentFrame.TcpSequenceNumber == lastPduFrame.TcpSequenceNumber && lastPduFrame.PmPacket.IsValidChecksum)
                            {
                                this.AddNonDataFrame();
                                //end of current L7PDU
                                if ((this.CurrentFrame.TcpFPsh || this.CurrentFrame.L7PayloadLength < this.L4Conversation.L4FlowMTU) && this.CurrentPDU.FrameList.Any())
                                {
                                    this.CurrentPDU = null;
                                }
                                this.NextFrame();
                                continue;
                            }
                            //todo SACK http://superuser.com/questions/598574/if-a-tcp-packet-got-partially-acknowledged-how-will-the-retransmission-mechanis //example tcp_retr1.pcapng 7,8,11,12 frames
                            //this bypass and ignores SACK ... assuming that correct packet have been captred and lost occured on the way
                            if (this.CurrentFrame.TcpSequenceNumber > lastPduFrame.TcpSequenceNumber && x < lastPduFrame.L7PayloadLength && lastPduFrame.PmPacket.IsValidChecksum)
                            {
                                this.AddNonDataFrame();
                                //end of current L7PDU
                                if ((this.CurrentFrame.TcpFPsh || this.CurrentFrame.L7PayloadLength < this.L4Conversation.L4FlowMTU) && this.CurrentPDU.FrameList.Any())
                                {
                                    this.CurrentPDU = null;
                                }
                                this.NextFrame();
                                continue;
                            }
                            var removedFrame = this.CurrentPDU.RemoveLastFrame();
                            this.AddNonDataFrame(removedFrame);
                        }
                        else // _currentPDU has no frames, get rid of it
                        {
                            this.CurrentTCPFlow.RemoveL7PDU(this.CurrentPDU);
                            this.CurrentPDU = this.CurrentTCPFlow.CreateL7PDU();
                        }
                    }
                    else
                    //if checksum is not valid frame is skipped
                    {
                        this.AddNonDataFrame();
                        //end of current L7PDU
                        if ((this.CurrentFrame.TcpFPsh || this.CurrentFrame.L7PayloadLength < this.L4Conversation.L4FlowMTU) && this.CurrentPDU.FrameList.Any())
                        {
                            this.CurrentPDU = null;
                        }
                        this.NextFrame();
                        continue;
                    }
                }
                //else //x == 0{//normal state}

                //L4PDU add frame to list
                if (this.CurrentFrame.L7PayloadLength > 0)
                {
                    if (this.CurrentPDU.LowestTCPSeq == null)
                    {
                        this.CurrentPDU.LowestTCPSeq = this.CurrentFrame.TcpSequenceNumber;
                    }
                    this.CurrentPDU.ExtractedBytes += this.CurrentFrame.L7PayloadLength;
                    this.CurrentPDU.AddFrame(this.CurrentFrame);

                    //If frame is IPv4 fragmented find remaining fragments
                    if (this.CurrentFrame.Ipv4FMf)
                    {
                        Int64 extractedBytes;
                        var   defragmentedFrames = this.FindFragments(this.CurrentFrame, out extractedBytes);

                        this.CurrentPDU.RemoveLastFrame();
                        this.CurrentPDU.ExtractedBytes -= this.CurrentFrame.L7PayloadLength;

                        this.CurrentPDU.AddFrameRange(defragmentedFrames);
                        this.CurrentPDU.ExtractedBytes += extractedBytes;
                        this.ExpectedSequenceNumber     = (UInt32)(this.CurrentFrame.TcpSequenceNumber + extractedBytes);
                    }
                    else
                    {
                        //Normal state, increment expected sequence number
                        this.ExpectedSequenceNumber = (UInt32)(this.CurrentFrame.TcpSequenceNumber + this.CurrentFrame.L7PayloadLength);
                    }
                }

                //end of current TCP session
                if (this.CurrentFrame.TcpFSyn)
                {
                    break;
                }
                if (this.CurrentFrame.TcpFFin || this.CurrentFrame.TcpFRst)
                {
                    this.FiNorRstProcess();
                    break;
                }

                //end of current L7PDU
                if ((this.CurrentFrame.TcpFPsh || this.CurrentFrame.L7PayloadLength < this.L4Conversation.L4FlowMTU) && this.CurrentPDU.FrameList.Any())
                {
                    this.CurrentPDU = null;
                }

                if (this.CurrentFrame.L7PayloadLength <= 0)
                {
                    this.AddNonDataFrame();
                }
                this.NextFrame();
            }
        }