前段时间ADSL密码忘记了,但幸好还保存在拨号连接里面,于是到网上找了些星号密码显示工具,可惜不起作用。后来找到一种名为dialupass的工具,这家伙不负重望把密码给我还原出来了。(用的dialupass v2.42,我的系统是windows xp)
看起来dialupass非普通的星号密码显示工具,那它的原理是什么呢?上GOOGLE查了一翻,没找到相关资料(可能是我用的关键字有问题)。 一生气便操起家伙(windbg)准备把它大卸八块。郁闷的是,用windbg加载后,密码就还原不出来了,显示是星号。换替补ollydbg上场,情况依旧。莫非这小工具有Anti-Debug功能?当时只是一丝怀疑,因为实
在不相信这样的小工具作者会花心思来保护。
后来在用s-ice跟踪的过程中,发现有这么一个调用:
GetProcAddress(xx, "IsDebugPresent")。
晕倒,原来真的有Anti-Debug功能,好在比较简单。统计了一下,总共有5处进行了
Anti-Debug检查。
情况查明了,便换回windbg来调试,在windbg里面下这么一个断点便可绕过Anti-Debug
检测:
bp KERNEL32!IsDebuggerPresent "g poi(esp);r eax=0;g"
花了些时间跟踪了一下,把dialupass恢复密码的流程都搞清楚了。这小程序猫腻还
挺多的,总结如下:
1. 关键函数不直接调用,而是用LoadLibraryA和GetProcAddress来获取函数地址
后再CALL。
2. 函数名是经过编码的,反汇编后看字符串是看不到的。
3. 关键地方一概用花指令来迷惑你和反汇编软件。
其实原理很简单,就是用rasapi32.dll里面的一些函数来获取拨号连接的一些信息,
再用 ADVAPI32!LsaRetrievePrivateData 函数来获取密码。
根据dialupasss的原理,写了个类似的工具,源代码参见后面的x_dialupass.c。
后来用"LsaRetrievePrivateData"和"RasDialParams"做关键字,重新在GOOGLE搜索了
一遍,找到一些类似的代码。
参考资源[1]和[2]的是俄罗斯人公布的演示代码,没有对LsaRetrievePrivateData返回
的数据进行拆分用户名和密码。参考资源[3]是日本人公布的完整的应用程序的代码,可惜
在对LsaRetrievePrivateData返回的数据进行拆分处理时存在BUG,导致有些情况下用户名
和密码取的不正确。
后来发现lsadump2 DUMP出来的数据里面包含了"LsaRetrievePrivateData"返回的数
据。lsadump2的原理大致如下:
1)插入一线程到lsass.exe进程
2)打开LSA Policy database
3)从注册表"HKLM\SECURITY\Policy\Secrets"中枚举子键
4)LsarOpenSecret
5)LsarQuerySecret
进一步跟踪后发现,其实ADVAPI32!LsaRetrievePrivateData是通过NdrClientCall2
发送RPC调用到lsass.exe进程,lsass.exe里面再调用LsarOpenSecret、LsarQuerySecret
来完成获取拨号连接信息过程的。(注:LsarOpenSecret里面有权限判断,非ADMIN组用
户是没有权限来调用ADVAPI32!LsaRetrievePrivateData的)
跟踪了一下LsarQuerySecret,发现它返回的数据其实是从注册表中读取。保存拨号
连接信息的注册表键值为:
HKLM\SECURITY\Policy\Secrets\RasDialParams!SID#0\CurrVal
SID对应的是用户的string SID。(“HKLM\SECURITY”这个键只有SYSTEM有权限读
写,连admin都没有权限)
LsarQuerySecret从注册表中读取出来数据后,接着调用LsapCrDecryptValue函数来
解密,对于同一台机器来说,解密时用的KEY始终都是固定的,这个KEY在lsasrv.dll里面
变量名为"_LsapDbSecretCipherKey"。在windows 2003里面,变量名不一样,对应的有两
个,分别为"LsapDbSecretCipherKeyWrite"和"LsapDbSecretCipherKeyRead",但这两个
变量里面的数据是一样的。
LsapCrDecryptValue用的似乎是标准DES算法,解密时主要流程如下:
|
假如[esi+45h]为0的话(esi是LsarOpenSecret函数返回的HANDLE),它会把解密后的
数据再进行一次加密,不管是2000还是2003,这时用的KEY始终都是固定为
“SystemLibraryDTC”。
lsadump2里面调用LsarOpenSecret得到的HANDLE,偏移0x45处值为1,所以
LsarQuerySecret函数返回的就是解密后的数据了。
而在调用ADVAPI32!LsaRetrievePrivateData时,LsarOpenSecret返回的HANDLE偏移
0x45处值为0x0,所以LsarQuerySecret返回的是解密后又加密的数据,所以在
ADVAPI32!LsaRetrievePrivateData里面还有一个对应的解密过程。相应的,
LsapCrEncryptValue加密的主要流程如下:
lsasrv!LsapCrEncryptValue |
开始我以为在同一版本的windows里面,_LsapDbSecretCipherKey是固定的,后来
发现我错了。那么这个_LsapDbSecretCipherKey是如何产生的?流程如下:
(1)调用ntdll!NtConnectPort打开 L"\Security\WxApiPort"
(2)调用ntdll!NtRequestWaitReplyPort得到一些数据
ebp-40处为NtRequestWaitReplyPort返回的LPCMESSAGE |
(3)将上述"ebp-14"处的0x10字节数据COPY到lsasrv.dll里面的"_LsapDbSysKey"变量。
"_LsapDbSysKey"在不同的机器上面(即使版本相同)都是不一样的。它是怎么产生的?有
幸拜读了flashsky的大作后(参考资源[4]),才明白这就是传说中的"SYSKEY"。用flashsky
的代码验证一下:
| c:\>getsyskey 3e 7e 31 fd 6d e8 24 7e d3 03 25 d1 a8 01 7d 5f |
跟踪系统启动过程,可知道"\Security\WxApiPort"是由winlogon.exe进程创建的,然
后lsass进程通过这个LPC PORT从winlogon进程获取SYSKEY,随后winlogon进程会关闭这
个LPC PORT。所以在系统启动完成之后,用"Process Explorer"等工具是看不到这个
LPC PORT存在的,而且在winlogon和LSASS进程空间都搜索不到上述SYSKEY。
(4)从注册表"HKLM\SECURITY\Policy\PolSecretEncryptionKey"中读取出来一段数据,
调用函数_LsapDbDecryptKeyWithSyskey,把它用"_LsapDbSysKey"来解密,
"_LsapDbSecretCipherKey"就在解密完后的数据里面。("LsapDbDecryptKeyWithSyskey"函
数做的其实就是MD5和RC4运算)
了解原理后,我们就可以直接从注册表里面来获取拨号连接中的密码等数据了。但
有几个问题需要解决:
(1)原料。
Q:"HKLM\SECURITY"键只有SYSTEM有权限读写?
A:我们可以把代码插入到SYSTEM进程里面去运行,或者把这个键修改为ADMIN有
权限读,或者提升本进程权限。
(2)催化剂:)
Q: 如何获取"_LsapDbSysKey"?解密用的函数_LsapDbDecryptKeyWithSyskey为非导出函
数,怎么办?
A1: 用flashsky的代码来获取SYSKEY,利用公开的MD5和RC4库函数来解密。
A2: 直接从lsass.exe进程里面搜索"_LsapDbSecretCipherKey",它的结构如下,
typedef struct _LSA_BLOB { |
pbData指向存储KEY的地址,KEY长度固定为0x10字节,即cbData和cbMaxData都是固定
为0x10。所以从lsass进程的空间里面搜索"\x10\x00\x00\x00\x10\x00\x00\x00"即可找到
正确的KEY。结果可能会有多个,可以把所有搜索到的KEY都试一下,总有一个正确的。
(3)工具
Q: 解密函数LsapCrDecryptValue为非导出函数,怎么办?
A: 或许可以根据特征码来搜索,但总觉得不太可靠。幸好,LsapCrDecryptValue
调用的advapi32!SystemFunction005是导出函数:)。或者直接利用公开的DES库函数,
自己来运算。
x_dialupass2.cpp中的代码演示了直接从注册表中读取数据并解密之的过程,没有
太多实际意义,just for fun!
-=-=-=-=-=-=-=-=-=-= x_dialupass.c -=-=-=-=-=-=-=-=-=-=
/*
演示还原NT平台上拨号连接的密码
可运行于windows 2000/xp/2003
原理基于分析dialupass v2.42
eyas at xfocus.org |
|
· “熊猫烧香”病毒制造.. · 中国黑客超强X档案 第2.. · 中国黑客超强X档案 第2.. · Windows年底再现图片漏.. · MBSA本地审核策略建议 · 年终岁末,注意病毒给.. |
· 中国黑客超强X档案 第2.. · 中国黑客超强X档案 第1.. · 中国黑客超强X档案 第1.. · 以crossbeam为硬件平台.. · 软考辅导内部资料:数.. · ospf的工作原理是怎么.. |
|
|||
| · OSPF路由协议专栏 · 思科路由器产品 · 华为路由器产品 · 路由器模拟器 · AIX操作系统管理应用(.. · 思科路由器配置 · 路由器组网解决方案 · 路由器密码恢复 |
· 无线路由器故障处理 · 路由故障处理手册 · 路由器访问控制列表(AC.. · 路由器的安全配置与安.. · 无线路由器配置 · 路由器技巧 · 华为路由器配置 · 路由器配置基础 |
||
|
|||
| · Java基础教程 · VPN技术 · SQL Server 2005全解 · ARP攻击防范与解决方案 · SOA 面向服务架构 · SQL Server 2005全解 · Java编程开发手册 · 三层交换技术专题 |
· SQL Server入门到精通 · Windows Server 2003企.. · Windows远程桌面应用 · C#技术开发指南 · VPN技术 · Solaris 10 配置管理 · C#技术开发指南 · Windows操作系统安装 |
||
|
|||
| · VPN技术 · ARP攻击防范与解决方案 · SQL Server 2005全解 · Java基础教程 · SQL Server入门到精通 · SQL Server 2005全解 · SOA 面向服务架构 · Java编程开发手册 |
· C#技术开发指南 · 三层交换技术专题 · C#技术开发指南 · Windows远程桌面应用 · Windows Server 2003企.. · 邮件服务器专题 · wimax技术与趋势 · Windows操作系统安装 |
||
| ·DB2 Viper快速入门 ·DB2 9数据库的镜像分割与.. |
·将XML应用程序从DB2 8.x.. ·DB2 9中的pureXML:如何.. |
| ·服务器中的“傻瓜机”在.. ·盖茨也喜欢登录Youtube看.. |
· · |
| · 职场冲浪(之八):让感.. ·职场冲浪(之七):潜心.. |
·人生如鞋 ·职场冲浪(之六):从离梦最.. |
| ·将职业教育职业化 - 各IT.. ·思科交换机上实现MAC地址.. |
·关于51CTO合作出书中的职.. ·OSPF动态路由协议入门简介 |
| · NGN:下一代网络 · 网络访问中断大排查 · FTTx光纤接入 |
· 平凡黑客讲述精彩人生(.. · 平凡黑客讲述精彩人生(.. · 平凡黑客讲述精彩人生(.. |
| · C++是垃圾语言?! · 2007年IT界七大抄袭事件 · Java实用开发全集 |
· 解析Ajax开发框架 走进A.. · 基于Google Maps与Ajax.. · 基于Google Maps与Ajax.. |
| · Ubuntu 中文开源频道 · Solaris基础知识入门 · 微软正式发布英文版Wind.. |
· 服务器基础知识入门 · Rambus第二?看全缓冲内.. · 服务器节能对比测试:AM.. |
| · 甲骨文Oracle 11g正式发.. · Oracle数据库开发之PL/S.. · Oracle数据库开发基础教.. |
· 存储2006,一个并购的大.. · IDC宣布浪潮蝉联存储市.. · 双机热备技术 |