|
|
//=============================================================================
// 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 <stdio.h>
;// 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); }
|