垃圾桶

EL PSY CONGROO.

Lz1y's avatar Lz1y

通过Dpapi获取Windows身份凭证

一开始想写的比较多,后来想了下还是算了,作为笔记简单记录下。

Dpapi简述

从Windows 2000开始,Microsoft随操作系统一起提供了一种特殊的数据保护接口,称为Data Protection Application Programming Interface(DPAPI)。其分别提供了加密函数CryptProtectData 与解密函数 CryptUnprotectData 以用作敏感信息的加密解密。

其用作范围包括且不限于:

  • IE、Chrome的登录表单自动完成
  • Powershell加密函数
  • Outlook, Windows Mail, Windows Mail, 等邮箱客户端的用户密码。
  • FTP管理账户密码
  • 共享资源文件夹的访问密码
  • 无线网络帐户密钥和密码
  • 远程桌面身份凭证
  • EFS
  • EAP/TLS 和 802.1x的身份凭证
  • Credential Manager中的数据
  • 以及各种调用了CryptProtectData函数加密数据的第三方应用,如Skype, Windows Rights Management Services, Windows Media, MSN messenger, Google Talk等。
  • etc

由于功能需求,Dpapi采用的加密类型为对称加密,所以只要找到了密钥,就能解开物理存储的加密信息了。

Master Key Files

存放密钥的文件则被称之为Master Key Files,其路径一般为%APPDATA%/Microsoft/Protect/%SID%。而这个文件中的密钥实际上是随机64位字节码经过用户密码等信息的加密后的密文,所以只需要有用户的明文密码/Ntlm/Sha1就可以还原了。


其中,除了GUID命名的文件之外,还存在一个名为Preferred的文件。

Preferred

为了安全考虑,Master Key是每90天就会更新一次,而Preferred文件中记录了目前使用的是哪一个Master Key文件以及其过期时间,这里这个文件并没有经过任何加密,只需要了解其结构体就可以任意篡改,三好学生师傅已经写过相关内容,我就不在赘述了:
https://3gstudent.github.io/3gstudent.github.io/%E6%B8%97%E9%80%8F%E6%8A%80%E5%B7%A7-%E8%8E%B7%E5%8F%96Windows%E7%B3%BB%E7%BB%9F%E4%B8%8BDPAPI%E4%B8%AD%E7%9A%84MasterKey/

CREDHIST

此外,在%APPDATA%/Microsoft/Protect/目录下还有一个CREDHIST文件。由于Master Key的还原与用户密码相关,所以需要保存用户的历史密码信息以确保接口的正常使用,而此文件中就保存了用户的历史密码(Ntlm hash/sha1 hash)。感兴趣的可以自己去查查资料,mimikatz中有这个相关功能,但是没有案例,需要自行阅读源码~

ps: 这些相关文件都被作为系统文件隐藏起来了,所以需要修改文件夹选项显示这些文件:

获取Master Key

这里列举几个常见的手段(非域环境):

  • 用户身份凭证(或者历史用户身份凭证)
  • DPAPI_SYSTEM(DPAPI_SYSTEM作为Master Key本地备份文件的密钥存放于LSA secret中,想要获取的话也就老办法,dump内存或者注册表即可)
  • Dump Lsass

用户身份凭证

使用mimikatz的dpapi模块中的masterkey方法,指定目标用户master key file。在无凭证传入的情况下,仅仅只是解析了结构体。

带入参数/hash或者/password 输入密码,即可获取到masterkey。

DPAPI_SYSTEM

使用lsadump::secrets命令获取DPAPI_SYSTEM。

使用mimikatz的dpapi模块中的masterkey方法,指定系统master key file

获取到key。

Dump Lsass

privilege::debug提升到debug权限。
sekurlsa::dpapi获取内存中的所有MasterKey。

tips
可以用dpapi::cache查看此前获取到的所有MasterKey。

可以看到,系统中存在这么多个Master key,那如何判断目标文件需要使用哪个key呢?

使用MasterKey解密

有关部分DPAPI可以解密的数据存储地址,本杰明整理了一份列表(列表失效了,但是能图中看到):
https://twitter.com/gentilkiwi/status/696021888385028096

这里使用Cred举例,其目录位%APPDATA%/Microsoft/Credentials/

使用dpapi::cred命令指定in参数:
dpapi::cred /in:C:\Users\11632\AppData\Local\Microsoft\Credentials\3151F79BA320A9E261AA218C58BED0A7
默认情况下会打印出其结构体信息:

可以看到有一行参数guidMasterKey: {dfe23673-86ee-420c-bcab-714a83f495d6}。
而 {dfe23673-86ee-420c-bcab-714a83f495d6} 就是指向MasterKey的索引,其实也就是文件名:

这样我们就可以找到文件所对应的Master key,并且解开密文了。
如果此前你已经使用之前介绍的几种方法找到了Master key,mimikatz会将其放入cache中,这样如果目标文件所对应的Master key在此前已经获取过,mimikatz会自动带入参数。

自动化利用

前面已经非常简单的介绍过相关的利用手段了,但是还是不够方便,还是需要人工手动的去解密。
这里推荐一个项目 https://github.com/GhostPack/SharpDPAPI ,程序功能出来与mimikatz没有太大区别,方便的是CNA脚本中,通过正则匹配Mimikatz导出的masterkey,然后批量的去解密credentials|vaults|RDP Cred文件。
使用流程,编译项目后,修改CNA脚本中的$SharpDPAPI::AssemblyPath为SharpDPAPI.exe的绝对路径。

Use: sharpDPAPI [-dump] [-allkeys]
Arguments:
    -dump        Use mimikatz to dump DPAPI keys from lsass using Mimikatz's sekurlsa::dpapi
    -allkeys     Use all DPAPI keys found in the credential store (not just the DPAPI keys found on this host)

初次使用就直接使用sharpDPAPI -dump,其命令流为:

sekurlsa::dpapi
dpapi::cache
正则匹配Console output中的所有Guid与Master key,并把结果存入CS的credman中
sharpDPAPI triage {GUID1}:MasterKey1  {GUID2}:MasterKey2  



效果相当喜人,美中不足是没有去Dump浏览器相关的信息。
sharpDPAPI中也包含sharpChrome,其也是通过Dpapi解密获取浏览器的密码信息(/unprotect参数需要是本用户的文件)。
SharpChrome.exe cookies /target:"C:\Users\11632\AppData\Local\Google\Chrome\User Data\Default\Cookies" /unprotect
or
SharpChrome.exe logins /target:"C:\Users\11632\AppData\Local\Google\Chrome\User Data\Default\Login Data" /unprotect
效果其实也还不错,缺点就是排版难看了点,以及并没有支持其他的浏览器。

这里可以与另外一个项目 https://github.com/djhohnstein/SharpWeb 互补。此项目优点就是排版舒服了,可惜没有导出Cookie的功能(苦笑

本机测试,密码太多了就不截图了 233,请自行测试吧~

REF

https://adsecurity.org/?page_id=1821#DPAPI
https://www.harmj0y.net/blog/redteaming/operational-guidance-for-offensive-user-dpapi-abuse/
https://www.passcape.com/index.php?section=docsys&cmd=details&id=28
https://github.com/gentilkiwi/mimikatz/wiki/module-~-dpapi#credhist
https://github.com/gentilkiwi/mimikatz/wiki/howto-~-decrypt-EFS-files