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); }
/// <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); }
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 }
/* /// <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(); }
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; } }
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; } } }
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)); }
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; }
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); }
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; }
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(); } }
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); }
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; } } }
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; } }
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); }
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); }
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); } }
public FrameVm(WindsorContainer applicationWindsorContainer, PmFrameBase model) : base(applicationWindsorContainer, model) { this.FwFrame = model; this._initialized = true; }
public DaRFlowDirection DeterminFrameDirection(PmFrameBase frame) { return(frame.DstPort == this.DestinationEndPointPort? DaRFlowDirection.up : DaRFlowDirection.down); }
/// <summary> Adds a non data frame.</summary> /// <param name="frame"> The frame. </param> private void AddNonDataFrame(PmFrameBase frame) => this.CurrentTCPFlow.NonDataFrames.Add(frame);
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(); } }