当数据库密码忘记时,可使用下面的代码进行暴力破解:
#include "windows.h"
#include "stdio.h"
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#define MAXBUFLEN 512
#define LOGIN_TIMEOUT 30
typedef struct _enum_pwd{
char wordbook[128];
char pwdstr[128];
int booklen;
int pwdlen;
long utype;
#define PWD_NUMBER 1
#define PWD_CHAR_UPPER 2
#define PWD_CHAR_LOWER 4
#define PWD_SYMB0L 8
int offset;
}ENUMPWD, * PENUMPWD;
PENUMPWD enum_pwd_init(long utype,int pwdlen)
{
char temp[128];
int i;
PENUMPWD epwd = (PENUMPWD)malloc(sizeof(ENUMPWD));
memset(epwd, 0 , sizeof(ENUMPWD));
epwd->pwdlen = pwdlen;
epwd->utype = utype;
if(PWD_NUMBER & utype)
{
i = 0;
for(char c = '0'; '9' >= c ; c++)
{
temp[i++] = c;
}
temp[i] = '\0';
strcat_s(epwd->wordbook, temp);
}
if(PWD_CHAR_LOWER & utype)
{
i = 0;
for(char c = 'a'; 'z' >= c ; c++)
{
temp[i++] = c;
}
temp[i] = '\0';
strcat_s(epwd->wordbook, temp);
}
if(PWD_CHAR_UPPER & utype)
{
i = 0;
for(char c = 'A'; 'Z' >= c ; c++)
{
temp[i++] = c;
}
temp[i] = '\0';
strcat_s(epwd->wordbook, temp);
}
if(PWD_SYMB0L & utype)
{
i = 0;
for(char c = '!'; '/' >= c ; c++)
{
temp[i++] = c;
}
temp[i] = '\0';
strcat_s(epwd->wordbook, temp);
i = 0;
for(char c = ':'; '@' >= c ; c++)
{
temp[i++] = c;
}
temp[i] = '\0';
strcat_s(epwd->wordbook, temp);
i = 0;
for(char c = '['; '`' >= c ; c++)
{
temp[i++] = c;
}
temp[i] = '\0';
strcat_s(epwd->wordbook, temp);
i = 0;
for(char c = '{'; '~' >= c ; c++)
{
temp[i++] = c;
}
temp[i] = '\0';
strcat_s(epwd->wordbook, temp);
}
epwd->booklen = strlen(epwd->wordbook);
return epwd;
}
void sub_script_index(ENUMPWD * epwd, int index)
{
int i=0;
while(epwd->wordbook[i++] != epwd->pwdstr[index])
{
}
epwd->pwdstr[index] = epwd->wordbook[i];
}
const char * enum_next_pwd(ENUMPWD * epwd)
{
int i;
char last = epwd->wordbook[epwd->booklen-1];
if(epwd->pwdstr[0] == 0)
{
for(i=0; epwd->pwdlen >i; i++)
{
epwd->pwdstr[i] = epwd->wordbook[0];
}
epwd->offset = 1;
return epwd->pwdstr;
}
int index = epwd->pwdlen;
while(epwd->pwdstr[index-1] == last)
{
index--;
}
//如果已经轮询到最大的字符串,返回失败
if(epwd->pwdstr == &epwd->pwdstr[index])
{
//密码轮询完毕
return NULL;
}
else if(index == epwd->pwdlen)
{
//这种情况是因为最后一个字符还可以继续递增
if(epwd->offset == epwd->booklen)
{
epwd->offset=0;
}
epwd->pwdstr[index-1] = epwd->wordbook[epwd->offset++];
}
else
{
//后面index这几位已经是最大字符,将其重新编排,并将index-1递增一位
sub_script_index(epwd, index-1);
while(epwd->pwdlen > index)
{
epwd->pwdstr[index++] = epwd->wordbook[0];
}
epwd->offset=1;
}
return epwd->pwdstr;
}
void enum_pwd_destory(ENUMPWD * epwd )
{
free(epwd);
}
int main()
{
const char *str;
char ConnStrIn[MAXBUFLEN];
char *text;
SQLCHAR ConnStrOut[MAXBUFLEN];
ENUMPWD * epwd = NULL;
SQLHENV henv = NULL;
SQLHDBC hdbc = NULL;
SQLHSTMT hstmt = NULL;
SQLRETURN result;
SQLINTEGER cbsatid;
epwd = enum_pwd_init(1,6);
result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);//环境句柄
result = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);//句柄属性
result = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);//
result = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (void*) LOGIN_TIMEOUT, 0);
while(str = enum_next_pwd(epwd))
//while(k--)
{
wsprintf(ConnStrIn,"Driver={sql server};server=127.0.0.1,1433;database=master;uid=sa;pwd=%s;",str);
result = SQLDriverConnect(hdbc, NULL,(SQLCHAR*) ConnStrIn, SQL_NTS, ConnStrOut, MAXBUFLEN, (SQLSMALLINT *)0, SQL_DRIVER_NOPROMPT);
if(SQL_ERROR == result)
{
printf("密码:%s\t连接失败\n",str);
}
else
{
printf("密码:%s\t连接成功\n",str);
break;
}
}
end:
getchar();
enum_pwd_destory(epwd);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}