spacer.png, 0 kB
spacer.png, 0 kB
Home arrow All Articles arrow Hacking Articles arrow SSL Key Password Retrieval Tool
SSL Key Password Retrieval Tool Print E-mail
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:

 
< Prev   Next >
spacer.png, 0 kB
spacer.png, 0 kB
spacer.png, 0 kB
spacer.png, 0 kB