static void ParseErrorResponseUDP(KerberosData KerbData, TDSReader ByteReader) { int TagID = 0, TagLen = 0; do { TagID = ByteReader.ReadByte() & (int)0x1F; TagLen = ReadAsnLen(ByteReader, false); switch (TagID) { case 4: //skip Tag4->Stime, case 5: //skip Tag5->SuSec { ByteReader.ReadBytes(TagLen); break; } case 6: { ReadAsnLen(ByteReader); KerbData.errorCode = ByteReader.ReadByte(); KerbData.ErrorDesc = GetErrorDesc((ErrorCodes)KerbData.errorCode); return; } default: { //throw new Exception("Unexpected Tag " + TagID + " found in KERB UDP error response"); break; } } }while (TagID < 6); //Total 12 tags expected, but we are reading only 6 tags until error code }
//Parse User name and domain name //check are they both 0 length? if yes, set a flag in conversation data that indicates null credentials public static bool AreTheCredentialsNull(FrameData fd) { if (fd.payload == null) { return(false); } // does not matter if the frame is fragmented. What we want - the length fields - are right near the beginning of the payload - just 36 bytes into it TDSReader ByteReader = new TDSReader(fd.payload, 0, -1, fd.payloadLength); ByteReader.ReadBytes(8); // TDS header ByteReader.ReadBytes(8); // Skip NTLMSSP string. ByteReader.ReadBytes(4); // Skip Message type ByteReader.ReadBytes(8); // Skip LmChallengeResponseFields - 8 bytes expected ByteReader.ReadBytes(8); // Skip NtChallengeResponseFields - 8 bytes expected short DomainNameLen = ByteReader.ReadInt16(); // Read DomainNameFields->Length - 2 bytes ByteReader.ReadBytes(2); // Skip DomainNameFields->MaximumLength - 2 bytes - to be ignored per the spec int DomainNameOffSet = ByteReader.ReadInt32(); // Read DomainNameFields->BufferOffset - 4 bytes short UserNameLen = ByteReader.ReadInt16(); // Read UserNameFields-Length ByteReader.ReadBytes(2); // Skip UserNameFields-MaximumLength - 2 bytes - to be ignored per the spec int UserNameOffSet = (int)ByteReader.ReadInt16(); // Read UserNameFields-BufferOffset if (UserNameLen > 0 && DomainNameLen > 0) { return(false); } return(true); // user name or domain name are null }
static void ParseErrorResponseTCP(KerberosData KerbData, TDSReader ByteReader) { //Tag4-TagC int TagID = 0, TagLen = 0; do { TagID = ByteReader.ReadByte(); TagLen = ReadAsnLen(ByteReader, false); TagID = (TagID & (int)0x1F); switch (TagID) { case 4: case 5: case 9: case 10: case 12: { ByteReader.ReadBytes(TagLen); // Skip 'STime', 'SuSec', 'Realm' break; } case 6: { ReadAsnLen(ByteReader); KerbData.errorCode = ByteReader.ReadByte(); KerbData.ErrorDesc = GetErrorDesc((ErrorCodes)KerbData.errorCode); return; } default: { break; //return; //throw new Exception("Unexpected Tag" + TagID + " found in KERB TCP response"); } } }while (TagID < 6); //Total 12 tags expected, but we are reading only 6 tags until error code }
public static KerberosData ProcessUDP(ConversationData c) { KerberosData KerbData = new KerberosData(); KerbData.SourcePort = c.sourcePort; KerbData.convData = c; int Len2 = 0; int TagLen = 0; string SPN = null; int TagID = 0; bool IsContinueToNextFrame = false; foreach (FrameData fd in c.frames) { if (fd.payloadLength <= 1) { continue; } TDSReader ByteReader = new TDSReader(fd.payload, 0, -1, fd.payloadLength); //Skip over 4 bytes 'ApplicationTag' ReadAsnLen(ByteReader); //Skip over 4 bytes 'KdcReq->SequenceHeader' ReadAsnLen(ByteReader); //Init vars after every frame processing Len2 = 0; TagLen = 0; SPN = null; TagID = 0; do { TagID = ByteReader.ReadByte(); TagLen = ReadAsnLen(ByteReader, false); TagID = TagID & 0x1F; switch (TagID) //Lower 5 bits { case 0: // version# in Tag 0 for KRB_TGS_REP (response) case 1: case 2: { if ((fd.isFromClient && TagID == 1) || (!fd.isFromClient && TagID == 0)) { GetVersion(KerbData, ByteReader); } else if ((!fd.isFromClient && TagID == 1) || (fd.isFromClient && TagID == 2)) { MessageTypes MsgType = GetMessageType(KerbData, ByteReader); KerbData.frameNo = fd.frameNo; if (MsgType == MessageTypes.KRB_TGS_REP) { //ParseNonErrorResponseUDP(KerbData, ByteReader); IsContinueToNextFrame = true; } else if (MsgType == MessageTypes.KRB_ERROR) { ParseErrorResponseUDP(KerbData, ByteReader); IsContinueToNextFrame = true; } } break; } case 3: { //ByteReader.ReadByte(); Len2 = ReadAsnLen(ByteReader); ByteReader.ReadBytes(Len2); // skip the padata tag. break; } case 4: { //ByteReader.ReadByte(); //skip sequence header of ReqBody ReadAsnLen(ByteReader); int TagId2 = 0; do { TagId2 = ByteReader.ReadByte(); Len2 = ReadAsnLen(ByteReader, false); TagId2 = TagId2 & 0x1F; switch (TagId2) { case 0: { ByteReader.ReadByte(); int Len3 = ReadAsnLen(ByteReader, false); //Read and skip 'padding' ByteReader.ReadBytes(Len3 - 4); KerbData.IsForwardable = (ByteReader.ReadByte() & 0x40) != 0; //Read remaining three bytes ByteReader.ReadBytes(3); break; } case 1: case 2: case 4: case 5: case 7: case 8: //skip these tags. { ByteReader.ReadBytes(Len2); break; } case 3: { // UDP SName implementation - replacing with TCP implementation // ReadAsnLen(ByteReader); //Skip sequence header of sname // int Len3 = ReadAsnLen(ByteReader); //Skip Tag0 of sname // ByteReader.ReadBytes(Len3); //skip nametype // ReadAsnLen(ByteReader); //Skip Tag1 of sname // Len3 = ReadAsnLen(ByteReader); //Skip sequence header of sname->Tag1 // Len3 = ReadAsnLen(ByteReader); // Read SPN Length - same as the TCP implementation // SPN = ByteReader.ReadAnsiString(Len3); // KerbData.SPNRequested = SPN; // TCP SName implementation ReadAsnLen(ByteReader); //Skip sequence header of sname int Len3 = ReadAsnLen(ByteReader); //Skip Tag0 of sname // // Read the Name Type: // // 2 = NT-SRV-INST - has two Strings: Service and Instance. '/' separater is implied // 10 = NT-ENTERPRISE - has one String // // Throw error on all other values // Len3 = ReadAsnLen(ByteReader); if (Len3 != 1) { throw new Exception("Unexpected length (" + Len3 + ") reading SName Name Type."); } byte NameType = ByteReader.ReadByte(); KerbData.SNameType = NameType; if (NameType != 2 && NameType != 10) { IsContinueToNextFrame = true; break; } ReadAsnLen(ByteReader); //Skip Tag1 of sname Len3 = ReadAsnLen(ByteReader); //Skip sequenceheader of sname. SPN = ""; if (NameType == 2) // read service type { Len3 = ReadAsnLen(ByteReader); SPN = ByteReader.ReadAnsiString(Len3) + "/"; } Len3 = ReadAsnLen(ByteReader); // read SPN length SPN += ByteReader.ReadAnsiString(Len3); KerbData.SPNRequested = SPN; break; } default: { throw new Exception("Unknonw tag in kerberos packet"); } } } while (TagId2 < 3); break; } default: { // throw new Exception("Un expected tags in kerberos request/response/ problem in parseing"); break; } } }while ((TagID < 4) && (!IsContinueToNextFrame)); } return(KerbData); }
public void Read(TDSReader r) { byte TDSVer = (byte)(r.TDSVersion & 0x000000FF); UserType = (TDSVer < 0x72) ? r.ReadUInt16() : r.ReadUInt32(); Flags = r.ReadUInt16(); Type = (TDSTokenColumnType)(r.ReadByte()); switch (Type) { // // no need to read anything else for fixed-length types // case TDSTokenColumnType.Null: case TDSTokenColumnType.TinyInt: case TDSTokenColumnType.Bit: case TDSTokenColumnType.SmallInt: case TDSTokenColumnType.Int: case TDSTokenColumnType.SmallDateTime: case TDSTokenColumnType.Real: case TDSTokenColumnType.Money: case TDSTokenColumnType.DateTime: case TDSTokenColumnType.Float: case TDSTokenColumnType.SmallMoney: case TDSTokenColumnType.BigInt: { break; } // // data types that have a 1 byte length // case TDSTokenColumnType.GUID: case TDSTokenColumnType.VarBinary: case TDSTokenColumnType.IntN: case TDSTokenColumnType.VarChar: case TDSTokenColumnType.DateN: // question about this type case TDSTokenColumnType.Binary: case TDSTokenColumnType.Char: case TDSTokenColumnType.BitN: case TDSTokenColumnType.FloatN: case TDSTokenColumnType.MoneyN: case TDSTokenColumnType.DateTimeN: { Length = r.ReadByte(); break; } // // data types that have a 1 byte length and 1 byte scale // case TDSTokenColumnType.TimeN: case TDSTokenColumnType.DateTime2N: case TDSTokenColumnType.DateTimeOffsetN: { Length = r.ReadByte(); Scale = r.ReadByte(); break; } // // data types that have a 1 byte length, 1 byte precision, and 1 byte scale // case TDSTokenColumnType.Decimal: case TDSTokenColumnType.Numeric: case TDSTokenColumnType.DecimalN: case TDSTokenColumnType.NumericN: { Length = r.ReadByte(); Precision = r.ReadByte(); Scale = r.ReadByte(); break; } // // data types that have a 2 byte length // case TDSTokenColumnType.LongVarBinary: case TDSTokenColumnType.LongBinary: { Length = r.ReadUInt16(); break; } // // data types that have a 2 byte length and an optional 5-byte collation // case TDSTokenColumnType.LongVarChar: case TDSTokenColumnType.LongChar: case TDSTokenColumnType.NVarChar: case TDSTokenColumnType.NChar: { Length = r.ReadUInt16(); if (TDSVer >= 0x71) { Collation = r.ReadBytes(5); } break; } // // data types that have a 4 byte length // case TDSTokenColumnType.Image: case TDSTokenColumnType.Variant: case TDSTokenColumnType.NText: { Length = r.ReadUInt32(); break; } // // data types that have a 4 byte length and an optional 5-byte collation // case TDSTokenColumnType.Text: { Length = r.ReadUInt32(); if (TDSVer >= 0x71) { Collation = r.ReadBytes(5); } break; } // // CLR User-Defined Type // case TDSTokenColumnType.UDT: { Length = r.ReadUInt16(); DBName = r.ReadUnicodeString1(); SchemaName = r.ReadUnicodeString1(); TypeName = r.ReadUnicodeString1(); AssemblyName = r.ReadUnicodeString2(); // can be longer than 255 characters break; } // // XML // case TDSTokenColumnType.XML: { XmlSchemaPresent = r.ReadByte(); if (XmlSchemaPresent == 1) { DBName = r.ReadUnicodeString1(); SchemaName = r.ReadUnicodeString1(); SchemaCollection = r.ReadUnicodeString2(); // can be longer than 255 characters } break; } default: { throw new InvalidTDSException("Unknown TDS data type: " + (byte)(Type) + "."); } } ColumnName = r.ReadUnicodeString1(); }
byte[] Nonce = null; // 32 bytes of data if FedAuth is non-zero public void Read(TDSReader r) { byte OptionToken = 0;; int DataOffset; int DataLength; TDSReader offsetReader = null; OptionToken = r.ReadByte(); while (OptionToken != (byte)TDSTokenType.DONEINPROC) // 255 or 0xFF { DataOffset = r.ReadBigEndianUInt16(); DataLength = r.ReadBigEndianUInt16(); offsetReader = r.OffsetReader(DataOffset); switch (OptionToken) { case 0: // version { if (DataLength > 0) { Version = offsetReader.ReadUInt32(); SubBuild = offsetReader.ReadUInt16(); } break; } case 1: // encryption { if (DataLength > 0) { Encryption = offsetReader.ReadByte(); } if (Encryption > 3) { throw new InvalidTDSException("Invalid encryption option: " + Encryption); } break; } case 2: // instanceValidity validity { if (DataLength > 0) { InstanceValidity = offsetReader.ReadByte(); } break; } case 3: // thread ID { if (DataLength > 0) { ThreadID = offsetReader.ReadUInt32(); } break; } case 4: // MARS { if (DataLength > 0) { MarsData = offsetReader.ReadByte(); } if (MarsData > 1) { throw new InvalidTDSException("Invalid MARS option: " + MarsData); } break; } case 5: // Trace ID { if (DataLength > 0) { TraceID = new Guid(offsetReader.ReadBytes(16)); } break; } case 6: // Federated Auth Required { if (DataLength > 0) { FedAuth = offsetReader.ReadByte(); } break; } case 7: // NONCE Option - 32 bytes of encrypted data { if (DataLength > 0) { Nonce = offsetReader.ReadBytes(32); } break; } } } r.DoneWithChildReaders(); // updates parent reader offset with child reader high offset - i.e. causes the parent to jump past the referenced data }
public void Read(TDSReader r) { ActivityID = r.ReadBytes(20); }