/// <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); }
public void ChangeCipherSuite(Byte[] data, out ConversationCipherSuite cipherSuite) { try { var len = new Byte[2]; Array.Copy(data, 3, len, 0, 2); Array.Reverse(len); // 1 byte for type // 2 bytes tls/ssl version // 2 bytes PDU length var offset = 5; len = new Byte[4]; // only 3 bytes are used so offset is 1 Array.Copy(data, offset + 1, len, 1, 3); Array.Reverse(len); // Should be server hello message // 71-72 position of bytes in Server hello message that inform about ciphersuite len = new Byte[2]; Array.Copy(data, offset + 71, len, 0, 2); Array.Reverse(len); var cs = BitConverter.ToInt16(len, 0); cipherSuite = (ConversationCipherSuite)cs; } catch (IndexOutOfRangeException e) { PmConsolePrinter.PrintError("PDUDecrypter : Problem when parsing ServerHello : " + e.Message); cipherSuite = ConversationCipherSuite.TlsNullWithNullNull; } }
/// <summary> /// Create PCAP-ng file that includes all frames stored in current instace. /// For each link type will be created "virtual interface" and all frames /// with this link type will in output file belong to it. /// </summary> private Boolean CreatePcapNgOutput(String outputFile) { try { // holds list of all link types inclede in frame vector var framesLinkTypes = new List <PmLinkType>(); // TODO - optimize LINQ ? foreach (var fr in this.PmCapture.Frames) { if (!framesLinkTypes.Contains(fr.PmLinkType)) { framesLinkTypes.Add(fr.PmLinkType); } } // holds list of new created virtual interfaces : var virtualInterfaces = new List <PcapNgInterface>(); // directory for faster lookup : var virtualInterfacesDictionary = new Dictionary <PmLinkType, PcapNgInterface>(); UInt16 ifaceId = 0; foreach (var type in framesLinkTypes) { // create new itnerface for each link type : var newIface = new PcapNgInterface((UInt16)ConvertCommonLayer2ToPcapNgLayer2(type), ifaceId); virtualInterfaces.Add(newIface); virtualInterfacesDictionary.Add(type, newIface); ifaceId++; } // open output file stream : var binWriter = new BinaryWriter(File.Open(Path.GetFullPath(outputFile), FileMode.Create, FileAccess.Write, FileShare.ReadWrite)); // skipt section header for now - will be add at end binWriter.BaseStream.Seek(this.CountSectionHeaderBlockSize(), SeekOrigin.Begin); var sectionSize = virtualInterfaces.Aggregate <PcapNgInterface, UInt64>(0, (current, iface) => current + this.WriteInterfaceDescriptionBlock(binWriter, iface)); sectionSize = this.PmCapture.Frames.Aggregate(sectionSize, (current, fr) => current + this.WriteEnhancedPacketBlock(binWriter, fr, virtualInterfacesDictionary)); // add section header size (section size is now known) : binWriter.BaseStream.Seek(0, SeekOrigin.Begin); this.WriteSectionHeaderBlock(binWriter, sectionSize); // close output file binWriter.Close(); } /* If anything went bad generate exception and return false */ catch (Exception ex) //todo to general { //todo fix //Log.Error("PmCaptureProcessorPcapNg General error", ex); PmConsolePrinter.PrintError(ex.Message); return(false); } /* otherwise return true if everything went good */ return(true); }
/// <summary> /// Initialize FrameTables and appropriate FrameVectors from input file /// </summary> protected override async Task <Boolean> ParseCaptureFile() { try { await this.ParseFile(); } catch (Exception ex) //todo to general { //todo fix //Log.Error("PmCaptureProcessorPcapNg General error", ex); PmConsolePrinter.PrintError("Error>\n" + ex.Message); return(false); } return(true); }
/// <summary> /// Initialize FrameTables and appropriate FrameVectors from input file /// </summary> protected override async Task <Boolean> ParseCaptureFile() { try { this.ParseTcpdHeader(); this._pmLinkType = ConvertPcapLayer2ToCommonLayer2(this._pcapLinkType); await this.ParseTcpdFrameTable(); } catch (EndOfStreamException ex) { //todo fix //Log.Error("Some packet was malformed and ended prematurely.", ex); PmConsolePrinter.PrintError("Error>\n" + ex.Message); } catch (Exception ex) //todo to general { //todo fix //Log.Error("PmCaptureProcessorPcap General error", ex); PmConsolePrinter.PrintError("Error>\n" + ex.Message); return(false); } return(true); }
/// <summary> /// Generate TCP Dump LibPCAP format output file /// </summary> /// <param name="outFile">File name or file path that will be converted to absolute file path</param> /// <returns></returns> protected Boolean CreateTcpdOutput(String outFile) { try { var bw = new BinaryWriter(File.Open(Path.GetFullPath(outFile), FileMode.Create)); /* TCP Dump format global header variables */ const UInt32 magicNumber = 0xa1b2c3d4; const UInt16 versionMaj = 0x2; const UInt16 versionMin = 0x4; /* Use first record as refernce TZI offset */ // Int32 thisZoneSec = timeZoneOffset; // no conversion needed // var linkType = (UInt32)RealFrames.First().PmPcapFile.TCPDLinkType; //TODO: Add TZI functionality const Int32 thisZoneSec = 0; var fileLinkType = TcpdLinkType.Null; var referenceLinkType = PmLinkType.Null; var frames = this.PmCapture.Frames.ToArray(); if (frames.Any()) { referenceLinkType = frames.First().PmLinkType; fileLinkType = ConvertCommonLayer2ToPcapLayer2(referenceLinkType); } var linkTypeValue = (UInt32)fileLinkType; const UInt32 sigFigs = 0; const UInt32 snapLen = 0x0000ffff; //Console.WriteLine("{0:x}|{1:x}|{2:x}|{3:x}|{4:x}|{5:x}|{6:x}", magicNumber, versionMaj, versionMin, thisZoneSec, sigFigs, snapLen, linkType); /* Write Global Header */ bw.Write(magicNumber); bw.Write(versionMaj); bw.Write(versionMin); bw.Write(thisZoneSec); bw.Write(sigFigs); bw.Write(snapLen); bw.Write(linkTypeValue); /* Write frames */ foreach (var fr in frames.Where(fr => fr.PmLinkType == referenceLinkType)) { /* Convert DateTime timestamp to TCPD variables used in TCPD Packet Header*/ UInt32 sec; UInt32 usec; ConvertUnixTimeToTcpd(ConvertDateToUnixTime(fr.TimeStamp), out sec, out usec); bw.Write(sec); bw.Write(usec); bw.Write(fr.IncludedLength); bw.Write(fr.OriginalLength); // bw.Write(GetTCPDPckFrameData(fr)); bw.Write(fr.L2Data()); } bw.Close(); } /* If anything went bad generate exception and return false */ catch (Exception ex) //todo to general { //todo fix //Log.Error("PmCaptureProcessorPcap General error", ex); PmConsolePrinter.PrintError(ex.Message); return(false); } /* otherwise return true if everything went good */ return(true); }
/// <summary> /// Fill L3, L4, L7 offsets and other useful information related to IP fragmentation or TCP reassembling /// BEAWARE Runns in Parallel /// </summary> /// <returns>Everything went fine ? true : false</returns> public virtual async Task IndexFrame(IPmCaptureProcessorBlockBase captureProcessorBlockBase) { try { this.PmCaptureRefId = this.PmCapture.Id; //TODO: After Packet.Extract refactor, what is current efficiency of this method? var packet = this.PmPacket; this.L3Offset = this.L2Offset + packet.PacketHeaderOffset; this.L4Offset = this.L2Offset + packet.SegmentHeaderOffset; //Verify that L4Payload has some data, if not then leave L7Offset uninitialized //TODO: Vesely - What about frames with L4Payload + padding? For them IncludedLength shoud be recounted! this.L7Offset = packet.SegmentPayloadLength != 0 ? this.L2Offset + packet.SegmentPayloadOffset : -1; this.IpProtocol = packet.ProtocolIdentifier; //Create virtual frame from tunel protocol payload switch (packet.ProtocolIdentifier) { case IPProtocolType.IP: case IPProtocolType.TCP: case IPProtocolType.UDP: this.SrcAddress = packet.SourceAddress; this.DstAddress = packet.DestinationAddress; break; case IPProtocolType.GRE: await captureProcessorBlockBase.CreateAndAddToMetaFramesVirtualFrame(this, packet); break; //Possible 6in4 case IPProtocolType.IPV6: this.SrcAddress = packet.SourceAddress; this.DstAddress = packet.DestinationAddress; if (packet.IpVersion == IpVersion.IPv4) { await captureProcessorBlockBase.CreateAndAddToMetaFramesVirtualFrame(this, packet); } break; //Possible Teredo // TODO: Looooot of exceptions //case IPProtocolType.UDP: // if(packet.IpVersion == IpVersion.IPv4) { this.CreateAndAddToMetaFramesVirtualFrame(this, packet); } // break; } this.SrcPort = packet.SourceTransportPort; this.DstPort = packet.DestinationTransportPort; this.Ipv4FIdentification = packet.Ipv4Identification; this.Ipv4FMf = packet.Ipv4MFbit; this.Ipv4FragmentOffset = packet.Ipv4FragmentOffset; this.TcpFAck = packet.TcpFAck; this.TcpFCwr = packet.TcpFCwr; this.TcpFEce = packet.TcpFEce; this.TcpFFin = packet.TcpFFin; // TODO: PacketDotNet can't read NS this.TcpFNs = false; // packet.TcpFNs; this.TcpFPsh = packet.TcpFPsh; this.TcpFRst = packet.TcpFRst; this.TcpFSyn = packet.TcpFSyn; this.TcpFUrg = packet.TcpFUrg; this.TcpSequenceNumber = packet.TcpSequenceNumber; this.TcpAcknowledgementNumber = packet.TcpAcknowledgmentNumber; this.L7PayloadLength = packet.SegmentPayloadLength; } catch (Exception ex) //TODO To general, it would be better to catch more and specific exceptions { this.IsMalformed = true; //Debugger.Break(); //todo fix //Log.Error( //"PmCaptureProcessorBase Cannot parse frame: " + (this.FrameIndex) + " in file: " + this.GetFileName() + // ". It is marked as malformed!", ex); PmConsolePrinter.PrintError("Cannot parse frame: " + (this.FrameIndex) + " in file: " + this.PmCapture.FileInfo.Name + ". It is marked as malformed!\n" + ex.Message); } }
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); }