分享
 
 
 

通过DPAPI获取当前帐号保存的 MSN Messenger 密码

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

通过DPAPI获取当前帐号保存的 MSN Messenger 密码

作者:Flier Lu <flier @ nsfocus.com>

出处:http://www.blogcn.com/User8/flier_lu/index.html?id=3300158

主页:http://flier_lu.blogone.net/

日期:2004-09-06

通过 DPAPI 获取当前帐号保存的 MSN Messenger 密码

tomekeeper 在水木BBS上贴了一个通过 DPAPI 获取保存的 MSN 密码的代码。其核心思想是从 MSN 加密保存在注册表中的键里,把加密后字符串抠出来,然后使用 DPAPI 的函数 CryptUnprotectData 解密之。关键代码如下:

//...

ret = RegOpenKeyEx

(

HKEY_CURRENT_USER,

"Software\\Microsoft\\MSNMessenger",

0,

KEY_READ,

&hKey

);

//...

ret = RegQueryValueEx

(

hKey,

"Password.NET Messenger Service",

//...

);

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);

不过这种方法针对 XP/2003 环境下的新版本 MSN 没有效果,因为最新版本的 MSN 已经不再将加密后的密码直接保存在注册表键里。于是我安装类似思路,使用 Windbg 和 IDA Pro 大概分析了一下新版本的保存密码方法。得出结论是 MSN 使用了 XP/2003 新增的对当前用户凭据集 (credential set) 管理的函数,将加密后密码放到这个里面统一管理。

可以使用新增的 CredReadDomainCredentials 函数,给定读取目标来获得加密凭据,如:

typedef struct _CREDENTIAL_TARGET_INFORMATIONW {

LPWSTR TargetName;

LPWSTR NetbiosServerName;

LPWSTR DnsServerName;

LPWSTR NetbiosDomainName;

LPWSTR DnsDomainName;

LPWSTR DnsTreeName;

LPWSTR PackageName;

ULONG Flags;

DWORD CredTypeCount;

LPDWORD CredTypes;

} CREDENTIAL_TARGET_INFORMATIONW, *PCREDENTIAL_TARGET_INFORMATIONW;

DWORD CredTypes = CRED_TYPE_DOMAIN_VISIBLE_PASSWORD;

CREDENTIAL_TARGET_INFORMATIONW target =

{ L"messenger.hotmail.com", NULL, NULL, NULL,

L"Passport.Net", NULL, L"Passport1.4", 0, 1, &CredTypes };

DWORD dwCount = 0;

PCREDENTIALW*creds;

Win32Check(CredReadDomainCredentialsW(

&target, CRED_CACHE_TARGET_INFORMATION, &dwCount, &creds),

"Cannot read user\'s domain credential, maybe you are not save your password");

这里的 CREDENTIAL_TARGET_INFORMATIONW 结构指定要获取凭据的来源和包名称;CredReadDomainCredentialsW 则根据此信息,通过 NdrClientCall2 函数发送 RPC 调用,完成实际功能。

读取出来的凭据包括此凭据的用户名 (UserName) 和凭据内容 (CredentialBlob):

typedef struct _CREDENTIALW {

DWORD Flags;

DWORD Type;

LPWSTR TargetName;

LPWSTR Comment;

FILETIME LastWritten;

DWORD CredentialBlobSize;

LPBYTE CredentialBlob;

DWORD Persist;

DWORD AttributeCount;

PCREDENTIAL_ATTRIBUTEW Attributes;

LPWSTR TargetAlias;

LPWSTR UserName;

} CREDENTIALW, *PCREDENTIALW;

PCREDENTIALW cred = creds[0];

MSN Messenger 来说,CREDENTIALW::UserName 中就是登陆帐号了。MSN Messenger 每次显示文件菜单时,都会从凭据集中获取当前帐号名称用于显示。而每次登陆时,则进一步将凭据集的内容使用 CryptUnprotectData 函数进行解密,代码如下:

static unsigned char entropyData[] = {

0xe0, 0x00, 0xc8, 0x00, 0x08, 0x01, 0x10, 0x01,

0xc0, 0x00, 0x14, 0x01, 0xd8, 0x00, 0xdc, 0x00,

0xb4, 0x00, 0xe4, 0x00, 0x18, 0x01, 0x14, 0x01,

0x04, 0x01, 0xb4, 0x00, 0xd0, 0x00, 0xdc, 0x00,

0xd0, 0x00, 0xe0, 0x00, 0xb4, 0x00, 0xe0, 0x00,

0xd8, 0x00, 0xdc, 0x00, 0xc8, 0x00, 0xb4, 0x00,

0x10, 0x01, 0xd4, 0x00, 0x14, 0x01, 0x18, 0x01,

0x14, 0x01, 0xd4, 0x00, 0x08, 0x01, 0xdc, 0x00,

0xdc, 0x00, 0xe4, 0x00, 0x08, 0x01, 0xc0, 0x00, 0x00, 0x00 };

PCREDENTIALW cred = creds[0];

DATA_BLOB data = { cred->CredentialBlobSize, cred->CredentialBlob },

entropy = { sizeof(entropyData), entropyData }, pass = { 0, NULL };

BOOL ret = CryptUnprotectData(&data, NULL, &entropy, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &pass);

这里 entropyData 保存着通过 WinDbg 直接从 MSN Messenger 代码中抠取出来的内部使用固定加密密钥,以后有可能根据版本不同发生变化。因为新版 MSN Messenger 不在直接加密密码,而是使用此密钥加密,因此与 tomekeeper 那种处理稍有不同。解密后的 pass中保存的就是明文的当前 MSN Messenger 帐号的密码了,呵呵。

static const std::string toString(LPCWSTR lpStr, DWORD cbStr)

{

std::string str;

str.resize(WideCharToMultiByte(CP_ACP, 0, lpStr, cbStr, NULL, 0, NULL, NULL));

WideCharToMultiByte(CP_ACP, 0, lpStr, cbStr, (char *)str.c_str(), str.size(), NULL, NULL);

return str;

}

static const std::string toString(LPCWSTR lpStr)

{

return toString(lpStr, wcslen(lpStr));

}

m_username = toString(cred->UserName);

m_fCredFree(creds);

Win32Check(ret, "Cannot decrypt credential");

m_password = toString((LPCWSTR)pass.pbData, pass.cbData / sizeof(wchar_t));

::LocalFree(pass.pbData);

看起来这样保存密码似乎很不安全,其实也还好了,呵呵。因为 CredReadDomainCredentials 和 CryptUnprotectData 等系列函数,缺省都是使用的当前帐号的安全上下文进行加密解密,哪怕换了台机器这些加密后的数据都不再有意义。因此除非你机器被人搞到当前帐号或者 Administrator 帐号权限,否则密码都还是安全的;反过来说,如果这两个帐号被别人搞到,随便装个键盘记录程序也能够达到类似的效果。因此总体上来说还是比较安全的,这个代码也只能作为忘记自动记录的 MSN 密码时的恢复工具 :P 其实这个才是我们俩研究此问题的主要目的,呵呵

此外 XP/2003 有一个新增命令行命令 cmdkey,使用其 /list 参数可以列出当前用户凭据集中所有保存的凭据信息,如你在其他机器上网络连接的登陆信息、.NET passport 的帐号信息等等。可以通过本文方法略做修改,获取所有这些帐号中保存的密码。:D

Just for fun! :P

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有