通过 Network Security Services 导出 Firefox 浏览器中保存的密码
0x00 前言
在上一篇文章 《渗透技巧——导出 Firefox 浏览器中保存的密码》 介绍了导出 Firefox 浏览器密码的常用方法,其中 firefox_decrypt.py 使用 NSS(Network Security Services) 进行解密,支持 key3.db 和 key4.db 的 Master Password 解密。本文将要对其涉及的原理进行介绍,编写测试代码,实现对 Master Password 的验证,分享脚本编写的细节
0x01 简介
本文将要介绍如下内容:
- Network Security Services 简介
- 通过 python 调用 Network Security Services 导出 Firefox 浏览器密码
- 开源 python 脚本
- 爆破脚本的实现
0x02 Network Security Services 简介
Network Security Services(NSS) 是一组旨在支持安全的客户端和服务器应用程序跨平台开发的库
参考文档:https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS
Firefox 浏览器使用 NSS 作为加密算法和安全网络协议的基础库,在凭据加解密上使用了 PKCS#11 标准
参考文档:https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/PKCS11
0x03 通过 Python 调用 Network Security Services 导出 Firefox 浏览器的密码
参考代码:
- https://github.com/unode/firefox_decrypt
- https://github.com/Kerisa/BrowserPasswordDump/blob/master/MozillaPwd.py
Windows 系统下的解密流程如下:
- 加载 Network Security Services 需要的 nss3.dll
- 调用 NSS_Init() 进行初始化
- 调用 PK11_GetInternalKeySlot() 来获得 internal slot(用作验证 Master Password)
- 调用 PK11_CheckUserPassword() 验证 Master Password
- 读取 logins.json 获得加密数据
- 调用 PK11SDR_Decrypt() 进行解密
具体需要注意的问题如下:
1. Python 和 Firefox 的版本需要保持一致
64 位系统下,需要同为 32 位或 64 位
2. 将 Firefox 的安装路径加入到环境变量,便于调用
Firefox 浏览器的安装目录下有我们需要调用的 nss3.dll,所以可以选择将 Firefox 的安装路径加入到环境变量 PATH,对应的 python 代码如下:
import os
firefoxPath = "C:\Program Files\Mozilla Firefox"
os.environ["PATH"] = ';'.join([firefoxPath, os.environ["PATH"]])
注:64 位操作系统下,64 位 Firefox 浏览器的默认安装目录为 C:\Program Files\Mozilla Firefox
,32 位 Firefox 浏览器的默认安装目录为 C:\Program Files (x86)\Mozilla Firefox
调用 nss3.dll 的 python 代码如下:
import ctypes
NssDll = ctypes.CDLL("nss3.dll")
3. NSS 初始化时需要三个文件
具体位置为: %APPDATA%\Mozilla\Firefox\Profiles\xxxxxxxx.default\
需要以下三个文件:
- cert9.db
- key4.db
- logins.json
可将以上三个文件保存在同一文件夹下,例如 c:\test\data
NSS 初始化的代码如下:
profilePath = "C:\\test\\data"
NssDll.NSS_Init(profilePath)
4. 读取 logins.json 获得加密的数据
encryptedUsername
和 encryptedPassword
项为加密的数据,需要使用 NSS 进行解密
在解密前需要先进行 base64 解码,再调用 PK11SDR_Decrypt()
解密获得明文
timeCreated
、 timeLastUsed
和 timePasswordChanged
项为 Epoch Time 格式(从协调世界时 1970 年 1 月 1 日 0 时 0 分 0 秒起到现在的总秒数,不包括闰秒),可通过如下网址转换成实际的时间:https://esqsoft.com/javascript_examples/date-to-epoch.htm
转换时间格式的 python 代码如下:
from datetime import datetime
def timestamp_to_strtime(timestamp):
return datetime.fromtimestamp(timestamp / 1000.0).strftime('%Y-%m-%d %H:%M:%S')
print timestamp_to_strtime(1580901797579)
注:不同版本的 Firefox 保存记录的文件名称不同,具体区别如下:
- Version 大于等于 32.0,保存记录的文件为 logins.json
- Version 大于等于 3.5,小于 32.0,保存记录的文件为 signons.sqlite
更详细的文件说明可参考:
http://kb.mozillazine.org/Profile_folder_-_Firefox
0x04 开源 python 脚本
参考代码:
- https://github.com/unode/firefox_decrypt
- https://github.com/Kerisa/BrowserPasswordDump/blob/master/MozillaPwd.py
我的测试代码已上传至 GitHub,地址如下:https://github.com/3gstudent/Homework-of-Python/blob/master/ExportFirefoxPassword.py
测试环境:
- 64 位 Windows 操作系统安装 64 位 Firefox 浏览器
- Firefox 默认安装路径为
"C:\Program Files\Mozilla Firefox"
- 配置文件路径为
"C:\\Users\\a\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\2yi8qmhz.default-beta"
,包括以下三个文件:- cert9.db
- key4.db
- logins.json
代码支持两个功能:
1. 验证 Master Password
对应子函数 checkMasterPassword(MasterPassword)
如果 MasterPassword 正确,显示正确的 MasterPassword,并返回 TRUE
如果 MasterPassword 错误,返回 FALSE
这个可以用来实现对 Master Password 的爆破
2. 导出 Firefox 浏览器中保存的密码
对应子函数 ExportData(MasterPassword)
如果未设置 Master Password,MasterPassword 参数设置为 ""
即可,如果设置了 Master Password,需要填入正确的 Master Password 才能解密获得真正的数据。
具体能够导出以下信息:
- url
- username
- password
- timeCreated
- timePasswordChanged
- timeLastUsed
0x05 小结
本文介绍了通过 Python 调用 Network Security Services 导出 Firefox 浏览器密码的方法,分享脚本编写细节。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 渗透技巧——导出 Firefox 浏览器中保存的密码
下一篇: Jvm 常量池
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论