演示从注册表中还原MSNMessenger口令
程序员文章站
2022-04-26 19:28:02
/* MSNMessenger的口令是经过DPAPI加密后保存在注册表中的
* 这个程序演示解码过程
* tombkeeper[0x40]nsfocus[0x2e]com
* tombkeeper[0x40]xfocus[0x2e]net
* 2004.... 08-10-08...
/* msnmessenger的口令是经过dpapi加密后保存在注册表中的
* 这个程序演示解码过程
* tombkeeper[0x40]nsfocus[0x2e]com
* tombkeeper[0x40]xfocus[0x2e]net
* 2004.08.11
*/ #include <windows.h> #pragma comment(lib, "advapi32.lib")
#define fchk(a) if (!(a)) {printf(#a " failed\n"); return 0;}
typedef struct _cryptoapi_blob {
dword cbdata;
byte* pbdata;
} data_blob;
typedef struct _cryptprotect_promptstruct {
dword cbsize;
dword dwpromptflags;
hwnd hwndapp;
lpcwstr szprompt;
} cryptprotect_promptstruct, *pcryptprotect_promptstruct;
typedef bool (winapi *pcryptunprotectdata)(
data_blob* pdatain,
lpwstr* ppszdatadescr,
data_blob* poptionalentropy,
pvoid pvreserved,
cryptprotect_promptstruct* ppromptstruct,
dword dwflags,
data_blob* pdataout
);
pcryptunprotectdata cryptunprotectdata = null; int main(void)
{
int ret;
hmodule hntdll;
hkey hkey;
dword dwtype;
char data[0x100] = {0};
dword dwsize;
data_blob datain;
data_blob dataout;
ret = regopenkeyex
(
hkey_current_user,
"software\\microsoft\\msnmessenger",
0,
key_read,
&hkey
);
if( ret != error_success ) return 1;
ret = regqueryvalueex
(
hkey,
"password.net messenger service",
null,
&dwtype,
data,
&dwsize
);
if( ret != error_success ) return 1;
fchk ((hntdll = loadlibrary ("crypt32.dll")) != null);
fchk ((cryptunprotectdata = (pcryptunprotectdata)
getprocaddress (hntdll, "cryptunprotectdata")) != null);
datain.pbdata = data 2; //口令密文从第二位开始
datain.cbdata = dwsize-2;
cryptunprotectdata
(
&datain,
null,
null,
null,
null,
1,
&dataout
);
base64_decode (dataout.pbdata, data, strlen(dataout.pbdata));
printf ( "msn password: %s\n", data);
return 0;
}
//copied from gnu libc - libc/resolv/base64.c
int base64_decode (char const *src, char *target, size_t targsize)
{
static const char base64[] =
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789 /";
static const char pad64 = ’=’;
int tarindex, state, ch;
char *pos;
state = 0;
tarindex = 0;
while ((ch = *src ) != ’\0’)
{
if (isspace (ch)) /* skip whitespace anywhere. */
continue;
if (ch == pad64)
break;
pos = strchr (base64, ch);
if (pos == 0) /* a non-base64 character. */
return (-1);
switch (state)
{
case 0:
if (target)
{
if ((size_t) tarindex >= targsize)
return (-1);
target[tarindex] = (pos - base64) << 2;
}
state = 1;
break;
case 1:
if (target)
{
if ((size_t) tarindex 1 >= targsize)
return (-1);
target[tarindex] |= (pos - base64) >> 4;
target[tarindex 1] = ((pos - base64) & 0x0f) << 4;
}
tarindex ;
state = 2;
break;
case 2:
if (target)
{
if ((size_t) tarindex 1 >= targsize)
return (-1);
target[tarindex] |= (pos - base64) >> 2;
target[tarindex 1] = ((pos - base64) & 0x03) << 6;
}
tarindex ;
state = 3;
break;
case 3:
if (target)
{
if ((size_t) tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - base64);
}
tarindex ;
state = 0;
break;
default:
abort ();
}
}
/*
* we are done decoding base-64 chars. let’s see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == pad64)
{ /* we got a pad char. */
ch = *src ; /* skip it, get next. */
switch (state)
{
case 0: /* invalid = in first position */
case 1: /* invalid = in second position */
return (-1);
case 2: /* valid, means one byte of info */
/* skip any number of spaces. */
for ((void) null; ch != ’\0’; ch = *src )
if (!isspace (ch))
break;
/* make sure there is another trailing = sign. */
if (ch != pad64)
return (-1);
ch = *src ; /* skip the = */
/* fall through to "single trailing =" case. */
/* fallthrough */
case 3: /* valid, means two bytes of info */
/*
* we know this char is an =. is there anything but
* whitespace after it?
*/
for ((void) null; ch != ’\0’; ch = *src )
if (!isspace (ch))
return (-1);
/*
* now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. if we don’t check them, they become a
* subliminal channel.
*/
if (target && target[tarindex] != 0)
return (-1);
}
}
else
{
/*
* we ended by seeing the end of the string. make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}
* 这个程序演示解码过程
* tombkeeper[0x40]nsfocus[0x2e]com
* tombkeeper[0x40]xfocus[0x2e]net
* 2004.08.11
*/ #include <windows.h> #pragma comment(lib, "advapi32.lib")
#define fchk(a) if (!(a)) {printf(#a " failed\n"); return 0;}
typedef struct _cryptoapi_blob {
dword cbdata;
byte* pbdata;
} data_blob;
typedef struct _cryptprotect_promptstruct {
dword cbsize;
dword dwpromptflags;
hwnd hwndapp;
lpcwstr szprompt;
} cryptprotect_promptstruct, *pcryptprotect_promptstruct;
typedef bool (winapi *pcryptunprotectdata)(
data_blob* pdatain,
lpwstr* ppszdatadescr,
data_blob* poptionalentropy,
pvoid pvreserved,
cryptprotect_promptstruct* ppromptstruct,
dword dwflags,
data_blob* pdataout
);
pcryptunprotectdata cryptunprotectdata = null; int main(void)
{
int ret;
hmodule hntdll;
hkey hkey;
dword dwtype;
char data[0x100] = {0};
dword dwsize;
data_blob datain;
data_blob dataout;
ret = regopenkeyex
(
hkey_current_user,
"software\\microsoft\\msnmessenger",
0,
key_read,
&hkey
);
if( ret != error_success ) return 1;
ret = regqueryvalueex
(
hkey,
"password.net messenger service",
null,
&dwtype,
data,
&dwsize
);
if( ret != error_success ) return 1;
fchk ((hntdll = loadlibrary ("crypt32.dll")) != null);
fchk ((cryptunprotectdata = (pcryptunprotectdata)
getprocaddress (hntdll, "cryptunprotectdata")) != null);
datain.pbdata = data 2; //口令密文从第二位开始
datain.cbdata = dwsize-2;
cryptunprotectdata
(
&datain,
null,
null,
null,
null,
1,
&dataout
);
base64_decode (dataout.pbdata, data, strlen(dataout.pbdata));
printf ( "msn password: %s\n", data);
return 0;
}
//copied from gnu libc - libc/resolv/base64.c
int base64_decode (char const *src, char *target, size_t targsize)
{
static const char base64[] =
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789 /";
static const char pad64 = ’=’;
int tarindex, state, ch;
char *pos;
state = 0;
tarindex = 0;
while ((ch = *src ) != ’\0’)
{
if (isspace (ch)) /* skip whitespace anywhere. */
continue;
if (ch == pad64)
break;
pos = strchr (base64, ch);
if (pos == 0) /* a non-base64 character. */
return (-1);
switch (state)
{
case 0:
if (target)
{
if ((size_t) tarindex >= targsize)
return (-1);
target[tarindex] = (pos - base64) << 2;
}
state = 1;
break;
case 1:
if (target)
{
if ((size_t) tarindex 1 >= targsize)
return (-1);
target[tarindex] |= (pos - base64) >> 4;
target[tarindex 1] = ((pos - base64) & 0x0f) << 4;
}
tarindex ;
state = 2;
break;
case 2:
if (target)
{
if ((size_t) tarindex 1 >= targsize)
return (-1);
target[tarindex] |= (pos - base64) >> 2;
target[tarindex 1] = ((pos - base64) & 0x03) << 6;
}
tarindex ;
state = 3;
break;
case 3:
if (target)
{
if ((size_t) tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - base64);
}
tarindex ;
state = 0;
break;
default:
abort ();
}
}
/*
* we are done decoding base-64 chars. let’s see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == pad64)
{ /* we got a pad char. */
ch = *src ; /* skip it, get next. */
switch (state)
{
case 0: /* invalid = in first position */
case 1: /* invalid = in second position */
return (-1);
case 2: /* valid, means one byte of info */
/* skip any number of spaces. */
for ((void) null; ch != ’\0’; ch = *src )
if (!isspace (ch))
break;
/* make sure there is another trailing = sign. */
if (ch != pad64)
return (-1);
ch = *src ; /* skip the = */
/* fall through to "single trailing =" case. */
/* fallthrough */
case 3: /* valid, means two bytes of info */
/*
* we know this char is an =. is there anything but
* whitespace after it?
*/
for ((void) null; ch != ’\0’; ch = *src )
if (!isspace (ch))
return (-1);
/*
* now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. if we don’t check them, they become a
* subliminal channel.
*/
if (target && target[tarindex] != 0)
return (-1);
}
}
else
{
/*
* we ended by seeing the end of the string. make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}
上一篇: PHP数据库安全之SQL注入
下一篇: 大、中、小企业运营的差距