|
SSL Key Password Retrieval Tool |
|
|
|
Details Administrators can now retrieve that password that IIS 4.0 requires you to use to create a certificate signing request, and then later to install the certificate. Not only is this password pointless, but it is stored in plain text in the IIS 4.0 metabase. The program will display the key common name and password tab delimited to STDOUT. Tool source code: /* SSL Key Password Retrieval Tool Extract the passwords used to generate SSL Keys for IIS 4.0. Author: Casey Zacek Date: 01-09-02 Version: 1.0 Documentation/Instigator: Floyd Russell Contact:
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
Copyright 2002 Floyd Russell. All rights reserved. It may be used and modified freely, but I do request that this copyright notice remain attached to the file. You may modify this program as you wish, but if you redistribute a modified version, please attach a note listing the modifications you have made. And if it breaks anything you can't sue me. The most recent version and complete docs are available at: http://www.floydsoft.com */ #define UNICODE #define INITGUID #include <windows.h> #include <wchar.h> #include <objbase.h> #include <ks.h> #include <stdio.h> #include <iadmw.h> // COM Interface header file. #include <iiscnfg.h> // MD_ & IIS_MD_ #defines header file. #include <atlBase.h> // ATL support header file. #define ORIGINAL_BUFFER_SIZE 65536 #define HTAB_SIZE 517 typedef struct htab_elt { WCHAR *name; // SSL Key Name char *pass; // SSL Key Password struct htab_elt *next; // Pointer to next struct } HTAB_ELT; struct htab_elt *htab[HTAB_SIZE]; // Hash Key Names int hash( WCHAR *key ) { int res = 0; while( *key ) { res += *key++; } res %= HTAB_SIZE; return res; } // Store Key Name/Password pair in hash table void store( WCHAR *key, char *data ) { struct htab_elt *e; int h = hash( key ); if( htab[h] == NULL ) { htab[h] = e = (struct htab_elt *)malloc( sizeof(struct htab_elt) ); } else { e = htab[h]; while( 1 ) { // Prevent storing a key multiple times (if it has multiple bindings) if( wcscmp( e->name, key ) == 0 ) { return; } if( e->next == NULL ) { break; } else { e = e->next; } } e->next = (struct htab_elt *)malloc( sizeof(struct htab_elt) ); e = e->next; } int len = wcslen( key ); e->name = (WCHAR *)malloc( (len+1) * sizeof(WCHAR) ); wcscpy( e->name, (const WCHAR *)key ); len = strlen(data); e->pass = (char *)malloc( (len+1) * sizeof(char) ); strcpy( e->pass, (const char *)data ); e->next = NULL; } // Initialize hash table void init_htab() { int i; for( i = HTAB_SIZE; i--; ) { htab[i] = NULL; } } void main() { HRESULT hr = 0; HRESULT hr2 = 0; DWORD i = 0; METADATA_HANDLE hand; METADATA_HANDLE hand2; WCHAR SubKeyName[METADATA_MAX_NAME_LEN]; WCHAR *tmp_n = NULL; char *tmp_p = NULL; struct htab_elt *e; CComPtr <IMSAdminBase> pIMeta; init_htab(); CoInitialize( NULL ); hr = CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, (void **) &pIMeta); if( FAILED(hr) ) { printf( "hr = CoCreateInstance() FAILED! (hr = 0x%x)\n", hr ); return; } // Get a handle to the local machine metabase. hr = pIMeta->OpenKey( METADATA_MASTER_ROOT_HANDLE, TEXT("/LM"), METADATA_PERMISSION_READ, 20, &hand ); // Loop until there are no more subkeys. while( SUCCEEDED(hr) ) { // Enumerate the subkeys of the w3svc. hr = pIMeta->EnumKeys( hand, TEXT("/W3SVC/SSLKeys"), SubKeyName, i ); if( SUCCEEDED(hr) ) { DWORD j = 0; WCHAR tmp[METADATA_MAX_NAME_LEN]; METADATA_RECORD rec; DWORD buflen = ORIGINAL_BUFFER_SIZE; PBYTE buf = new BYTE[buflen]; buflen = 0; // 5500 = certificate // 5501 = private key // 5502 = password // 5503 = request // 5504 = key name // 5505 = expiration date? wsprintf( tmp, L"%s/%s", TEXT("/W3SVC/SSLKeys"), SubKeyName ); hr2 = pIMeta->OpenKey( METADATA_MASTER_ROOT_HANDLE, TEXT("/LM"), METADATA_PERMISSION_READ, 20, &hand2 ); if( FAILED(hr2) ) { printf( "OpenKey(/LM/W3SVC/SSLKeys/%s) FAILED! (hr2 = 0x%x)\n", hr2, SubKeyName ); continue; } while( SUCCEEDED(hr2) ) { rec.dwMDAttributes = METADATA_INHERIT; rec.dwMDUserType = IIS_MD_UT_SERVER; rec.dwMDDataType = ALL_METADATA; rec.dwMDDataLen = ORIGINAL_BUFFER_SIZE; rec.pbMDData = buf; hr2 = pIMeta->EnumData( hand2, tmp, &rec, j, &buflen ); if( SUCCEEDED(hr2) ) { DWORD sz = rec.dwMDDataLen; DWORD id = rec.dwMDIdentifier; if( id == 5502 ){ if( tmp_n == NULL ) { int len = strlen( (const char *)rec.pbMDData ); tmp_p = (char *)malloc( (len+1) * sizeof(char) ); strcpy( tmp_p, (const char *)rec.pbMDData ); } else { store( tmp_n, (char *)rec.pbMDData ); free( tmp_n ); tmp_n = NULL; tmp_p = NULL; } } else if( id == 5504 ){ if( tmp_p == NULL ) { int len = wcslen( (const WCHAR *)rec.pbMDData ); tmp_n = (WCHAR *)malloc( (len+1) * sizeof(WCHAR) ); wcscpy( tmp_n, (const WCHAR *)rec.pbMDData ); } else { store( (WCHAR *)rec.pbMDData, tmp_p ); free( tmp_p ); tmp_n = NULL; tmp_p = NULL; } } } j++; } } // Increment the index. i++; } // Release the handle to the local machine metabase. pIMeta->CloseKey( hand ); // Print results as keyname tab password for( i = 0; i < HTAB_SIZE; i++ ) { e = htab[i]; while( e != NULL ) { wprintf( L"%s\t", e->name ); printf( "%s\n", e->pass ); e = e->next; } } fflush(stdout); }
Related Items:
|