//============================================================================= // MODULE: Kerbparser.c // // Description: // // Bloodhound Parser DLL for Kerberos Authentication Protocol // // Modification History // // Michael Webb & Kris Frost Date: 06/04/99 //============================================================================= #define MAINPROG #include "kerbparser.h" #include "kerbGlob.h" #include "kdcreq.h" #include "kdcrep.h" #include "krberr.h" #include ;// Need to find out why error is generated without this semicolon //============================================================================= // Forward references. //============================================================================= VOID WINAPIV KerberosFormatSummary(LPPROPERTYINST lpPropertyInst); //============================================================================= // Protocol entry points. //============================================================================= VOID WINAPI KerberosRegister(HPROTOCOL); VOID WINAPI KerberosDeregister(HPROTOCOL); LPBYTE WINAPI KerberosRecognizeFrame(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL, DWORD, LPDWORD, LPHPROTOCOL, PDWORD_PTR); LPBYTE WINAPI KerberosAttachProperties(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL, DWORD, DWORD_PTR); DWORD WINAPI KerberosFormatProperties(HFRAME, LPVOID, LPVOID, DWORD, LPPROPERTYINST); ENTRYPOINTS KerberosEntryPoints = { KerberosRegister, KerberosDeregister, KerberosRecognizeFrame, KerberosAttachProperties, KerberosFormatProperties }; HPROTOCOL hKerberos = NULL; DWORD Attached = 0; PPF_PARSERDLLINFO WINAPI ParserAutoInstallInfo() { PPF_PARSERDLLINFO pParserDllInfo; PPF_PARSERINFO pParserInfo; DWORD NumProtocols, NumHandoffs; PPF_HANDOFFSET pHandoffSet; PPF_HANDOFFENTRY pHandoffEntry; // Base structure ======================================================== // Allocate memory for parser info: NumProtocols = 1; pParserDllInfo = (PPF_PARSERDLLINFO)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( PF_PARSERDLLINFO ) + NumProtocols * sizeof( PF_PARSERINFO) ); if( pParserDllInfo == NULL) { return NULL; } // fill in the parser DLL info pParserDllInfo->nParsers = NumProtocols; // fill in the individual parser infos... // BLRPLATE ============================================================== pParserInfo = &(pParserDllInfo->ParserInfo[0]); sprintf( pParserInfo->szProtocolName, "KERBEROS" ); sprintf( pParserInfo->szComment, "Kerberos Authentication Protocol" ); sprintf( pParserInfo->szHelpFile, ""); // the incoming handoff set ---------------------------------------------- // allocate NumHandoffs = 2; pHandoffSet = (PPF_HANDOFFSET)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( PF_HANDOFFSET ) + NumHandoffs * sizeof( PF_HANDOFFENTRY) ); if( pHandoffSet == NULL ) { // just return early return pParserDllInfo; } // fill in the incoming handoff set pParserInfo->pWhoHandsOffToMe = pHandoffSet; pHandoffSet->nEntries = NumHandoffs; // UDP PORT 88 pHandoffEntry = &(pHandoffSet->Entry[0]); sprintf( pHandoffEntry->szIniFile, "TCPIP.INI" ); sprintf( pHandoffEntry->szIniSection, "UDP_HandoffSet" ); sprintf( pHandoffEntry->szProtocol, "KERBEROS" ); pHandoffEntry->dwHandOffValue = 88; pHandoffEntry->ValueFormatBase = HANDOFF_VALUE_FORMAT_BASE_DECIMAL; // TCP PORT 88 pHandoffEntry = &(pHandoffSet->Entry[1]); sprintf( pHandoffEntry->szIniFile, "TCPIP.INI" ); sprintf( pHandoffEntry->szIniSection, "TCP_HandoffSet" ); sprintf( pHandoffEntry->szProtocol, "KERBEROS" ); pHandoffEntry->dwHandOffValue = 88; pHandoffEntry->ValueFormatBase = HANDOFF_VALUE_FORMAT_BASE_DECIMAL; return pParserDllInfo; } //============================================================================= // FUNCTION: DLLEntry() // // Modification History // // Michael Webb & Kris Frost Date: 06/04/99 //============================================================================= BOOL WINAPI DLLEntry(HANDLE hInstance, ULONG Command, LPVOID Reserved) { //========================================================================= // If we are loading! //========================================================================= if ( Command == DLL_PROCESS_ATTACH ) { if ( Attached++ == 0 ) { hKerberos = CreateProtocol("KERBEROS", &KerberosEntryPoints, ENTRYPOINTS_SIZE); } } //========================================================================= // If we are unloading! //========================================================================= if ( Command == DLL_PROCESS_DETACH ) { if ( --Attached == 0 ) { DestroyProtocol(hKerberos); } } return TRUE; //... Bloodhound parsers ALWAYS return TRUE. } //============================================================================= // FUNCTION: KerberosRegister() // // Modification History // // Michael Webb & Kris Frost Date: 06/04/99 //============================================================================= VOID WINAPI KerberosRegister(HPROTOCOL hKerberosProtocol) { register DWORD i; //========================================================================= // Create the property database. //========================================================================= CreatePropertyDatabase(hKerberosProtocol, nKerberosProperties); for(i = 0; i < nKerberosProperties; ++i) { AddProperty(hKerberosProtocol, &KerberosDatabase[i]); } // Here we are checking to see whether TCP or UDP is being used. hTCP = GetProtocolFromName("TCP"); hUDP = GetProtocolFromName("UDP"); } //============================================================================= // FUNCTION: Deregister() // // Modification History // // Michael Webb & Kris Frost Date: 06/04/99 //============================================================================= VOID WINAPI KerberosDeregister(HPROTOCOL hKerberosProtocol) { DestroyPropertyDatabase(hKerberosProtocol); } //============================================================================= // FUNCTION: KerberosRecognizeFrame() // // Modification History // // Michael Webb & Kris Frost Date: 06/04/99 //============================================================================= LPBYTE WINAPI KerberosRecognizeFrame(HFRAME hFrame, //... frame handle. LPBYTE MacFrame, //... Frame pointer. LPBYTE KerberosFrame, //... Relative pointer. DWORD MacType, //... MAC type. DWORD BytesLeft, //... Bytes left. HPROTOCOL hPreviousProtocol, //... Previous protocol or NULL if none. DWORD nPreviousProtocolOffset, //... Offset of previous protocol. LPDWORD ProtocolStatusCode, //... Pointer to return status code in. LPHPROTOCOL hNextProtocol, //... Next protocol to call (optional). PDWORD_PTR InstData) //... Next protocol instance data. { // ProtoInfo=GetProtocolInfo(hPreviousProtocol); // MessageBox(NULL, _itoa(TestForUDP,test,10),"TestForUDP 1", MB_OK); *ProtocolStatusCode = PROTOCOL_STATUS_CLAIMED; return NULL; } //============================================================================= // FUNCTION: KerberosAttachProperties() // // Modification History // // Michael Webb & Kris Frost Date: 06/04/99 //============================================================================= LPBYTE WINAPI KerberosAttachProperties(HFRAME hFrame, LPBYTE Frame, LPBYTE KerberosFrame, DWORD MacType, DWORD BytesLeft, HPROTOCOL hPreviousProtocol, DWORD nPreviousProtocolOffset, DWORD_PTR InstData) { // Local variable to hold the value of KerberosFrame, depending on whether // the packet is TCP or UDP. LPBYTE pKerberosFrame; /* kf Here checking to see if first two octets of are equal to 00 00 which would be the case should the packet be the first of TCP. */ if(KerberosFrame[0] == 0x00 && KerberosFrame[1] == 0x00) { TempFrame = KerberosFrame+4; pKerberosFrame = TempFrame; } else { TempFrame = KerberosFrame; pKerberosFrame = TempFrame; } // Here we are going to do a check to see if the packet is TCP and // check to see if the first two octets of the packet don't have the // value of 00 00. If not, then we mark the frame as a continuation // packet. Reason for doing this is because, sometimes 0x1F of the // first packet can still match one of the case statements which // erroneously displays a continuation packet. // NOTE: THIS CODE BREAKS ON SOME OF THE OLDER SNIFFS BECAUSE THE 4 // OCTETS WHICH SPECIFY THE ENTIRE PACKET LENGTH WERE SENT IN A TCP // PACKET ALL BY ITSELF. ACCORDING TO DEV, THIS ISN'T EXPECTED BEHAVIOR // IN THE LATER W2K BUILDS. THE 4 LENGTH OCTETS FOR TCP SHOULD ALWAYS BE // PRE-PENDED TO THE FIRST TCP PACKET if( hPreviousProtocol == hTCP && KerberosFrame[0] != 0 && KerberosFrame[1] != 0 ) { // Displaying as a continutation packet AttachPropertyInstance(hFrame, KerberosDatabase[KerberosDefaultlbl].hProperty, BytesLeft, TempFrame, 0, 0, 0); } else { // pKerberosFrame is a local variable and is used // to display TCP data as well. switch (*(pKerberosFrame) & 0x1F) { case ASN1_KRB_AS_REQ: case ASN1_KRB_TGS_REQ: TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft); TempFrame=KdcRequest(hFrame, TempFrame); break; case ASN1_KRB_AS_REP: case ASN1_KRB_TGS_REP: TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft); TempFrame=KdcResponse(hFrame, TempFrame); break; case ASN1_KRB_AP_REQ: TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft); break; case ASN1_KRB_AP_REP: TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft); break; case ASN1_KRB_SAFE: TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft); break; case ASN1_KRB_PRIV: TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft); break; case ASN1_KRB_CRED: TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft); break; case ASN1_KRB_ERROR: TempFrame=EntryFrame(hFrame, TempFrame, BytesLeft); TempFrame=KrbError(hFrame, TempFrame); break; default: AttachPropertyInstance(hFrame, KerberosDatabase[KerberosDefaultlbl].hProperty, BytesLeft, TempFrame, 0, 0, 0); break; } } return (LPBYTE) KerberosFrame + BytesLeft; } //============================================================================== // FUNCTION: KerberosFormatProperties() // // Modification History // // Michael Webb & Kris Frost Date: 06/04/99 //============================================================================== DWORD WINAPI KerberosFormatProperties(HFRAME hFrame, LPBYTE MacFrame, LPBYTE FrameData, DWORD nPropertyInsts, LPPROPERTYINST p) { //========================================================================= // Format each property in the property instance table. // // The property-specific instance data was used to store the address of a // property-specific formatting function so all we do here is call each // function via the instance data pointer. //========================================================================= // kf Doing a check here for TCP packets. If it's the first packet, // we increment FrameData by 4 to get past the length header if(*FrameData == 0x00 && *(FrameData+1) == 0x00) FrameData+=4; while (nPropertyInsts--) { switch (*FrameData & 0x1F) { case ASN1_KRB_AS_REQ: strcpy(MsgType, "KRB_AS_REQ"); break; case ASN1_KRB_AS_REP: strcpy(MsgType, "KRB_AS_REP"); break; case ASN1_KRB_TGS_REQ: strcpy(MsgType, "KRB_TGS_REQ"); break; case ASN1_KRB_TGS_REP: strcpy(MsgType, "KRB_TGS_REP"); break; case ASN1_KRB_AP_REQ: strcpy(MsgType, "KRB_AP_REQ"); break; case ASN1_KRB_AP_REP: strcpy(MsgType, "KRB_AP_REP"); break; case ASN1_KRB_SAFE: strcpy(MsgType, "KRB_SAFE"); break; case ASN1_KRB_PRIV: strcpy(MsgType, "KRB_PRIV"); break; case ASN1_KRB_CRED: strcpy(MsgType, "KRB_CRED"); break; case ASN1_KRB_ERROR: strcpy(MsgType, "KRB_ERROR"); break; default: strcpy(MsgType, "Didn't recognize"); break; } ((FORMAT) p->lpPropertyInfo->InstanceData)(p); p++; } return NMERR_SUCCESS; } LPBYTE EntryFrame(HFRAME hFrame, LPBYTE KerberosFrame, DWORD BytesLeft) { int LenVal = 0; TempFrame=KerberosFrame; AttachPropertyInstance(hFrame, KerberosDatabase[KerberosSummary].hProperty, BytesLeft, TempFrame, 0, 0, 0); AttachPropertyInstance(hFrame, KerberosDatabase[KerberosIDSummary].hProperty, sizeof(BYTE), TempFrame, 0, 1, 0); // Adding Code here to display Summary, thus letting us indent the ASN breakdown of the // Identifier Octets to where the user won't initially see this. AttachPropertyInstance(hFrame, KerberosDatabase[DispSummary].hProperty, 0, TempFrame, 0, 2, 0); // Break down the Identifier Octet for Message Type TempFrame=CalcMsgType(hFrame, TempFrame, 3, KerberosIdentifier); // Display Length Octet TempFrame=CalcLengthSummary(hFrame, TempFrame, 3); // Adjust TempFrame the appropriate # of octets LenVal=CalcLenOctet(TempFrame-1); // This code handles incrementing to the proper octet based // on the number of octets occupied by TempFrame. if(LenVal <= 1) return TempFrame; else return TempFrame+=(LenVal-1); } /************************************************************************************* ** ** ** This function handles: pa-data ::= SEQUENCE{ ** padata-type[1] INTEGER, ** padata-value[2] OCTET STRING ** } ** hFrame = Handle to the frame. ** ** TempFrame = Offset we which we are at in the current packet ** ** OffSet = The indention level to display the data within Netmon ** ** TypeVal = Variable used to identify node from KerberosDatabase[] ** ************************************************************************************/ LPBYTE HandlePaData(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal) { int TempLength; int lValueReqPadata = 0; //Display Padata[?] NEED TO CHANGE THIS FUNCTION TO PASS THE PARAMETERS SO THE FUNCTION // WILL DISPLAY THE PROPER PADATA TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, KdcReqTagID, KdcReqSeq); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); //Display SEQUENCE OF TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5); /* Incrementing TempFrame based on the number of octets taken up by the Length octet */ TempFrame = IncTempFrame(TempFrame); //Display SEQUENCE OF TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Display padata-type[1] TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, PaDataSummary, PaDataSeq); // Display INTEGER value TempFrame =DispPadata(hFrame, TempFrame, OffSet+4, PadataTypeValID); // Display padata-value[2] DispASNTypes(hFrame, TempFrame, OffSet+2, PaDataSummary, PaDataSeq); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, ++TempFrame, OffSet+5); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); //Display OCTET STRING TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+7); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // HERE IT LOOKS AS IF AN AS-REQ, PADATA-VALUE IS FORMATTED AS ENCRYPTEDDATA // AND TGS IS FORMATTED AS AP-REQ. HOWEVER, IF A SMART CARD IS PRESENT, IT IS // FORMATTED AS. // Check to see if formatted as AP-REQ (6E) if(*(TempFrame+1) == 0x6E ) TempFrame = HandleAPReq(hFrame, TempFrame); // If true, handle AP-REQ traffic else if(*(TempFrame+1) == 0x81) {// Here I'm incrementing TempFrame by two to get it to the first // offset making up the Length Octet. TempFrame++; // Here I'm going to label the rest of the data as a Certificate TempLength = CalcMsgLength(TempFrame); AttachPropertyInstance(hFrame, KerberosDatabase[Certificatelbl].hProperty, TempLength, TempFrame, 0, OffSet+4, 0); // Increment TempFrame by the length octet value returned by CalcMsgLength TempFrame+=TempLength; // Pretty sloppy hack here but hoping Dev will supply me doc // of how the certificate is structured in ASN.1. For the time // being, CalcMsgLength doesn't take us to the end of padata and the // start of KDC-Req-Body. With no idea of what the A1 and A2 tags I see // in the smart card sniff. I don't know if it will possibly ever contain // an A4. But at anyrate, I'm going to increase TempFrame by one until // a value of A4 is matched. (This signifies the start of KDC-Req-Body.) while(*TempFrame != 0xA3) { ++TempFrame; } // Once TempFrame is A4, have to decrement TempFrame by one // in order for KDC-Req-Body to start on the correct offset. // Again this whole else statement is a Kludge but not much I can // until I get the ASN.1 layout of Certificates. --TempFrame; } else { //Display SEQUENCE OF TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+7); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); if(*(TempFrame+1) == 0xA0) { // Handle EncryptedData TempFrame = HandleEncryptedData( hFrame, TempFrame, OffSet+2); } // kfrost 11/12 In smart card the value here is 0x80 or 0x81 in as-req & as-rep respectively. // Can not find out or get Dev to produce the appropriate ASN.1 format that is being // followed here. Basically, whatever encoding layout that is being followed, the first // parameter is 06 Object Identifier. The only thing I have found is KERB-ALGORITHM-IDENTIFIER // found in krb5.asn. Until I get some assistance walking through the offsets, I'm going to label // the data as PKCS and increment TempFrame past all of this and start parsing again at KDC-Req-Body else { if(*(TempFrame+1) == 0x80) { // Here I'm incrementing TempFrame by two to get it to the first // offset making up the Length Octet. TempFrame++; // Here I'm going to label the rest of the data as a Certificate TempLength = CalcMsgLength(TempFrame); AttachPropertyInstance(hFrame, KerberosDatabase[Certificatelbl].hProperty, TempLength, TempFrame, 0, OffSet+4, 0); // Increment TempFrame by the length octet value returned by CalcMsgLength TempFrame+=TempLength; // Pretty sloppy hack here but hoping Dev will supply me doc // of how the certificate is structured in ASN.1. For the time // being, CalcMsgLength doesn't take us to the end of padata and the // start of KDC-Req-Body. With no idea of what the A1 and A2 tags I see // in the smart card sniff. I don't know if it will possibly ever contain // an A4. But at anyrate, I'm going to increase TempFrame by one until // a value of A4 is matched. (This signifies the start of KDC-Req-Body.) while(*TempFrame != 0xA4) { ++TempFrame; } // Once TempFrame is A4, have to decrement TempFrame by one // in order for KDC-Req-Body to start on the correct offset. // Again this whole else statement is a Kludge but not much I can // until I get the ASN.1 layout of Certificates. --TempFrame; } } } // Not going to display anymore padata after this point. padata[3] is a // SequenceOf. Any repetition traffic will get highlighted and TempFrame will // be incremented to the appropriate frame which starts req-body[4] while(*(TempFrame+1) == 0x30) { TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+7); // Adjust TempFrame to the appropriate octet TempFrame+=(CalcMsgLength(--TempFrame)+1); } return TempFrame; } LPBYTE HandleEncryptedData(HFRAME hFrame, LPBYTE TempFrame, int OffSet) { int size = 0; int value = 0; // Display Encryption Type TempFrame = DefineEtype(hFrame, TempFrame, OffSet+2, DispSumEtype2, EncryptedDataTag, EncryptedDataTagBitF); // Display Kvno[1] OPTIONAL if(*TempFrame == 0xA1) { // KF LEFT OFF HERE. CLEAN UP CODE TO DISPLAY KVNO CORRECT // Display Universal Class Tag TempFrame = DispASNTypes(hFrame, --TempFrame, OffSet+2, EncryptedDataTag, EncryptedDataTagBitF); // Need to finish handling kvno[1] // Display INTEGER value TempFrame =DispPadata(hFrame, TempFrame, OffSet+4, PadataTypeValID); // The following increments TempFrame by 1 to get to the cipher[2] octet, however // it doesn't take into account if the integer value takes up more than one octet. ++TempFrame; } // Display cipher[2] TempFrame = DispASNTypes(hFrame, --TempFrame, OffSet+2, EncryptedDataTag, EncryptedDataTagBitF); // Determing the size of cipher[2] size = CalcMsgLength(TempFrame); // Determine whether Length Octet is short or long to // use in incrementing TempFrame in return value value = *(TempFrame+1); // Display Length Octet(s) and highlight cipher text TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5); // The following return takes the offset to the end of cipher[2]. If // value is equal to 0x81 then the length octet was short form // else it's long form so add to size to TempFrame. If long from assumming // length octet will be 2. if(value <= 0x81) { return TempFrame+=(size); } else { return TempFrame+=(size+1); } } // This function is used to break down Identifier Octets and display their types LPBYTE CalcMsgType(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal ) { AttachPropertyInstance(hFrame, KerberosDatabase[KerberosClassTag].hProperty, sizeof(BYTE), TempFrame, 0, OffSet, 0); AttachPropertyInstance(hFrame, KerberosDatabase[PCIdentifier].hProperty, sizeof(BYTE), TempFrame, 0, OffSet, 0); AttachPropertyInstance(hFrame, KerberosDatabase[TypeVal].hProperty, sizeof(BYTE), TempFrame, 0, OffSet, 0); return TempFrame; } LPBYTE CalcLengthSummary(HFRAME hFrame, LPBYTE TempFrame, int OffSet) { // Check the first bit of the length octet to see if length is short form (Value 0) // or Long Form (Value is 1) if(*(++TempFrame) & 0x80) { // This code handles long form. Bits 7-1 of this octet give the number of additional // octets associated with this length octet. We need some type of checking after the last // octet in length to determine if the next octet is an Identifier or Contents. // The additional octets specified in bits 7-1 of the first octet give the length. LongSize = *(TempFrame) & 0x7F; // Assign LongSize to the value of bits 7-1 lValueRepMsg = CalcMsgLength(TempFrame-1); AttachPropertyInstance(hFrame, KerberosDatabase[LengthSummary].hProperty, sizeof(BYTE)+LongSize, // This highlights all bits associated with Length TempFrame, 0, OffSet, 0); AttachPropertyInstance(hFrame, KerberosDatabase[LengthFlag].hProperty, // Will display short or Long sizeof(BYTE), TempFrame, 0, OffSet+1, 0); AttachPropertyInstanceEx(hFrame, KerberosDatabase[LengthBits].hProperty, // Shows how many octets used in Length sizeof(BYTE), TempFrame, 1, &LongSize, 0, OffSet+1, 0); if(LongSize > 1) AttachPropertyInstance(hFrame, KerberosDatabase[LongLength1].hProperty, LongSize, TempFrame+=1, 0, OffSet+1, 0); else AttachPropertyInstance(hFrame, KerberosDatabase[LongLength2].hProperty, LongSize, TempFrame+=1, 0, OffSet+1, 0); } else { // Assuming this code is to handle short form. lValueRepMsg = CalcMsgLength(TempFrame-1); AttachPropertyInstance(hFrame, KerberosDatabase[KdcReqSeqLength].hProperty, sizeof(BYTE)+lValueRepMsg, TempFrame, 0, OffSet, 0); } return TempFrame; } LPBYTE DefineValue(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal) { BYTE Size[4]; PBYTE lSize = (PBYTE)&Size; // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+2); // Need to advance TempFrame the proper # of frames. TempFrame = IncTempFrame(TempFrame); // Display Universal Class Tag TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3); // Need to advance TempFrame the proper # of frames. TempFrame = IncTempFrame(TempFrame); // Code below is used to display Integer values if they occupy more than 2 octets if (*(TempFrame) == 3) { memcpy(lSize, TempFrame, 4); *lSize = *lSize & 0xffffff00; // Prints out Value. Need to change the Array to give better description AttachPropertyInstanceEx(hFrame, KerberosDatabase[TypeVal].hProperty, *(TempFrame-1), ++TempFrame, *(TempFrame) == 3 ? 4 : *(TempFrame), lSize, 0, OffSet, 0); } else { // Prints out Value. Need to change the Array to give better description AttachPropertyInstance(hFrame, KerberosDatabase[TypeVal].hProperty, *(TempFrame-1), ++TempFrame, 0, OffSet+1, 0); } // kf 8/16 This wasn't returning to the proper octet in some cases return (TempFrame-1)+*(TempFrame-1); } /* This is spinoff of DefineValue. However, this code has been modified to handle displaying the ASN.1 breakdown of etype[?] */ LPBYTE DefineEtype(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal, DWORD TypeVal2, DWORD TypeVal3) { // Display Universal Class Tag TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, TypeVal2, TypeVal3); // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); while(*(++TempFrame) == 0x02) { --TempFrame; TempFrame = DispSum(hFrame, TempFrame, 0x02, 0x02, OffSet, DispSumEtype2); // Display Unversal Class Tag TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5); // Increment TempFrame according to length octet TempFrame+=CalcMsgLength(--TempFrame); ++TempFrame; // Display First Encryption Type AttachPropertyInstance(hFrame, KerberosDatabase[TypeVal].hProperty, 1, TempFrame, 0, OffSet+4, 0); } return TempFrame; } int CalcMsgLength(LPBYTE TempFrame) { if(*(TempFrame+1) & 0x80) { LongSize = *(TempFrame+1) & 0x7F; if(LongSize > 1) // Here we are or'd the two values of the length octets together // Note this could fail if the Length octet ever took up more than // two octets in defining a length return (*(TempFrame+3)) | (*(TempFrame+2) << 8); else // This is in case the length octet only had one following defining octet return (BYTE) *(TempFrame+2); } else // For a short form Length octet return *(TempFrame+1) & 0x7F; } /*********************************************************************************************************** ** ** This function will break down ASN.1 PrincipalName. ** PrincipalName ::= SEQUENCE{ ** name-type[0] INTEGER, Specifies the type of name that follows. ** Pre-defined values for this field are specified in ** section 7.2. ** ** name-string[1] SEQUENCE OF GeneralString Encodes a sequence of components ** that form a name, each component ** encoded as a GeneralString. Taken ** together, a PrincipalName and a Realm ** form a principal Identifier. ** **************************************************************************************************************/ LPBYTE DefinePrincipalName(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal) { // This functions starts breaking down the A0 octet of a PrincipalName // Print out name-type[0] of PrincipalName TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, KrbPrincipalNamelSet, KrbPrincipalNamelBitF); // Display octets associated with INTEGER TempFrame = DefineValue(hFrame, TempFrame, OffSet+2, KrbPrincNameType); // End code to display name-type[0] of PrincipalName // Print out name-string[1] of PrincipalName TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, KrbPrincipalNamelSet, KrbPrincipalNamelBitF); // Display Length Summary TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+2); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Display SEQUENCE TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag); // Print out Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Checking for GeneralString 0x1B TempRepGString = *(++TempFrame) & 0x1F; while(TempRepGString == 0x1B) { //Display GeneralString TempFrame = DispASNTypes(hFrame, --TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag); // Calculate the size of the Length Octet lValueRepMsg = CalcMsgLength(TempFrame); //Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+4); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); AttachPropertyInstance(hFrame, KerberosDatabase[TypeVal].hProperty, sizeof(BYTE)+(lValueRepMsg - 1), ++TempFrame, 0, OffSet+3, 0); // Assign TempRepGString to value of octet after the string to see if another SEQUENCE OF // GeneralString exists. TempRepGString = *(TempFrame+=lValueRepMsg) & 0x1F; } // End Code to display name-string[1] return TempFrame; } // Function used parse Length octets in PrincipalName int CalcLenOctet(LPBYTE TempFrame) { int size = 0; // If long form, assign size to value of bits 7-1 if(*(TempFrame) & 0x80) size = (*(TempFrame) & 0x7F); else // Short form, only takes one octet size = 1; return size; } /********************************************************************************************** ** ** LPBYTE DispASNTypes(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal, DWORD TypeVal2) ** ** This function is used to break down and display the ASN.1 Universal Tags. ** (Universal Tag Allocations can be found at page 155 in ASN.1 by Douglas Steedman.) ** ** hFrame - Handle to the fram ** TempFrame - Pointer to the current offset in the packet ** Offset - Used for indenting the parser display ** TypeVal - Used to distinguish which node out of the KerberosDatbase to use ** TypeVal2 - Same use as TypeVal ** **********************************************************************************************/ LPBYTE DispASNTypes(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal, DWORD TypeVal2) { // Assign the value of last 5 bits to TempAsnMsg TempAsnMsg = *(++TempFrame) & 0x1F; // Calculates the length octet to see how many octets should be highlighted lValueRepMsg = CalcMsgLength(TempFrame); // Display the Identifier and the appropriate # of octets are highlighted AttachPropertyInstanceEx(hFrame, KerberosDatabase[TypeVal].hProperty, sizeof(WORD) + lValueRepMsg, TempFrame, 1, &TempAsnMsg, 0, OffSet, 0); // Adding Code here to display Summary, thus letting us indent the ASN breakdown of the // Identifier Octets to where the user won't initially see this. AttachPropertyInstance(hFrame, KerberosDatabase[DispSummary].hProperty, 0, TempFrame, 0, OffSet+1, 0); // Break out the identifier octet to ASN.1 format TempFrame=CalcMsgType(hFrame, TempFrame, OffSet+2, TypeVal2); return TempFrame; } LPBYTE DispSeqOctets(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal, DWORD TypeVal2) { // Display SEQUENCE (First frame we handle in this file. TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, TypeVal, TypeVal2); // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3); return TempFrame; } /*********************************************************************************************************** ** ** This function will break down ASN.1 HostAddresses. P39 rfc 1510 ** HostAddresses::= SEQUENCE OF SEQUENCE{ ** addr-type[0] INTEGER, ** address[1] OCTET STRING, ** } ** ** ** ** ** ** **************************************************************************************************************/ LPBYTE DispHostAddresses(HFRAME hFrame, LPBYTE TempFrame, int OffSet) { // Determine the number of octets occupied by the length ocet lValueRepMsg = CalcLenOctet(TempFrame); // Checking for SEQUENCE OF 0x30 TempReq = *(TempFrame+lValueRepMsg); // while loop is calculate SEQUENCE OF SEQUENCE while(TempReq == 0x30) { // Display SEQUENCE Octets TempFrame = DispSeqOctets(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag); // Display addr-type[0] TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, HostAddressesID, HostAddressesBitF); // Calculate the size of the Length Octet lValueRepMsg = CalcMsgLength(TempFrame); // Display INTEGER TempFrame = DefineValue(hFrame, TempFrame, OffSet+4, KdcContentsValue); // Display address[1] TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, HostAddressesID, HostAddressesBitF); // Display String value TempFrame = DefineValue(hFrame, TempFrame, OffSet+4, DispString); TempReq = *(TempFrame+lValueRepMsg); } return TempFrame; } LPBYTE DispSum(HFRAME hFrame, LPBYTE TempFrame, int ClassValue, int ClassValue2, int OffSet, DWORD TypeVal) { /* Working here now to display info name at the top. Will indent everything else 1 to the right. Not sure how well this is going to work since name-string[1] is a SEQUENCE OF. Writing code now to assume there is only going to be one name and display the first one. */ TempFrameReq = (TempFrame+1); TempFrameReq2 = (TempFrame+2); // This while statement increments TempFrameReq until 1B is reached // If 1B is ever used in a length octet or elsewhere this will fail. // Might look at doing a memcopy later on to a global variable // THINK WE CAN USE BERGETSTRING TO DISPLAY FULL SERVER NAME. WE CAN // USE A STRING CONSTANTS WITH TO DISPLAY THE FULL VALUE. // Incrementing TempFrameReq until String is found while(*(TempFrameReq) != ClassValue || *(TempFrameReq2) == ClassValue2) { TempFrameReq++; TempFrameReq2++; // Trying to come up with a way to make sure the Length Value doesn't == ClassValue // Still need some type of checking in case the length octet's value after the SEQUENCE OF // turns out to be equal to ClassValue. if(*(TempFrameReq) == ClassValue && *(TempFrameReq2) == ClassValue2) { TempFrameReq++; TempFrameReq2++; // Checking to see if Length Octet's value after SEQUENCE OF is equal to ClassValue. If so, // incrementing TempFrameReq in order to get to the correct offset. if(*(TempFrameReq) == ClassValue2 && *(TempFrameReq2) == ClassValue) { TempFrameReq++; TempFrameReq2++; } } } if(ClassValue2 == 0x02) {// Put this if statement to handle highlighting the appropriate # of // Octets for EType. Don't know how valid this is going to be but trying // to get all the code in. Will worry about later. // Calculate the value of the length octet lValueReq = CalcMsgLength(TempFrameReq-1); AttachPropertyInstance(hFrame, KerberosDatabase[TypeVal].hProperty, 1, TempFrameReq+=2, 0, OffSet, 0); } else { // Calculate the value of the length octet lValueReq = CalcMsgLength(TempFrameReq); // Increment TempFrameReq to the proper Octet TempFrameReq+=CalcLenOctet(TempFrameReq); AttachPropertyInstance(hFrame, KerberosDatabase[TypeVal].hProperty, sizeof(BYTE)+(lValueReq-1), ++TempFrameReq, 0, OffSet, 0); } return TempFrame; } /**************************************************************************** ** ** ** This function is used to display a top level Summary description ** ** ****************************************************************************/ LPBYTE DispTopSum(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal) { AttachPropertyInstance(hFrame, KerberosDatabase[TypeVal].hProperty, 0, TempFrame, 0, OffSet, 0); return TempFrame; } /********************************************************************************* ** ** Another Subset of DispSum. Altering this function to gather string info ** and reformat to print out in a Date, Time format. ** *********************************************************************************/ LPBYTE DispSumTime(HFRAME hFrame, LPBYTE TempFrame, int ClassValue, int OffSet, DWORD TypeVal) { char RawTimeBuf[16]; char TimeFormatBuf[TIME_FORMAT_SIZE]; LPSTR TimeFormat = TimeFormatBuf; TempFrameReq = (TempFrame+1); TempFrameReq2 = (TempFrame+2); // This while statement increments TempFrameReq until 1B is reached // If 1B is ever used in a length octet or elsewhere this will fail. // Next loop is to find 1B value and is designed to prevent mistakenly // going to the wrong octet in case a 1b is the value in a Length octet // Incrementing TempFrameReq until String is found while(*(TempFrameReq) != ClassValue || *(TempFrameReq2) == 0x30) { TempFrameReq++; TempFrameReq2++; // Trying to come up with a way to make sure the Length Value doesn't == ClassValue // Still need some type of checking in case the length octet's value after the SEQUENCE OF // turns out to be equal to ClassValue. if(*(TempFrameReq) == ClassValue && *(TempFrameReq2) == 0x30) { TempFrameReq++; TempFrameReq2++; // Checking to see if Length Octet's value after SEQUENCE OF is equal to ClassValue. If so, // incrementing TempFrameReq in order to get to the correct offset. if(*(TempFrameReq) == 0x30 && *(TempFrameReq2) == ClassValue) { TempFrameReq++; TempFrameReq2++; } } } // Calculate the value of the length octet lValueReq = CalcMsgLength(TempFrameReq); if( lValueReq > ((sizeof RawTimeBuf) / (sizeof RawTimeBuf[0])) ) { memcpy( RawTimeBuf, (TempFrameReq+2), sizeof RawTimeBuf / sizeof RawTimeBuf[0] ); } else { memcpy(RawTimeBuf, (TempFrameReq+2), lValueReq); } sprintf( TimeFormat, TIME_FORMAT_STRING, RawTimeBuf[4], RawTimeBuf[5], // month RawTimeBuf[6], RawTimeBuf[7], // day RawTimeBuf[0], RawTimeBuf[1], RawTimeBuf[2], RawTimeBuf[3], // year RawTimeBuf[8], RawTimeBuf[9], // hours RawTimeBuf[10], RawTimeBuf[11], // minutes RawTimeBuf[12], RawTimeBuf[13] ); // seconds // Increment TempFrameReq to the proper Octet TempFrameReq+=CalcLenOctet(TempFrameReq); // Display initial Time AttachPropertyInstanceEx( hFrame, KerberosDatabase[TypeVal].hProperty, lValueReq, ++TempFrameReq, TIME_FORMAT_SIZE, TimeFormat, 0, OffSet, 0 ); return TempFrame; } /****************************************************************************** ** ** Created this function to address displaying the FQDN of the server name (under KDC-Options) ** at the top level. ** *******************************************************************************/ LPBYTE DispSumString(HFRAME hFrame, LPBYTE TempFrame, int ClassValue, int OffSet, DWORD TypeVal) { LPBYTE TempFrameSname, TempFrameSnameB; int segments = 0; int j = 0; int ServNameCount = 0; int lValueStr = 0; int sizeAsString = 0; LPSTR cServName = NULL; LPSTR ServNameBuf[MAX_SERVER_NAME_SEGMENTS]; memset( ServNameBuf, 0, sizeof ServNameBuf ); TempFrameSname = (TempFrame+1); TempFrameSnameB = (TempFrame+2); // This while statement increments TempFrameReq until ClassValue is reached // Incrementing TempFrameReq until ClassValue while(*(TempFrameSname) != ClassValue || *(TempFrameSnameB) == 0x30) { TempFrameSname++; TempFrameSnameB++; // Trying to come up with a way to make sure the Length Value doesn't == ClassValue // Still need some type of checking in case the length octet's value after the SEQUENCE OF // turns out to be equal to ClassValue. 11/18. Found a situation where the first part of // of a principal name had the length of 1B. Added the || *(TempFrameSnameB) == 0xA0 to // handle this problem The 0xA0 is the first tag of Principal Name if(*(TempFrameSname) == ClassValue && *(TempFrameSnameB) == 0x30 || *(TempFrameSnameB) == 0xA0) { TempFrameSname++; TempFrameSnameB++; // Checking to see if Length Octet's value after SEQUENCE OF is equal to ClassValue. If so, // incrementing TempFrameReq in order to get to the correct offset. if(*(TempFrameSname) == 0x30 && *(TempFrameSnameB) == ClassValue) { TempFrameSname++; TempFrameSnameB++; } } } TempFrameSnameB = TempFrameSname; while(*(TempFrameSnameB) == ClassValue) { if( segments >= MAX_SERVER_NAME_SEGMENTS ) { break; } lValueStr = CalcMsgLength(TempFrameSnameB); sizeAsString = lValueStr + sizeof '\0'; ServNameCount += lValueStr; ServNameBuf[ segments ] = (LPSTR) malloc( sizeAsString ); if( ServNameBuf[ segments ] == NULL ) { for( ; segments > 0; segments-- ) { free( ServNameBuf[segments - 1] ); } return TempFrame; } ZeroMemory( ServNameBuf[ segments ], sizeAsString ); memcpy( ServNameBuf[ segments ], TempFrameSnameB+2, lValueStr ); // Use the Length Octet to progress TempFrameReq TempFrameSnameB+=CalcMsgLength(TempFrameSnameB); // Need to Increment TempFrameSnameB by number of ASN.1 octets // Increasing by two here. This could be wrong if the Length octet // were ever in Long Form. TempFrameSnameB+=2; segments++; } cServName = (LPSTR) malloc( ServNameCount + segments ); if (NULL == cServName) { for( ; segments > 0; segments-- ) { free( ServNameBuf[segments - 1] ); } return TempFrame; } ZeroMemory(cServName, ServNameCount + segments ); strcpy(cServName, ServNameBuf[0]); for( j = 1; j < segments; j++ ) { strcat(cServName, "/"); strcat(cServName, ServNameBuf[j]); } AttachPropertyInstanceEx(hFrame, KerberosDatabase[TypeVal].hProperty, ServNameCount + 2*segments, TempFrameSname+=2, ServNameCount + segments, cServName, 0, OffSet, 0); for( ; segments > 0; segments-- ) { free( ServNameBuf[segments - 1] ); } if (NULL != cServName) { free(cServName); } return TempFrame; } /********************************************************************************* ** ** ** This function was copied from DefineValue but was created to display the ** Ticket Flags for KDC-Options in the KDC-Req packet. ** *********************************************************************************/ LPBYTE DefineKdcOptions(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal) { AttachPropertyInstance(hFrame, KerberosDatabase[TypeVal].hProperty, sizeof(DWORD), TempFrame, 0, OffSet, 0); return (TempFrame); } /***************************************************************************** * This function is used to display the initial values of padata-type[1] & * padata-value[2] found in the AS-REQ packet * NOTE: I LEFT *INTVAL AND THE OTHER LINES COMMENTED AS FOR IF THE INT VALUE * TAKES UP TWO OCTETS, WE ONLY DISPLAY THE # INSTEAD OF ENCRYPTION TYPE. NOT * WORRYING WITH THIS AT THIS TIME BUT LEAVING THE CODE IN PLACE SHOULD IT NEED * TO BE IMPLEMENTED. *****************************************************************************/ LPBYTE DispPadata(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal) { // Calculate Length Octet and highligh the # of octets // BYTE *intval; int size = 0; // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+1); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Display Universal Class Tag TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3); //Assumming the Integer value will always be contained in // either 1 or 2 octets. size = *TempFrame; // Here need to check the length octet and determine whether // it is short or long form if(size == 1) { // intval = malloc(2); // memcpy(intval, (TempFrame+1), 2); // Prints out Value. Need to change the Array to give better description AttachPropertyInstance(hFrame, KerberosDatabase[TypeVal].hProperty, 1, ++TempFrame, 0, OffSet+1, 0); /* AttachPropertyInstanceEx(hFrame, KerberosDatabase[TypeVal].hProperty, 1, ++TempFrame, 4, intval, 0, OffSet, 0); */ } else { // intval = malloc(4); // memcpy(intval, (TempFrame+1), 4); // *intval = *(intval) & 0xffff; AttachPropertyInstance(hFrame, KerberosDatabase[PaDataSummaryMulti].hProperty, 1, ++TempFrame, 0, OffSet+1, 0); /* // Prints out Value. Need to change the Array to give better description AttachPropertyInstanceEx(hFrame, KerberosDatabase[PaDataSummaryMulti].hProperty, 2, ++TempFrame, 4, intval, 0, OffSet, 0); */ // Incrementing TempFrame by an extra Octet because the Integer here takes // up 2 octets instead of one. ++TempFrame; } return (TempFrame); } LPBYTE IncTempFrame(LPBYTE TempFrame) { if(*(TempFrame-1) >= 0x81 && *(TempFrame-1) <= 0x84) TempFrame+=CalcLenOctet(--TempFrame); else TempFrame; return TempFrame; } LPBYTE HandleTicket(HFRAME hFrame, LPBYTE TempFrame, int OffSet) { // Display Summary ASN.1 TempFrame = DispASNSum(hFrame, TempFrame, OffSet+1, DispSummary); //Display Ticket[3] // Display msg-type[2] TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, KrbApReqID, KrbApReqBitF); // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+4); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Display Ticket (61) TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ApTicketID, ApTicketBitF); // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+4); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Display SEQUENCE TempFrame = DispSeqOctets(hFrame, TempFrame, OffSet+3, ASN1UnivTagSumID, ASN1UnivTag); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Display Ticket Version value at the Top level TempFrame = DispSum(hFrame, TempFrame, 0x02, 0x30, OffSet+2, DispSumTixVer); // Display tvt-vno[0] TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+3, TicketStructID, TicketStructBitF); // Break Down INTEGER values TempFrame = DefineValue(hFrame, TempFrame, OffSet+4, KdcContentsValue); // Display Realm name value at the Top level TempFrame = DispSum(hFrame, TempFrame, 0x1B, 0x30, OffSet+2, DispStringRealmName); // Display realm[1] TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+3, TicketStructID, TicketStructBitF); TempFrame = DefineValue(hFrame, TempFrame, OffSet+5, DispStringRealmName); // Display Server name value at the Top level TempFrame = DispSumString(hFrame, TempFrame, 0x1B, OffSet+2, DispStringServNameGS); // Display sname[2] TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+3, TicketStructID, TicketStructBitF); // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+4); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Display SEQUENCE Octets TempFrame = DispSeqOctets(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag); // Display sname[2] TempFrame = DefinePrincipalName(hFrame, TempFrame, OffSet+3, DispStringServerName); --TempFrame; // Display enc-part[3] TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, TicketStructID, TicketStructBitF); // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+4); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Display SEQUENCE Octets TempFrame = DispSeqOctets(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); //Display EncryptedData TempFrame = HandleEncryptedData(hFrame, TempFrame, OffSet+1); return TempFrame; } LPBYTE DispASNSum(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal) { AttachPropertyInstance(hFrame, KerberosDatabase[TypeVal].hProperty, 0, TempFrame, 0, OffSet, 0); return TempFrame; } /************************************************************************************ ** **This function is a spinoff of DispSum. I created this one separately for the sole **purpose of displaying the full value of susec and cusec at the top levels ** *************************************************************************************/ LPBYTE DispSumSec(HFRAME hFrame, LPBYTE TempFrame, int ClassValue, int ClassValue2, int OffSet, DWORD TypeVal) { /* Working here now to display info name at the top. Will indent everything else 1 to the right. Not sure how well this is going to work since name-string[1] is a SEQUENCE OF. Writing code now to assume there is only going to be one name and display the first one. */ BYTE SizeSec[4]; PBYTE lSizeSec = (PBYTE)&SizeSec; TempFrameReq = (TempFrame+1); TempFrameReq2 = (TempFrame+2); // This while statement increments TempFrameReq until 1B is reached // If 1B is ever used in a length octet or elsewhere this will fail. // Might look at doing a me mcopy later on to a global variable // THINK WE CAN USE BERGETSTRING TO DISPLAY FULL SERVER NAME. WE CAN // USE A STRING CONSTANTS WITH TO DISPLAY THE FULL VALUE. // Incrementing TempFrameReq until String is found while(*(TempFrameReq) != ClassValue || *(TempFrameReq2) == ClassValue2) { TempFrameReq++; TempFrameReq2++; // Trying to come up with a way to make sure the Length Value doesn't == ClassValue // Still need some type of checking in case the length octet's value after the SEQUENCE OF // turns out to be equal to ClassValue. if(*(TempFrameReq) == ClassValue && *(TempFrameReq2) == ClassValue2) { TempFrameReq++; TempFrameReq2++; // Checking to see if Length Octet's value after SEQUENCE OF is equal to ClassValue. If so, // incrementing TempFrameReq in order to get to the correct offset. if(*(TempFrameReq) == ClassValue2 && *(TempFrameReq2) == ClassValue) { TempFrameReq++; TempFrameReq2++; } } } memcpy(lSizeSec, (TempFrameReq2++), 4); *lSizeSec = *(lSizeSec) & 0xffffff00; // Prints out Value. Need to change the Array to give better description AttachPropertyInstanceEx(hFrame, KerberosDatabase[TypeVal].hProperty, 3, TempFrameReq2, 4, lSizeSec, 0, OffSet, 0); return TempFrame; } /******************************************************************************************* * LPBYTE DispEdata(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal) * * This function is a spinoff of DefineValue. Problem is, e-data for Kerb error can be * displayed in two different formats. Even though this does present duplicate code, * it does make it more convenenient and cleaner to have specific functions to handle specific data. * *******************************************************************************************/ LPBYTE DispEdata(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal) { // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+2); // Need to advance TempFrame the proper # of frames. TempFrame = IncTempFrame(TempFrame); // Display Universal Class Tag TempFrame = DispASNTypes(hFrame, TempFrame, OffSet, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+3); // Need to advance TempFrame the proper # of frames. TempFrame = IncTempFrame(TempFrame); // This if statement is checking to see if e-data is a Sequence of PA-DATA's. If so // we send the data to function to handle padata, if not, we display the Octet String. if (*((TempFrame)+1) == 0x30) { // Display padata TempFrame = HandlePadataKrbErr(hFrame, TempFrame, 2, PaDataSummary); // 1/18/00 LEFT OFF HERE. NEED TO DISPLAY E-DATA WHEN IT'S FORMATTED AS PA-DATA. LOOK AT // ADDING THE IF STATEMENT IN HANDLEPADATA AS YOU DID YESTERDAY. } else { AttachPropertyInstance(hFrame, KerberosDatabase[TypeVal].hProperty, *(TempFrame-1), ++TempFrame, 0, OffSet+1, 0); } return (TempFrame-1)+*(TempFrame-1); } /******************************************************************************************* ** LPBYTE HandlePadataKrbErr(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal) ** This function handles the initial display of padata include in Kerb-Error ** *******************************************************************************************/ LPBYTE HandlePadataKrbErr(HFRAME hFrame, LPBYTE TempFrame, int OffSet, DWORD TypeVal) { //Display SEQUENCE OF TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); //Display SEQUENCE OF TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+5); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Display padata-type[1] TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+2, PaDataSummary, PaDataSeq); // Display INTEGER value TempFrame =DispPadata(hFrame, TempFrame, OffSet+4, PadataTypeValID); // Display padata-value[2] DispASNTypes(hFrame, TempFrame, OffSet+2, PaDataSummary, PaDataSeq); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, ++TempFrame, OffSet+5); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); //Display OCTET STRING TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+7); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); //Display SEQUENCE OF TempFrame = DispASNTypes(hFrame, TempFrame, OffSet+4, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, OffSet+7); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Handle MethodData TempFrame = HandleMethodData(hFrame, TempFrame); return(TempFrame); } /****************************************************************************************** ** ** LPBYTE HandleMethodData(HFRAME hFrame, LPBYTE TempFrame) ** ** This function displays METHOD-DATA as described in kerb-error ** ******************************************************************************************/ LPBYTE HandleMethodData(HFRAME hFrame, LPBYTE TempFrame) { int iStringLength = 0; int inc = 0; // METHOD-DATA :: = SEQUENCE of PA-DATA. This is a Sequence of, thus creating a loop to display // all info. Added the inc variable so that the look will only go through twice. In the sniff // I was going by, the 3rd sequence of looked to be formatted in a whole different form than // METHOD-DATA. Even if this is by design, off-hand, I don't see how to code this to break // out a different data format without any type of signifier in the frame. while(*(TempFrame+1) == 0x30 && inc <= 1) { //Display SEQUENCE OF TempFrame = DispASNTypes(hFrame, TempFrame, 6, ASN1UnivTagSumID, ASN1UnivTag); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, 8); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); // Display method-type[0] TempFrame = DispASNTypes(hFrame, TempFrame, 5, MethodDataSummary, MethodDataBitF); // Break Down INTEGER values TempFrame = DefineValue(hFrame, TempFrame, 7, DispSumEtype2); // Display method-data[1] TempFrame = DispASNTypes(hFrame, TempFrame, 5, MethodDataSummary, MethodDataBitF); // Display Length Octet(s) TempFrame = CalcLengthSummary(hFrame, TempFrame, 8); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); //Display OCTET STRING TempFrame = DispASNTypes(hFrame, TempFrame, 7, ASN1UnivTagSumID, ASN1UnivTag); // Calculate the size of the Length Octet iStringLength = CalcMsgLength(TempFrame); //Display Length Octet TempFrame = CalcLengthSummary(hFrame, TempFrame, 10); // Incrementing TempFrame based on the number of octets // taken up by the Length octet TempFrame = IncTempFrame(TempFrame); AttachPropertyInstance(hFrame, KerberosDatabase[DispReqAddInfo].hProperty, sizeof(BYTE)+(iStringLength - 1), ++TempFrame, 0, 9, 0); // Increment TempFrame to the end of the string so we can check for another Sequence TempFrame += (iStringLength - 1); ++inc; } // LEFT OFF HERE 1/19/00 THIS IS A SEQUENCE OF, SO YOU NEED TO INCREMENT TEMPFRAME APPROPRIATELY // AND THEN CHECK FOR 0x30. IF PRESENT, KEEP LOOPING. return(TempFrame); }