当前位置:首页 > 未分类 > 创建密码重置盘的时候,系统都做了些什么

创建密码重置盘的时候,系统都做了些什么

admin1年前 (2020-10-12)未分类207

创建密码重置盘的时候,系统都做了些什么
注:本文作为一篇研究报告,转自网络,查看后续请点击此处
“密码重置盘”是从Windows XP开始即加入Windows系统,并且一直保留至今的一项功能。其目的是在用户忘记登录密码时,可以使用预先创建好的物理凭据重置密码。
基本原理

密码重置盘的本质是一个RSA私钥,用于解密在系统中(为密码重置而专门)存储的用户密码。
创建密码重置盘时,系统会生成一个RSA公私钥对和一张自签名的证书。用户密码被公钥加密并签名,并和证书一起存储在计算机中(具体细节见下);私钥则被保存在密码重置盘根目录下的userkey.psw文件中。
由这个过程,我们可以得到密码重置盘的几个性质:
密码重置盘与用户一一对应;更换用户,密码重置盘会失效。
系统识别密码重置盘只会看根目录下的userkey.psw文件,与其他文件一律无关。由此,使用一个可移动介质做多张密码重置盘是可行的,不过需要每次使用之前手动修改文件名。
密码重置盘只能重置密码是系统有意进行的限制。由密码重置盘恢复密码是可能的。
下文中,我的研究方向也就在“如何从密码重置盘恢复密码”上。对于其它方向涉及的可能不算深入。
技术细节

值得注意的是,微软在密码重置盘这个功能上基本没有做出过任何改动或改进。下文中,若非特殊说明,分析结论适用于自Windows XP开始所有版本的Windows。

0. 向导程序的手动调用方式
密码重置盘的创建向导和使用向导都在系统的凭据管理器keymgr.dll中,可以使用命令手动调用:
创建向导(当前用户):rundll32 keymgr.dll,PRShowSaveWizardEx
创建向导(指定用户):rundll32 keymgr.dll,PRShowSaveFromMsginaW <用户名>
重置向导(指定用户):rundll32 keymgr.dll,PRShowRestoreWizardEx <用户名>
在启动向导之前要确保电脑中已有可移动介质插入,否则向导会报错,拒绝启动。
1. 自签名证书
证书因为只做签名目的与恢复密码无关,不做深入研究。
生成的证书被放在本地计算机的一个名为Recovery的存储区中。这些证书具有如下性质:
颁发给/颁发者:空
有效期从:创建密码重置盘的时间
有效期至:创建密码重置盘的时间 + 5年
签名算法:SHA1
公钥:RSA 2048位
注意在没创建过密码重置盘的系统中,Recovery存储区是不存在的。
2. 密码重置盘/RSA私钥
上文所述的userkey.psw文件具有只读、归档属性。
在Windows XP上,.psw还有类型标注,名为Password Backup。同时在注册表中(HKEY_CLASSES_ROOT\PSWFile)还标注了NoOpen属性,即在试图打开psw类型文件时,会弹出一个“系统文件警告”提示。
文件的内容本质上是系统API CryptExportKey的导出结果,外加了一个8字节的文件头。私钥明文存储,文件结构见userkey.h。
由这个文件的内容,可以使用这里提供的方法还原出一个标准格式的RSA私钥文件。具体操作不再赘述。
3. 加密的用户密码

这些数据(不出所料地)被放进了注册表。
在Windows XP上,具体的路径为HKEY_LOCAL_MACHINE\SECURITY\Recovery\<SID>的默认键值,类型为REG_BINARY,其中<SID>为用户的SID。
在Windows 7及以上版本,注册表路径变为了HKEY_LOCAL_MACHINE\C80ED86A-0D28-40dc-B379-BB594E14EA1B\<SID>(原文如此),而且这个项变成了按需加载;密码重置盘创建完毕时这个项就会被卸载。卸载后的注册表文件位于%SystemRoot%\System32\Microsoft\Protect\Recovery\Recovery.dat。
注意:无论是注册表还是卸载后的文件,都需要至少SYSTEM权限才能够读取。
这些REG_BINARY数据的结构如regdata.h所示。数据的最后256字节便是加密过的用户密码。解密步骤如下:
取这256字节的数据,进行一次字节顺序翻转。
设翻转后的数据保存为文件enc.bin,使用上面的步骤生成的DER格式私钥为key.der。使用OpenSSL解密数据:openssl rsautl -decrypt -in enc.bin -out dec.bin -inkey key.der -keyform DER。
文件dec.bin中便是以Unicode格式(Windows口中的Unicode,即UTF-16 LE)存储的密码明文。
X. 逆向工程的更多细节
向导的GUI界面,和密钥/证书生成部分的逻辑,都是在keymgr.dll中实现的。
由界面到生成逻辑的引用链如下所示(符号名称来自PDB):

PRShowSaveWizardExW
  SPageProc1
    SaveThread
      SaveInfo(进入逻辑部分,返回时保存私钥)
        PRGenerateRecoveryKey(生成私钥)
          GenerateRecoveryCert(生成证书)
          PRImportRecoveryKey(RPC,通知系统保存密码)
 
PRShowRestoreWizardExW
  PRShowRestoreWizardW
    RPageProc1
      SetAccountPassword(进入逻辑部分)
        PRRecoverPassword(RPC,通知系统验证与修改密码)

两条调用链都终止于RPC调用,确切的说是LPC端口protected_storage。有趣的是提供这个端口的服务Protected Storage服务早在Windows 8时就因为不安全而被移除了,但Windows 10中这个功能仍然可用。
查阅资料得到关键信息:这个端口下有PasswordRecovery接口,GUID为5cbe92cb-f4be-45c9-9fc9-33e73e557b20。使用RpcView工具轻易查到,提供这个接口的模块是由lsass.exe加载的dpapisrv.dll。

P.S.: RpcView的上次Release是2017年,又因为有对系统文件版本的检查,导致其拒绝启动。最终对程序进行了patch才能用。
接口中的三个方法调用链如下:

keymgr!PRImportRecoveryKey
  s_SSRecoverImportRecoveryKey
    EncryptRecoveryPassword(构造注册表数据并保存)
      (各类细化的操作)
 
keymgr!PRRecoverPassword
  s_SSRecoverPassword
    ???(未进行分析)
 
???
  s_SSRecoverQueryStatus
    ???(这个方法好像没用到)

注册表数据中的SHA1和签名分别由API CertGetCertificateContextProperty和内部函数LogonCredGenerateSignature生成,过程复杂,未进行分析。
负责加密的是API BCryptEncrypt函数,之后由FMyReverseBytes进行字节顺序翻转。
最后保存数据的是RecoverySetSupplementalCredential函数。由此可见,微软内部称密码重置盘为“追加凭据”。那个让前辈不明所以的GUID字符串C80ED86A-0D28-40dc-B379-BB594E14EA1B也得到了解释:这个字符串是硬编码进去的,不具备什么实际意义。
更多逆向工程细节(以及伪造密码重置盘的尝试)参见本文后续

参考
https://blog.51cto.com/markwin/219205


https://docs.microsoft.com/en-us/windows/win32/seccrypto/rsa-schannel-key-blobs


https://technet.microsoft.com/zh-cn/learning/aa380258(v=vs.100).aspx


https://stackoverflow.com/a/19855935


https://l.wzm.me/_security/internet/_internet/WinServices/ch04s10s15.html


https://reverseengineering.stackexchange.com/a/8118


https://github.com/silverf0x/RpcView


转载自:http://www.cnhonkerarmy.com/thread-252803-1-1.html

    扫描二维码推送至手机访问。

    版权声明:本文由勤奋的思远发布,如需转载请注明出处。

    如果文章对你有帮助的话就赞助一下吧https://lsybk.xyz/donation.html

    本文链接:https://lsybk.xyz/post/PRD1.html

    标签: 系统安全
    分享给朋友:

    相关文章

    【C++入门教程(3)】简单的加法程序

    【C++入门教程(3)】简单的加法程序

    上节课我们学了输出语句那么这节课我们就再教些新的知识加法程序看看源码#include<iostream> using namespace std; int ...

    一款强大的网站在线客服聊天系统:whisper搭建教程

    一款强大的网站在线客服聊天系统:whisper搭建教程

    简介whisper是一个在线客服系统源码,采用thinkphp5+Gatewayworker编写,性能强悍。自己搭建,控制在自己,也无需为您的数据安全担心,您可以应用在任何的正规的网站,只需要添加一段...

    友情链接-My Friends

    友情链接-My Friends

    全站链接(附在侧边栏及下方)梦之国             内页链接(只在本页显...

    友情赞助

    友情赞助

    寄语:本着学习与记录技术的初心,我在初一时搭建了这个博客。如果您觉得本站的内容对您有所帮助,希望您可以小小的意思一下,多少不限,一切都是为了能够更好的运营和维护本站,能打赏站长一个鸡腿嘛。现支持三种赞...

    GoogleHacking常用语法(转载)

    GoogleHacking常用语法(转载)

    1、intext:(仅针对Google有效) 把网页中的正文内容中的某个字符作为搜索的条件2、intitle:把网页标题中的某个字符作为搜索的条件3、cache:搜索搜索引擎里关于某些内容的缓存,可能...

    sqlmap各项参数介绍

    sqlmap各项参数介绍

    教程说明学习sqlmap前,建议了解SQL注入实现原理与基本的手工注入操作,更易于理解sqlmap的使用。我的另一个笔记整理:可能是网上最易懂的SQL手工注入教程【个人笔记精华整理】针对sqlmap注...

    发表评论

    访客

    看不清,换一张

    ◎欢迎参与讨论,请在这里发表您的看法和观点。