public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable <PacketParser.Packets.AbstractPacket> packetList) { Packets.OscarPacket oscarPacket = null; Packets.TcpPacket tcpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.OscarPacket)) { oscarPacket = (Packets.OscarPacket)p; } else if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } } if (oscarPacket != null && tcpPacket != null) { if (oscarPacket.ImText != null) { base.MainPacketHandler.OnMessageDetected(new PacketParser.Events.MessageEventArgs(ApplicationLayerProtocol.Oscar, sourceHost, destinationHost, oscarPacket.ParentFrame.FrameNumber, oscarPacket.ParentFrame.Timestamp, oscarPacket.SourceLoginId, oscarPacket.DestinationLoginId, oscarPacket.ImText, oscarPacket.ImText, oscarPacket.Attributes)); } return(oscarPacket.BytesParsed); } return(0); }
/* * public string[] GetOperatingSystems(Packets.IPv4Packet ipv4Packet, Packets.TcpPacket tcpPacket) { * byte originalTimeToLive=GetOriginalTimeToLive(ipv4Packet, tcpPacket); * return GetOperatingSystems(ipv4Packet, tcpPacket, originalTimeToLive); * }*/ #region IOsFingerprinter Members public bool TryGetOperatingSystems(out IList <string> osList, IEnumerable <Packets.AbstractPacket> packetList) { //throw new Exception("The method or operation is not implemented."); Packets.IPv4Packet ipv4Packet = null; Packets.TcpPacket tcpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.IPv4Packet)) { ipv4Packet = (Packets.IPv4Packet)p; } else if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } } if (ipv4Packet != null && tcpPacket != null && tcpPacket.FlagBits.Synchronize) { byte originalTimeToLive = GetOriginalTimeToLive(ipv4Packet, tcpPacket); osList = new List <string>(); foreach (string os in GetOperatingSystems(ipv4Packet, tcpPacket, originalTimeToLive)) { osList.Add(os); } if (osList.Count > 0) { return(true); } } osList = null; return(false); }
public override bool TryGetTtlDistance(out byte ttlDistance, IEnumerable <Packets.AbstractPacket> packetList) { Packets.IPv4Packet ipv4Packet = null; Packets.TcpPacket tcpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.IPv4Packet)) { ipv4Packet = (Packets.IPv4Packet)p; } else if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } } if (ipv4Packet != null && tcpPacket != null) { ttlDistance = GetTtlDistance(ipv4Packet, tcpPacket); return(true); } else { ttlDistance = 0; return(false); } }
public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable <Packets.AbstractPacket> packetList) { bool successfulExtraction = false; Packets.CifsPacket.AbstractSmbCommand smbCommandPacket = null; Packets.TcpPacket tcpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType().IsSubclassOf(typeof(Packets.CifsPacket.AbstractSmbCommand))) { smbCommandPacket = (Packets.CifsPacket.AbstractSmbCommand)p; } else if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } } if (tcpPacket != null && smbCommandPacket != null) { successfulExtraction = true; ExtractSmbData(sourceHost, destinationHost, tcpPacket, smbCommandPacket, base.MainPacketHandler); } if (successfulExtraction) { //return tcpPacket.PayloadDataLength; return(0);//changed 2011-04-25 since the NetBiosSessionServicePacketHandler will return the # parsed bytes anyway. } else { return(0); } }
internal bool Matches(Packets.TcpPacket tcpPacket, Packets.IPv4Packet ipPacket) { foreach (string key in attributeList.Keys) { if (key == "weight") { //do nothing } else if (key == "matchtype") { //do nothing, I will alway require an exact match } else if (key == "tcpflag")//used to be "flag" { if (tcpPacket.FlagBits.Synchronize && !attributeList[key].Contains("S")) { return(false); } else if (!tcpPacket.FlagBits.Synchronize && attributeList[key].Contains("S")) { return(false); } else if (tcpPacket.FlagBits.Acknowledgement && !attributeList[key].Contains("A")) { return(false); } else if (!tcpPacket.FlagBits.Acknowledgement && attributeList[key].Contains("A")) { return(false); } else if (tcpPacket.FlagBits.Fin && !attributeList[key].Contains("F")) { return(false); } else if (!tcpPacket.FlagBits.Fin && attributeList[key].Contains("F")) { return(false); } } else if (key == "tcpsig") { //this is the really important part! //now make sure to identify if the fingerprint doesn't match! if (this.p0fFingerprint == null) { return(false); } else { if (!p0fFingerprint.Matches(ipPacket, tcpPacket, base.GetOriginalTimeToLive(ipPacket.TimeToLive))) { return(false); } } } } //since no mis-match was found I guess it was a match... return(true); }
public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable <Packets.AbstractPacket> packetList) { bool successfulExtraction = false; /* * Packets.TlsRecordPacket tlsRecordPacket=null; * Packets.TcpPacket tcpPacket=null; * foreach(Packets.AbstractPacket p in packetList) { * if(p.GetType()==typeof(Packets.TlsRecordPacket)) * tlsRecordPacket=(Packets.TlsRecordPacket)p; * else if(p.GetType()==typeof(Packets.TcpPacket)) * tcpPacket=(Packets.TcpPacket)p; * } * */ Packets.TcpPacket tcpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } } int parsedBytes = 0; if (tcpPacket != null) { //there might be several TlsRecordPackets in an SSL packet foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.TlsRecordPacket)) { Packets.TlsRecordPacket tlsRecordPacket = (Packets.TlsRecordPacket)p; if (tlsRecordPacket.TlsRecordIsComplete) { ExtractTlsRecordData(tlsRecordPacket, tcpPacket, sourceHost, destinationHost, base.MainPacketHandler); successfulExtraction = true; parsedBytes += tlsRecordPacket.Length + 5; } else if (tlsRecordPacket.Length > 4000)//it should have been complete, so just skip it... there is no point in reassembling it any more { successfulExtraction = true; parsedBytes = tcpPacket.PayloadDataLength; } } } } if (successfulExtraction) { return(parsedBytes); //return tcpPacket.PayloadDataLength; } else { return(0); } }
public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable <PacketParser.Packets.AbstractPacket> packetList) { Packets.OscarFileTransferPacket oscarFileTransferPacket = null; Packets.TcpPacket tcpPacket = null; int parsedByteCount = 0; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.OscarFileTransferPacket)) { oscarFileTransferPacket = (Packets.OscarFileTransferPacket)p; } else if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } } if (oscarFileTransferPacket != null && tcpPacket != null) { parsedByteCount = oscarFileTransferPacket.ParsedBytesCount; if (oscarFileTransferPacket.Type == PacketParser.Packets.OscarFileTransferPacket.CommandType.SendRequest) { //see if there is an old assembler that needs to be removed if (base.MainPacketHandler.FileStreamAssemblerList.ContainsAssembler(sourceHost, tcpPacket.SourcePort, destinationHost, tcpPacket.DestinationPort, true)) { FileTransfer.FileStreamAssembler oldAssembler = base.MainPacketHandler.FileStreamAssemblerList.GetAssembler(sourceHost, tcpPacket.SourcePort, destinationHost, tcpPacket.DestinationPort, true); base.MainPacketHandler.FileStreamAssemblerList.Remove(oldAssembler, true); } FileTransfer.FileStreamAssembler assembler = new FileTransfer.FileStreamAssembler(base.MainPacketHandler.FileStreamAssemblerList, sourceHost, tcpPacket.SourcePort, destinationHost, tcpPacket.DestinationPort, true, FileTransfer.FileStreamTypes.OscarFileTransfer, oscarFileTransferPacket.FileName, "", (int)oscarFileTransferPacket.TotalFileSize, (int)oscarFileTransferPacket.TotalFileSize, oscarFileTransferPacket.FileName, "", oscarFileTransferPacket.ParentFrame.FrameNumber, oscarFileTransferPacket.ParentFrame.Timestamp); //assembler.SetRemainingBytesInFile((int)oscarFileTransferPacket.TotalFileSize); base.MainPacketHandler.FileStreamAssemblerList.Add(assembler); } else if (oscarFileTransferPacket.Type == PacketParser.Packets.OscarFileTransferPacket.CommandType.ReceiveAccept) { if (base.MainPacketHandler.FileStreamAssemblerList.ContainsAssembler(destinationHost, tcpPacket.DestinationPort, sourceHost, tcpPacket.SourcePort, true)) { FileTransfer.FileStreamAssembler assembler = base.MainPacketHandler.FileStreamAssemblerList.GetAssembler(destinationHost, tcpPacket.DestinationPort, sourceHost, tcpPacket.SourcePort, true); if (assembler != null) { assembler.TryActivate(); } } } else if (oscarFileTransferPacket.Type == PacketParser.Packets.OscarFileTransferPacket.CommandType.TransferComplete) { //remove assembler from destination to client if (base.MainPacketHandler.FileStreamAssemblerList.ContainsAssembler(destinationHost, tcpPacket.DestinationPort, sourceHost, tcpPacket.SourcePort, true)) { FileTransfer.FileStreamAssembler oldAssembler = base.MainPacketHandler.FileStreamAssemblerList.GetAssembler(destinationHost, tcpPacket.DestinationPort, sourceHost, tcpPacket.SourcePort, true); base.MainPacketHandler.FileStreamAssemblerList.Remove(oldAssembler, true); } } } return(parsedByteCount); }
//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; * }*/ bool successfulExtraction = false; Packets.HttpPacket httpPacket = null; Packets.TcpPacket tcpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.HttpPacket)) { httpPacket = (Packets.HttpPacket)p; } else if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } } if (httpPacket != null && tcpPacket != null) { if (httpPacket.PacketHeaderIsComplete) { //check if it is a POST and content length is small if (httpPacket.RequestMethod != Packets.HttpPacket.RequestMethods.POST || httpPacket.ContentLength > 4096 /* used to be 1024*/ || httpPacket.ContentIsComplete()) { successfulExtraction = ExtractHttpData(httpPacket, tcpPacket, tcpSession.Flow.FiveTuple, transferIsClientToServer, base.MainPacketHandler); //successfulExtraction=true; } if (base.MainPacketHandler.ExtraHttpPacketHandler != null) { base.MainPacketHandler.ExtraHttpPacketHandler.ExtractHttpData(httpPacket, tcpPacket, tcpSession.Flow.FiveTuple, transferIsClientToServer, base.MainPacketHandler); } } } if (successfulExtraction) { return(httpPacket.PacketLength); //return tcpPacket.PayloadDataLength; } else { return(0); } }
//public bool TryGetOperatingSystems(out IList<string> osList, IEnumerable<Packets.AbstractPacket> packetList) { public bool TryGetOperatingSystems(out IList <DeviceFingerprint> osList, IEnumerable <Packets.AbstractPacket> packetList) { try { //throw new Exception("The method or operation is not implemented."); Packets.TcpPacket tcpPacket = null; Packets.IPv4Packet ipPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } else if (p.GetType() == typeof(Packets.IPv4Packet)) { ipPacket = (Packets.IPv4Packet)p; } } if (tcpPacket != null)//It is OK if the ipPacket is null (which is unlikely) //osList=new List<string>(); { osList = new List <DeviceFingerprint>(); int osListWeight = 3;//in order to avoid getting hits on tests with weight 1 and 2 foreach (TcpFingerprint f in this.fingerprintList) { int w = f.GetHighestMatchWeight(tcpPacket, ipPacket); if (w > osListWeight) { osListWeight = w; osList.Clear(); //osList.Add(f.ToString()); osList.Add(new DeviceFingerprint(f.ToString())); } else if (w == osListWeight) { //osList.Add(f.ToString()); osList.Add(new DeviceFingerprint(f.ToString())); } } if (osList.Count > 0) { //packetList=osList; return(true); } } } catch (Exception e) { System.Diagnostics.Debug.Print(e.ToString()); } osList = null; return(false); }
internal void AddData(Packets.TcpPacket tcpPacket) { if (!this.tcpTransfer) { throw new Exception("No TCP packets accepted, only UDP"); } if (tcpPacket.PayloadDataLength > 0) { AddData(tcpPacket.GetTcpPacketPayloadData(), tcpPacket.SequenceNumber); } }
//returns -1 if there was no match internal int GetHighestMatchWeight(Packets.TcpPacket tcpPacket, Packets.IPv4Packet ipPacket) { int highestWeight = -1; foreach (Test t in testList) { if (t.Weight >= 3 && t.Weight > highestWeight && t.Matches(tcpPacket, ipPacket)) { highestWeight = t.Weight; } } return(highestWeight); }
private byte GetOriginalTimeToLive(Packets.IPv4Packet ipv4Packet, Packets.TcpPacket tcpPacket) { for (int ttlOffset = 0; ttlOffset < maxTtlDistance && ipv4Packet.TimeToLive + ttlOffset <= Byte.MaxValue; ttlOffset++) { if (timeToLiveExists[ipv4Packet.TimeToLive + ttlOffset]) { string[] oss = GetOperatingSystems(ipv4Packet, tcpPacket, (byte)(ipv4Packet.TimeToLive + ttlOffset)); if (oss != null && oss.Length > 0) { return((byte)(ipv4Packet.TimeToLive + ttlOffset)); } } } //if we still havn't found any OS we will have to guess the time to live return(base.GetOriginalTimeToLive(ipv4Packet.TimeToLive));//from the abstract base class }
public bool ContainsFingerprintsForTcpFlags(Packets.TcpPacket tcpPacket) { if (this.tcpFlagsTestLists[tcpPacket.FlagsRaw] == null) { List <Test> list = new List <Test>(); foreach (Test t in this.testList) { if (t.TcpFlagsMatch(tcpPacket)) { list.Add(t); } } this.tcpFlagsTestLists[tcpPacket.FlagsRaw] = list.ToArray(); } return(this.tcpFlagsTestLists[tcpPacket.FlagsRaw].Length > 0); }
//returns -1 if there was no match internal int GetHighestMatchWeight(Packets.TcpPacket tcpPacket, Packets.IPv4Packet ipPacket) { int highestWeight = -1; if (this.ContainsFingerprintsForTcpFlags(tcpPacket)) { var flagsTestList = this.tcpFlagsTestLists[tcpPacket.FlagsRaw]; foreach (Test t in flagsTestList) { if (t.Weight >= 3 && t.Weight > highestWeight && t.Matches(tcpPacket, ipPacket)) { highestWeight = t.Weight; } } } return(highestWeight); }
private string[] GetOperatingSystems(Packets.IPv4Packet ipv4Packet, Packets.TcpPacket tcpPacket, byte originalTimeToLive) { string osFingerprint = GetEttercapOperatingSystemFingerprint(ipv4Packet, tcpPacket, originalTimeToLive); if (osDictionary.ContainsKey(osFingerprint)) { return(osDictionary[osFingerprint].ToArray()); } else if (osDictionary.ContainsKey(osFingerprint.Substring(0, osFingerprint.Length - 3) + ":LT")) { return(osDictionary[osFingerprint.Substring(0, osFingerprint.Length - 3) + ":LT"].ToArray()); } else { return(new string[0]); } }
public bool TryGetOperatingSystems(out IList <DeviceFingerprint> osList, IEnumerable <Packets.AbstractPacket> packetList) { //throw new Exception("The method or operation is not implemented."); Packets.IPv4Packet ipv4Packet = null; Packets.TcpPacket tcpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.IPv4Packet)) { ipv4Packet = (Packets.IPv4Packet)p; } else if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } } if (ipv4Packet != null && tcpPacket != null && tcpPacket.FlagBits.Synchronize) { List <P0fFingerprint> osFingerprintList; if (tcpPacket.FlagBits.Acknowledgement) //ack { osFingerprintList = this.synAckOsFingerprints; } else //syn { osFingerprintList = this.synOsFingerprints; } byte originalTTL = GetOriginalTimeToLive(ipv4Packet, tcpPacket); foreach (P0fFingerprint fingerprint in osFingerprintList) { if (fingerprint.Matches(ipv4Packet, tcpPacket, originalTTL)) { //return the first (and best) match //osList=new List<string>(); osList = new List <DeviceFingerprint>(); osList.Add(new DeviceFingerprint(fingerprint.OS, fingerprint.OsGenre)); //osList.Add(fingerprint.OS); return(true); } } } osList = null; return(false); }
internal bool TcpFlagsMatch(Packets.TcpPacket tcpPacket) { if (tcpPacket.FlagBits.Synchronize != this.tcpflags.Contains('S')) { return(false); } else if (tcpPacket.FlagBits.Acknowledgement != this.tcpflags.Contains('A')) { return(false); } else if (tcpPacket.FlagBits.Fin != this.tcpflags.Contains('F')) { return(false); } else { return(true); } }
public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable <Packets.AbstractPacket> packetList) { bool successfulExtraction = false; Packets.HttpPacket httpPacket = null; Packets.TcpPacket tcpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.HttpPacket)) { httpPacket = (Packets.HttpPacket)p; } else if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } } if (httpPacket != null && tcpPacket != null) { if (httpPacket.PacketHeaderIsComplete) { //check if it is a POST and content length is small if (httpPacket.RequestMethod != Packets.HttpPacket.RequestMethods.POST || httpPacket.ContentLength > 4096 /* used to be 1024*/ || httpPacket.ContentIsComplete()) { successfulExtraction = ExtractHttpData(httpPacket, tcpPacket, sourceHost, destinationHost, base.MainPacketHandler); //successfulExtraction=true; } } } if (successfulExtraction) { return(tcpPacket.PayloadDataLength); } else { return(0); } }
private byte GetOriginalTimeToLive(Packets.IPv4Packet ipv4Packet, Packets.TcpPacket tcpPacket) { for (int ttlOffset = 0; ttlOffset < maxTtlDistance && ipv4Packet.TimeToLive + ttlOffset <= Byte.MaxValue; ttlOffset++) { if (timeToLiveExists[ipv4Packet.TimeToLive + ttlOffset]) { if (ipv4Packet.TimeToLive + ttlOffset == (int)GetOriginalTimeToLive(ipv4Packet.TimeToLive)) { return((byte)(ipv4Packet.TimeToLive + ttlOffset)); } } } for (int ttlOffset = 0; ttlOffset < maxTtlDistance && ipv4Packet.TimeToLive + ttlOffset <= Byte.MaxValue; ttlOffset++) { if (timeToLiveExists[ipv4Packet.TimeToLive + ttlOffset]) { return((byte)(ipv4Packet.TimeToLive + ttlOffset)); } } //if we still havn't found any OS we will have to guess the time to live return(base.GetOriginalTimeToLive(ipv4Packet.TimeToLive));//from base class }
//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; * }*/ bool successfulExtraction = false; Packets.TcpPacket tcpPacket = null; List <Packets.AbstractPacket> packets = new List <Packets.AbstractPacket>(packetList); foreach (Packets.AbstractPacket p in packets) { if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } } //there can be multiple SMB2 commands in the same NetBiosSessionServicePacket foreach (Packets.AbstractPacket p in packets) { if (p.GetType().IsSubclassOf(typeof(Packets.SmbPacket.AbstractSmbCommand))) { ExtractSmbData(tcpSession, transferIsClientToServer, tcpPacket, (Packets.SmbPacket.AbstractSmbCommand)p, base.MainPacketHandler); } } return(0);//NetBiosSessionServicePacketHandler will return the # parsed bytes anyway. }
public int ExtractData(NetworkTcpSession tcpSession, bool transferIsClientToServer, IEnumerable <PacketParser.Packets.AbstractPacket> packetList) { Packets.OscarPacket oscarPacket = null; Packets.TcpPacket tcpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.OscarPacket)) { oscarPacket = (Packets.OscarPacket)p; } else if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } } if (oscarPacket != null && tcpPacket != null) { if (oscarPacket.ImText != null) { 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.OnMessageDetected(new PacketParser.Events.MessageEventArgs(ApplicationLayerProtocol.Oscar, sourceHost, destinationHost, oscarPacket.ParentFrame.FrameNumber, oscarPacket.ParentFrame.Timestamp, oscarPacket.SourceLoginId, oscarPacket.DestinationLoginId, oscarPacket.ImText, oscarPacket.ImText, Encoding.Default, oscarPacket.Attributes, oscarPacket.PacketLength)); } return(oscarPacket.BytesParsed); } return(0); }
private string GetEttercapOperatingSystemFingerprint(Packets.IPv4Packet ipv4Packet, Packets.TcpPacket tcpPacket, byte originalTimeToLive) { if (tcpPacket.OptionList == null || tcpPacket.OptionList.Count == 0) { return(GetEttercapOperatingSystemFingerprint(tcpPacket.WindowSize, null, originalTimeToLive, null, false, false, ipv4Packet.DontFragmentFlag, false, tcpPacket.FlagBits.Synchronize, tcpPacket.FlagBits.Acknowledgement, ipv4Packet.ParentFrame.Data.Length - ipv4Packet.PacketStartIndex)); } else { ushort?maximumSegmentSize = null; byte? windowScaleFactor = null; bool sackPermitted = false; bool noOperation = false; bool timestamp = false; foreach (KeyValuePair <Packets.TcpPacket.OptionKinds, byte[]> optionKeyValue in tcpPacket.OptionList) { if (optionKeyValue.Key.Equals(Packets.TcpPacket.OptionKinds.MaximumSegmentSize)) { if (optionKeyValue.Value != null && optionKeyValue.Value.Length > 1) { maximumSegmentSize = Utils.ByteConverter.ToUInt16(optionKeyValue.Value, 0); } } else if (optionKeyValue.Key.Equals(Packets.TcpPacket.OptionKinds.WindowScaleFactor)) { if (optionKeyValue.Value != null && optionKeyValue.Value.Length > 0) { windowScaleFactor = optionKeyValue.Value[0]; } } else if (optionKeyValue.Key.Equals(Packets.TcpPacket.OptionKinds.SackPermitted)) { sackPermitted = true; } else if (optionKeyValue.Key.Equals(Packets.TcpPacket.OptionKinds.NoOperation)) { noOperation = true; } else if (optionKeyValue.Key.Equals(Packets.TcpPacket.OptionKinds.Timestamp)) { timestamp = true; } } /*if(tcpPacket.OptionList.ContainsKey(NetworkMiner.Packets.TcpPacket.OptionKinds.MaximumSegmentSize)) * maximumSegmentSize=ByteConverter.ToUInt16(tcpPacket.OptionList[NetworkMiner.Packets.TcpPacket.OptionKinds.MaximumSegmentSize], 0); * * if(tcpPacket.OptionList.ContainsKey(NetworkMiner.Packets.TcpPacket.OptionKinds.WindowScaleFactor)) */ return(GetEttercapOperatingSystemFingerprint( tcpPacket.WindowSize, maximumSegmentSize, originalTimeToLive, windowScaleFactor, sackPermitted, //tcpPacket.OptionList.ContainsKey(NetworkMiner.Packets.TcpPacket.OptionKinds.SackPermitted), noOperation, //tcpPacket.OptionList.ContainsKey(NetworkMiner.Packets.TcpPacket.OptionKinds.NoOperation), ipv4Packet.DontFragmentFlag, timestamp, //tcpPacket.OptionList.ContainsKey(NetworkMiner.Packets.TcpPacket.OptionKinds.Timestamp), tcpPacket.FlagBits.Synchronize, tcpPacket.FlagBits.Acknowledgement, ipv4Packet.ParentFrame.Data.Length - ipv4Packet.PacketStartIndex)); } }
//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); }
internal bool Matches(Packets.IPv4Packet ipPacket, Packets.TcpPacket tcpPacket, byte originalTimeToLive) { //window size (can be * or %nnn or Sxx or Txx) //"Snn" (multiple of MSS) and "Tnn" (multiple of MTU) are allowed. if (this.windowSize.StartsWith("S")) { int multipleMSS = Convert.ToInt32(this.windowSize.Substring(1)); int mss = 0; foreach (KeyValuePair <Packets.TcpPacket.OptionKinds, byte[]> keyValuePair in tcpPacket.OptionList) { if (keyValuePair.Key.Equals(Packets.TcpPacket.OptionKinds.MaximumSegmentSize)) { mss = (int)Utils.ByteConverter.ToUInt32(keyValuePair.Value); } } if (tcpPacket.WindowSize != multipleMSS * mss) { return(false); } } else if (this.windowSize.StartsWith("T")) { int multipleMTU = Convert.ToInt32(this.windowSize.Substring(1)); int mtu = 1500; //MTU is defined by Michal Zalewski (p0f author) as MSS+40 however in reality I guess it could be different. //For Ethernet the MTU is 1500 bytes (http://en.wikipedia.org/wiki/MTU_%28networking%29) //It can also be calculated from MSS, depending on the IP and TCP header size. See: http://www.faqs.org/rfcs/rfc879.html for more details foreach (KeyValuePair <Packets.TcpPacket.OptionKinds, byte[]> keyValuePair in tcpPacket.OptionList) { if (keyValuePair.Key.Equals(Packets.TcpPacket.OptionKinds.MaximumSegmentSize)) { mtu = (int)Utils.ByteConverter.ToUInt32(keyValuePair.Value) + 40; } } if (tcpPacket.WindowSize != multipleMTU * mtu) { return(false); } } else if (this.windowSize.StartsWith("%")) { int modulo = Convert.ToInt32(windowSize.Substring(1)); if (tcpPacket.WindowSize % modulo != 0) { return(false); } } else if (this.windowSize.StartsWith("*")) { //do noting } else if (!this.windowSize.Equals(tcpPacket.WindowSize.ToString())) { return(false); } if (originalTimeToLive != this.initialTtl) { return(false); } if (ipPacket.DontFragmentFlag != this.dontFragment) { return(false); } if (!this.overallSynPacketSize.Equals("!") && !this.overallSynPacketSize.Equals(ipPacket.PacketByteCount.ToString())) { return(false); } //options char[] separator = { ',' }; string[] optionValues = this.optionValue.Split(separator); if (optionValues.Length != tcpPacket.OptionList.Count) { return(false); } for (int i = 0; i < optionValues.Length; i++) { //string o in this.optionValue.Split(separator)) {//the options must be in the same order! if (optionValues[i].Equals("N")) //N - NOP option { if (!tcpPacket.OptionList[i].Key.Equals(Packets.TcpPacket.OptionKinds.NoOperation)) { return(false); } } else if (optionValues[i].Equals("E")) //E - EOL option { if (!tcpPacket.OptionList[i].Key.Equals(Packets.TcpPacket.OptionKinds.EndOfOptionList)) { return(false); } } else if (optionValues[i].StartsWith("W")) //Wnnn - window scaling option, value nnn (or * or %nnn) { if (!tcpPacket.OptionList[i].Key.Equals(Packets.TcpPacket.OptionKinds.WindowScaleFactor)) { return(false); } else { int signatureScaleFactor; if (optionValues[i][1] == '%') { int windowScaleFactor = (int)Utils.ByteConverter.ToUInt32(tcpPacket.OptionList[i].Value); int modulo = Convert.ToInt32(optionValues[i].Substring(2)); if (windowScaleFactor % modulo != 0) { return(false); } } else if (optionValues[i][1] == '*') { //do nothing } else if (Int32.TryParse(optionValues[i].Substring(1), out signatureScaleFactor)) { int packetScaleFactor = (int)Utils.ByteConverter.ToUInt32(tcpPacket.OptionList[i].Value); if (signatureScaleFactor != packetScaleFactor) { return(false); } } else { return(false); } } } else if (optionValues[i].StartsWith("M")) //Mnnn - maximum segment size option, value nnn (or * or %nnn) { if (!tcpPacket.OptionList[i].Key.Equals(Packets.TcpPacket.OptionKinds.MaximumSegmentSize)) { return(false); } else { int signatureMSS; if (optionValues[i][1] == '%') { int packetMSS = (int)Utils.ByteConverter.ToUInt32(tcpPacket.OptionList[i].Value); int modulo = Convert.ToInt32(optionValues[i].Substring(2)); if (packetMSS % modulo != 0) { return(false); } } else if (optionValues[i][1] == '*') { //do nothing } else if (Int32.TryParse(optionValues[i].Substring(1), out signatureMSS)) { int packetMSS = (int)Utils.ByteConverter.ToUInt32(tcpPacket.OptionList[i].Value); if (signatureMSS != packetMSS) { return(false); } } else { return(false); } } } else if (optionValues[i].Equals("S")) //S - selective ACK OK { if (!tcpPacket.OptionList[i].Key.Equals(Packets.TcpPacket.OptionKinds.SackPermitted)) { return(false); } } else if (optionValues[i].Equals("K")) //K = SACK. This is a special extension for the Satori TCP database { if (!tcpPacket.OptionList[i].Key.Equals(Packets.TcpPacket.OptionKinds.Sack)) { return(false); } } else if (optionValues[i].Equals("T")) //T - timestamp { if (!tcpPacket.OptionList[i].Key.Equals(Packets.TcpPacket.OptionKinds.Timestamp)) { return(false); } } else if (optionValues[i].Equals("T0")) //T0 - timestamp with zero value { if (!tcpPacket.OptionList[i].Key.Equals(Packets.TcpPacket.OptionKinds.Timestamp)) { return(false); } foreach (byte b in tcpPacket.OptionList[i].Value) { if (b != 0x00) { return(false); } } } else if (optionValues[i].StartsWith("?")) //?n - unrecognized option number n. //i'll skip this one for now... { } } //quirks list... i'll skip it also return(true); }
private void parseMultipart(Mime.MultipartPart multipart, System.Collections.Specialized.NameValueCollection rootAttributes, Packets.TcpPacket tcpPacket, /*NetworkHost sourceHost, NetworkHost destinationHost, */ ref bool messageSentToPacketHandler, Encoding customEncoding, string from = null, string to = null, string subject = null, string messageId = null) { if (multipart.Attributes.Count > 0) { this.MainPacketHandler.OnParametersDetected(new PacketParser.Events.ParametersEventArgs(tcpPacket.ParentFrame.FrameNumber, this.fiveTuple, this.transferIsClientToServer, multipart.Attributes, tcpPacket.ParentFrame.Timestamp, this.protocol + " packet")); } string contentType = multipart.Attributes["Content-Type"]; string charset = multipart.Attributes["charset"]; if (charset != null && charset.Length > 0) { try { customEncoding = System.Text.Encoding.GetEncoding(charset); } catch { }; } bool attachment = false; string contentDisposition = multipart.Attributes["Content-Disposition"]; if (contentDisposition != null && contentDisposition.Contains("attachment")) { attachment = true; } if (contentType != null && ( contentType.Equals("multipart/mixed", StringComparison.InvariantCultureIgnoreCase) || contentType.Equals("multipart/alternative", StringComparison.InvariantCultureIgnoreCase) || contentType.Equals("multipart/related", StringComparison.InvariantCultureIgnoreCase) )) { /** * There are a variety of ways to attach images to an email. * Content types are used to identify what is contained by each part of the email. * As well as the various types of image, and text/plain and text/html for the text and HTML parts, * there are various containers: * multipart/alternative as a container for parts containing the same information in different formats, * multipart/related as a container for parts that are linked in some way, and * multipart/mixed as a general container. **/ //Mime.MultipartPart mimeMultipart = new Mime.MultipartPart(multipart.Data); System.IO.Stream mixedStream = new System.IO.MemoryStream(multipart.Data); Mime.UnbufferedReader mixedReader = new PacketParser.Mime.UnbufferedReader(mixedStream); string boundary = mixedReader.ReadLine(200, customEncoding); if (boundary != null && boundary.Length == 0)//there was an empty line before the boundary, try to read it again { boundary = mixedReader.ReadLine(200, customEncoding); } if (boundary != null && boundary.StartsWith("--")) { boundary = boundary.Substring(2); List <Mime.MultipartPart> innerParts = new List <Mime.MultipartPart>(Mime.PartBuilder.GetParts(mixedReader, boundary, customEncoding)); foreach (Mime.MultipartPart innerPart in innerParts) { //a bit of recursion here this.parseMultipart(innerPart, rootAttributes, tcpPacket, ref messageSentToPacketHandler, customEncoding, from, to, subject, messageId); } } } else if (!attachment && contentType == null || !attachment && contentType != null && (contentType.Equals("text/plain", StringComparison.InvariantCultureIgnoreCase) || !messageSentToPacketHandler && contentType.Equals("text/html", StringComparison.InvariantCultureIgnoreCase))) { //print the data as text //string textData = null; byte[] textDataBytes = null; if (multipart.Attributes["Content-Transfer-Encoding"] == "quoted-printable") { textDataBytes = Utils.ByteConverter.ReadQuotedPrintable(multipart.Data).ToArray(); //textData = Utils.ByteConverter.ReadString(); } else if (multipart.Attributes["Content-Transfer-Encoding"] == "base64") { textDataBytes = System.Convert.FromBase64String(Utils.ByteConverter.ReadString(multipart.Data)); //textData = Utils.ByteConverter.ReadString(); } else { textDataBytes = multipart.Data; //textData = Utils.ByteConverter.ReadString(); } string textData = null; if (customEncoding == null) { textData = Utils.ByteConverter.ReadString(textDataBytes); } else { textData = customEncoding.GetString(textDataBytes); } if (textData != null) { Dictionary <string, string> aggregatedAttributeDictionary = new Dictionary <string, string>(); System.Collections.Specialized.NameValueCollection aggregatedAttributes = new System.Collections.Specialized.NameValueCollection(); aggregatedAttributes.Add(rootAttributes); foreach (string name in rootAttributes.Keys) { aggregatedAttributeDictionary.Add(name, rootAttributes[name]); } foreach (string name in multipart.Attributes) { if (!aggregatedAttributeDictionary.ContainsKey(name)) { aggregatedAttributeDictionary.Add(name, multipart.Attributes[name]); aggregatedAttributes.Add(name, multipart.Attributes[name]); } } if (textData.Length > 0) { if (this.transferIsClientToServer) { this.MainPacketHandler.OnMessageDetected(new PacketParser.Events.MessageEventArgs(this.protocol, this.fiveTuple.ClientHost, this.fiveTuple.ServerHost, tcpPacket.ParentFrame.FrameNumber, tcpPacket.ParentFrame.Timestamp, from, to, subject, textData, customEncoding, aggregatedAttributes)); } else { this.MainPacketHandler.OnMessageDetected(new PacketParser.Events.MessageEventArgs(this.protocol, this.fiveTuple.ServerHost, this.fiveTuple.ClientHost, tcpPacket.ParentFrame.FrameNumber, tcpPacket.ParentFrame.Timestamp, from, to, subject, textData, customEncoding, aggregatedAttributes)); } } messageSentToPacketHandler = true; if (contentType != null && contentType.Equals("text/html", StringComparison.InvariantCultureIgnoreCase)) { //re-parse the multipart so that it is also extracted to an HTML file this.parseMultipart(multipart, rootAttributes, tcpPacket, ref messageSentToPacketHandler, customEncoding, from, to, subject, messageId); } } } else { //store the stuff to disk string filename = multipart.Attributes["name"]; if (filename == null || filename.Length == 0) { filename = multipart.Attributes["filename"]; } if (filename == null || filename.Length == 0) { if (subject != null && subject.Length > 3) { filename = Utils.StringManglerUtil.ConvertToFilename(subject, 10); } else if (messageId != null && messageId.Length > 3) { filename = Utils.StringManglerUtil.ConvertToFilename(messageId, 10); } if (filename == null || filename.Length < 3) { filename = "email_" + (multipart.GetHashCode() % 1000); } string extension = Utils.StringManglerUtil.GetExtension(contentType); if (extension == null || extension.Length < 1) { extension = "dat"; } filename = filename + "." + extension; } List <byte> fileData = new List <byte>(); if (multipart.Attributes["Content-Transfer-Encoding"] == "base64") { //decode base64 stuff int index = 0; while (index < multipart.Data.Length) { string base64 = Utils.ByteConverter.ReadLine(multipart.Data, ref index); if (base64 == null && index < multipart.Data.Length) { //read the remaining data base64 = Utils.ByteConverter.ReadString(multipart.Data, index, multipart.Data.Length - index, false, false); index = multipart.Data.Length; } #if DEBUG if (base64 == null) { System.Diagnostics.Debugger.Break(); } #endif //if (base64 != null && base64.Length > 0) { try { fileData.AddRange(Convert.FromBase64String(base64)); } catch (FormatException e) { } } } else if (multipart.Attributes["Content-Transfer-Encoding"] == "quoted-printable") { //must be decoded according to http://www.ietf.org/rfc/rfc2045.txt fileData = Utils.ByteConverter.ReadQuotedPrintable(multipart.Data); } else { //Add the raw data fileData.AddRange(multipart.Data); } if (fileData != null && fileData.Count > 0) { string fileId = GetFileId(rootAttributes); FileTransfer.FileStreamAssembler assembler = new FileTransfer.FileStreamAssembler(MainPacketHandler.FileStreamAssemblerList, this.fiveTuple, this.transferIsClientToServer, this.fileTransferProtocol, filename, "/", fileData.Count, fileData.Count, "E-mail From: " + from + " To: " + to + " Subject: " + subject, fileId, tcpPacket.ParentFrame.FrameNumber, tcpPacket.ParentFrame.Timestamp, this.fileAssmeblyRootLocation); if (assembler.TryActivate()) { assembler.FileReconstructed += MainPacketHandler.OnMessageAttachmentDetected; assembler.AddData(fileData.ToArray(), tcpPacket.SequenceNumber); //assembler.FinishAssembling(); } else { assembler.Clear(); assembler.FinishAssembling(); } } } }
//public int ExtractData(NetworkTcpSession tcpSession, NetworkHost sourceHost, NetworkHost destinationHost, IEnumerable<PacketParser.Packets.AbstractPacket> packetList) { public int ExtractData(NetworkTcpSession tcpSession, bool transferIsClientToServer, IEnumerable <PacketParser.Packets.AbstractPacket> packetList) { /* * NetworkHost sourceHost, destinationHost; * if (transferIsClientToServer) { * sourceHost = tcpSession.Flow.FiveTuple.ClientHost; * destinationHost = tcpSession.Flow.FiveTuple.ServerHost; * } * else { * sourceHost = tcpSession.Flow.FiveTuple.ServerHost; * destinationHost = tcpSession.Flow.FiveTuple.ClientHost; * }*/ SmtpSession smtpSession; if (this.smtpSessionList.ContainsKey(tcpSession)) { smtpSession = this.smtpSessionList[tcpSession]; } else { smtpSession = new SmtpSession(); this.smtpSessionList.Add(tcpSession, smtpSession); } Packets.TcpPacket tcpPacket = null; Packets.SmtpPacket smtpPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.TcpPacket)) { tcpPacket = (Packets.TcpPacket)p; } else if (p.GetType() == typeof(Packets.SmtpPacket)) { smtpPacket = (Packets.SmtpPacket)p; } } if (smtpPacket != null) { if (smtpPacket.ClientToServer) { if (smtpSession.State == SmtpSession.SmtpState.Username) { string base64Username = smtpPacket.ReadLine().Trim(); try { byte[] usernameBytes = System.Convert.FromBase64String(base64Username); smtpSession.Username = System.Text.ASCIIEncoding.ASCII.GetString(usernameBytes); } catch (FormatException e) { } } else if (smtpSession.State == SmtpSession.SmtpState.Password) { string base64Password = smtpPacket.ReadLine().Trim(); try { byte[] passwordBytes = System.Convert.FromBase64String(base64Password); smtpSession.Password = System.Text.ASCIIEncoding.ASCII.GetString(passwordBytes); } catch (FormatException e) { } } else if (smtpSession.State == SmtpSession.SmtpState.Data) { //write data to file until we receive "\n.\n" could also be \r\n.\r\n smtpSession.AddData(smtpPacket.ParentFrame.Data, smtpPacket.PacketStartIndex, smtpPacket.PacketLength); //check if state has transitioned over to footer if (smtpSession.State == SmtpSession.SmtpState.Footer) { Mime.Email email = new Mime.Email(smtpSession.DataStream, base.MainPacketHandler, tcpPacket, transferIsClientToServer, tcpSession, ApplicationLayerProtocol.Smtp, FileTransfer.FileStreamAssembler.FileAssmeblyRootLocation.destination); } } else { foreach (KeyValuePair <string, string> requestCommandAndArgument in smtpPacket.RequestCommandsAndArguments) { if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.HELO.ToString(), StringComparison.InvariantCultureIgnoreCase)) { string clientDomain = requestCommandAndArgument.Value; } else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.EHLO.ToString(), StringComparison.InvariantCultureIgnoreCase)) { string clientDomain = requestCommandAndArgument.Value; } else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.AUTH.ToString(), StringComparison.InvariantCultureIgnoreCase)) { if (requestCommandAndArgument.Value.Trim().StartsWith("LOGIN", StringComparison.InvariantCultureIgnoreCase)) { //if (requestCommandAndArgument.Value.ToUpper().Contains("LOGIN")) { smtpSession.State = SmtpSession.SmtpState.AuthLogin; //SMTP clients sometimes send the email address right away like this: "AUTH LOGIN aGVqaG9wcEBpbnRlcm5ldC5zZQ==" if (requestCommandAndArgument.Value.Length > "LOGIN ".Length) { try { string base64Username = requestCommandAndArgument.Value.Substring("LOGIN ".Length).Trim(); byte[] usernameBytes = System.Convert.FromBase64String(base64Username); smtpSession.Username = System.Text.ASCIIEncoding.ASCII.GetString(usernameBytes); } catch (ArgumentException) { } } } else if (requestCommandAndArgument.Value.Trim().StartsWith("PLAIN", StringComparison.InvariantCultureIgnoreCase)) { //AUTH PLAIN <base64-encoded username and password> smtpSession.State = SmtpSession.SmtpState.AuthLogin; //SMTP clients sometimes send the email address right away like this: "AUTH LOGIN aGVqaG9wcEBpbnRlcm5ldC5zZQ==" if (requestCommandAndArgument.Value.Length > "PLAIN ".Length) { try { string base64 = requestCommandAndArgument.Value.Substring("PLAIN ".Length).Trim(); NetworkCredential cred = SmtpPacketHandler.ExtractBase64EncodedAuthPlainCredential(base64, smtpPacket.ParentFrame, tcpSession, ApplicationLayerProtocol.Smtp); if (cred != null) { //this.MainPacketHandler.OnCredentialDetected(new Events.CredentialEventArgs(cred)); this.MainPacketHandler.AddCredential(cred); } } catch (ArgumentException) { } } } } else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.MAIL.ToString(), StringComparison.InvariantCultureIgnoreCase)) { if (requestCommandAndArgument.Value.StartsWith("FROM", StringComparison.InvariantCultureIgnoreCase)) { int colonIndex = requestCommandAndArgument.Value.IndexOf(':'); if (colonIndex > 0 && requestCommandAndArgument.Value.Length > colonIndex + 1) { smtpSession.MailFrom = requestCommandAndArgument.Value.Substring(colonIndex + 1).Trim(); } } } else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.RCPT.ToString(), StringComparison.InvariantCultureIgnoreCase)) { if (requestCommandAndArgument.Value.StartsWith("TO", StringComparison.InvariantCultureIgnoreCase)) { int colonIndex = requestCommandAndArgument.Value.IndexOf(':'); if (colonIndex > 0 && requestCommandAndArgument.Value.Length > colonIndex + 1) { smtpSession.AddRecipient(requestCommandAndArgument.Value.Substring(colonIndex + 1).Trim()); } } } else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.DATA.ToString(), StringComparison.InvariantCultureIgnoreCase)) { smtpSession.State = SmtpSession.SmtpState.Data; } else if (requestCommandAndArgument.Key.Equals(SmtpPacket.ClientCommands.STARTTLS.ToString(), StringComparison.InvariantCultureIgnoreCase)) { smtpSession.State = SmtpSession.SmtpState.StartTlsRequested; } } } } else //server to client { foreach (KeyValuePair <int, string> replyCodeAndArgument in smtpPacket.Replies) { if (replyCodeAndArgument.Key == 334) //AUTH LOGIN { if (replyCodeAndArgument.Value.Equals("VXNlcm5hbWU6")) { smtpSession.State = SmtpSession.SmtpState.Username; } else if (replyCodeAndArgument.Value.Equals("UGFzc3dvcmQ6")) { smtpSession.State = SmtpSession.SmtpState.Password; } } else if (replyCodeAndArgument.Key == 235) //AUTHENTICATION SUCCESSFUL { base.MainPacketHandler.AddCredential(new NetworkCredential(tcpSession.ClientHost, tcpSession.ServerHost, smtpPacket.PacketTypeDescription, smtpSession.Username, smtpSession.Password, smtpPacket.ParentFrame.Timestamp)); smtpSession.State = SmtpSession.SmtpState.Authenticated; } else if (replyCodeAndArgument.Key >= 500) //error { smtpSession.State = SmtpSession.SmtpState.None; } else if (replyCodeAndArgument.Key == 354) //DATA "Start mail input; end with <CRLF>.<CRLF>" { smtpSession.State = SmtpSession.SmtpState.Data; } else if (replyCodeAndArgument.Key == 250) //"Requested mail action okay, completed" { if (smtpSession.State == SmtpSession.SmtpState.Footer) { //smtpSession.DataStream.Seek(0, System.IO.SeekOrigin.Begin); smtpSession.DataStream = new System.IO.MemoryStream(); //System.Diagnostics.Debugger.Break(); } smtpSession.State = SmtpSession.SmtpState.None;//Added in order to reset state when multiple SMTP sessions are sent within the same TCP session } else if (replyCodeAndArgument.Key == 220) { if (smtpSession.State == SmtpSession.SmtpState.StartTlsRequested) { tcpSession.ProtocolFinder.SetConfirmedApplicationLayerProtocol(ApplicationLayerProtocol.Ssl, false); } } } } //There was a SMTP packet, so treat this as a sucsessfull extraction return(tcpPacket.PayloadDataLength); } else //smtpPacket == null { return(0); } }
public byte GetTtlDistance(Packets.IPv4Packet ipv4Packet, Packets.TcpPacket tcpPacket) { byte originalTimeToLive = GetOriginalTimeToLive(ipv4Packet, tcpPacket); return((byte)(originalTimeToLive - ipv4Packet.TimeToLive)); }
private int ExtractData(NetworkTcpSession tcpSession, bool transferIsClientToServer, Packets.ModbusTcpPacket modbusPacket) { 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; } foreach (string anomaly in modbusPacket.Anomalies) { base.MainPacketHandler.OnAnomalyDetected(anomaly + " (frame " + modbusPacket.ParentFrame.FrameNumber + ")", modbusPacket.ParentFrame.Timestamp); } System.Collections.Specialized.NameValueCollection parameters = new System.Collections.Specialized.NameValueCollection(); //parameters.Add("Transaction ID", modbusPacket.TransactionID.ToString()); StringBuilder pName = new StringBuilder(); if (modbusPacket.IsResponse) { pName.Append("RSP "); } else { pName.Append("QRY "); } pName.Append("sa:" + modbusPacket.SlaveAddress.ToString().PadRight(4)); pName.Append("fc:" + modbusPacket.FunctionCode.ToString() + " (" + modbusPacket.FunctionCodeName.ToString() + ")"); if (modbusPacket.IsResponse) { if (modbusPacket.ModbusMessage == null) { parameters.Add(pName.ToString(), ""); } else { parameters.Add(pName.ToString(), modbusPacket.ModbusMessage.ToString()); } } else //QUERY { if (modbusPacket.ModbusMessage == null) { parameters.Add(pName.ToString(), "UNKNOWN"); } /*else if (modbusPacket.FunctionCode == (byte)Packets.ModbusTcpPacket.FunctionCodeEnum.WriteSingleCoil) { * Packets.ModbusTcpPacket.WriteSingleCoilQueryOrResponse writeQuery = new Packets.ModbusTcpPacket.WriteSingleCoilQueryOrResponse(modbusPacket.StartingAddress.Value, modbusPacket.NRegistersToRead.Value); * parameters.Add(pName.ToString(), writeQuery.ToString()); * }*/ else { parameters.Add(pName.ToString(), modbusPacket.ModbusMessage.ToString()); } } ushort sourcePort = 0; ushort destinationPort = 0; if (tcpSession.ClientHost.IPAddress.Equals(tcpSession.ServerHost.IPAddress)) { //special case if src IP == dst IP foreach (Packets.AbstractPacket packet in modbusPacket.ParentFrame.PacketList) { if (packet is Packets.TcpPacket) { Packets.TcpPacket tcpPacket = packet as Packets.TcpPacket; sourcePort = tcpPacket.SourcePort; destinationPort = tcpPacket.DestinationPort; } } } else if (tcpSession.ClientHost.IPAddress.Equals(sourceHost.IPAddress)) { sourcePort = tcpSession.ClientTcpPort; destinationPort = tcpSession.ServerTcpPort; } else { sourcePort = tcpSession.ServerTcpPort; destinationPort = tcpSession.ClientTcpPort; } base.MainPacketHandler.OnParametersDetected(new Events.ParametersEventArgs(modbusPacket.ParentFrame.FrameNumber, tcpSession.Flow.FiveTuple, transferIsClientToServer, parameters, modbusPacket.ParentFrame.Timestamp, "Modbus/TCP Transaction ID: " + modbusPacket.TransactionID.ToString())); return(Math.Min(modbusPacket.Length + 6, modbusPacket.PacketLength)); }
public Email(System.IO.MemoryStream emailMimeStream, PacketHandler mainPacketHandler, Packets.TcpPacket tcpPacket, bool transferIsClientToServer, NetworkTcpSession tcpSession, ApplicationLayerProtocol protocol, FileTransfer.FileStreamAssembler.FileAssmeblyRootLocation fileAssmeblyRootLocation = FileTransfer.FileStreamAssembler.FileAssmeblyRootLocation.destination) { Mime.UnbufferedReader ur = new PacketParser.Mime.UnbufferedReader(emailMimeStream); this.MainPacketHandler = mainPacketHandler; this.protocol = protocol; if (this.protocol == ApplicationLayerProtocol.Smtp) { this.fileTransferProtocol = FileTransfer.FileStreamTypes.SMTP; } else if (this.protocol == ApplicationLayerProtocol.Pop3) { this.fileTransferProtocol = FileTransfer.FileStreamTypes.POP3; } else if (this.protocol == ApplicationLayerProtocol.Imap) { this.fileTransferProtocol = FileTransfer.FileStreamTypes.IMAP; } //this.reassembleFileAtSourceHost = reassembleFileAtSourceHost; this.fileAssmeblyRootLocation = fileAssmeblyRootLocation; this.fiveTuple = tcpSession.Flow.FiveTuple; this.transferIsClientToServer = transferIsClientToServer; this.attachments = new List <FileTransfer.ReconstructedFile>(); this.from = null; this.to = null; this.subject = null; this.messageId = null; this.date = null;//Date: Fri, 1 Aug 2003 14:17:51 -0700 Encoding customEncoding = null; System.Collections.Specialized.NameValueCollection rootAttributes = null; bool messageSentToPacketHandler = false; foreach (Mime.MultipartPart multipart in Mime.PartBuilder.GetParts(ur)) //I might need to add "ref customEncoding" as a parameter here { if (rootAttributes == null) { from = multipart.Attributes["From"]; to = multipart.Attributes["To"]; subject = multipart.Attributes["Subject"]; messageId = multipart.Attributes["Message-ID"]; date = multipart.Attributes["Date"]; rootAttributes = multipart.Attributes; } if (multipart.Attributes["charset"] != null) { try { customEncoding = Encoding.GetEncoding(multipart.Attributes["charset"]); } catch { } } this.parseMultipart(multipart, rootAttributes, tcpPacket, ref messageSentToPacketHandler, customEncoding, from, to, subject, messageId); } //create an .eml file with the whole DATA portion string emlFilename = null; if (subject != null && subject.Length > 3) { emlFilename = Utils.StringManglerUtil.ConvertToFilename(subject, 10); /* * try { * System.IO.FileInfo fi = new System.IO.FileInfo(subject.Substring(0, 10)); * emlFilename = subject.Substring(0, 10); * } * catch { * emlFilename = Utils.StringManglerUtil.ConvertToFilename(subject, 10); * } */ } if (emlFilename == null || emlFilename.Length == 0) { if (messageId != null && messageId.Length > 3) { emlFilename = Utils.StringManglerUtil.ConvertToFilename(messageId, 10); } else { emlFilename = "message_" + tcpSession.GetHashCode().ToString("X8"); } } emlFilename = emlFilename + ".eml"; /* * string extendedFileId = tcpSession.GetHashCode().ToString(); * if (messageId != null && messageId.Length > 0) * extendedFileId = messageId; */ if (rootAttributes != null) { string extendedFileId = GetFileId(rootAttributes); using (FileTransfer.FileStreamAssembler assembler = new FileTransfer.FileStreamAssembler(MainPacketHandler.FileStreamAssemblerList, this.fiveTuple, this.transferIsClientToServer, this.fileTransferProtocol, emlFilename, "/", emailMimeStream.Length, emailMimeStream.Length, this.protocol.ToString() + " transcript From: " + from + " To: " + to + " Subject: " + subject, extendedFileId, tcpPacket.ParentFrame.FrameNumber, tcpPacket.ParentFrame.Timestamp, this.fileAssmeblyRootLocation)) { if (assembler.TryActivate()) { assembler.FileReconstructed += MainPacketHandler.OnMessageAttachmentDetected; assembler.FileReconstructed += Assembler_FileReconstructed; assembler.AddData(emailMimeStream.ToArray(), tcpPacket.SequenceNumber); //assembler.FinishAssembling(); } else { assembler.Clear(); assembler.FinishAssembling(); } } } }
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); * } * */ } } } }