0x00 Preface
---
In the previous article 'Penetration Techniques - Exporting Saved Passwords from Firefox Browser', common methods for exporting Firefox browser passwords were introduced. Among them, firefox_decrypt.py uses NSS (Network Security Services) for decryption, supporting Master Password decryption for key3.db and key4.db. This article will explain the principles involved, develop test code to achieve Master Password verification, and share details of script development.
0x01 Introduction
---
This article will cover the following topics:
- Introduction to Network Security Services
- Exporting Firefox browser passwords via Python calls to Network Security Services
- Open-source Python scripts
- Implementation of brute-force scripts
0x02 Introduction to Network Security Services
---
Network Security Services (NSS) is a set of libraries designed to support cross-platform development of secure client and server applications.
Reference documentation:
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS
The Firefox browser uses NSS as the foundational library for encryption algorithms and secure network protocols, employing the PKCS#11 standard for credential encryption and decryption.
Reference documentation:
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/PKCS11
0x03 Exporting passwords from the Firefox browser by calling Network Security Services via Python
---
Reference code:
https://github.com/unode/firefox_decrypt
https://github.com/Kerisa/BrowserPasswordDump/blob/master/MozillaPwd.py
The decryption process on Windows systems is as follows:
- Load the nss3.dll required by Network Security Services
- Call NSS_Init() for initialization
- Call PK11_GetInternalKeySlot() to obtain the internal slot (used for verifying the Master Password)
- Call PK11_CheckUserPassword() to verify the Master Password
- Read logins.json to obtain encrypted data
- Call PK11SDR_Decrypt() for decryption
Specific issues to note are as follows:
1. Python and Firefox versions must be consistent
On 64-bit systems, both must be either 32-bit or 64-bit
2. Add Firefox installation path to environment variables for easy invocation
The Firefox installation directory contains the nss3.dll we need to call, so you can add the Firefox installation path to the PATH environment variable. The corresponding Python code is:
import os |
Note:
On 64-bit operating systems, the default installation directory for 64-bit Firefox is C:\Program Files\Mozilla Firefox, and for 32-bit Firefox it is C:\Program Files (x86)\Mozilla Firefox
The Python code to call nss3.dll is:
import ctypes |
3. NSS initialization requires three files
The specific location is: %APPDATA%\Mozilla\Firefox\Profiles\xxxxxxxx.default\
The following three files are required:
- cert9.db
- key4.db
- logins.json
The above three files can be saved in the same folder, for example, c:\test\data
The code for NSS initialization is as follows:
profilePath = "C:\\test\\data" |
4. Read logins.json to obtain encrypted data
The encryptedUsername and encryptedPassword entries are encrypted data and need to be decrypted using NSS
Before decryption, base64 decoding is required first, then call PK11SDR_Decrypt() to decrypt and obtain the plaintext
The timeCreated, timeLastUsed, and timePasswordChanged entries are in Epoch Time format (total seconds from 00:00:00 on January 1, 1970, Coordinated Universal Time to the present, excluding leap seconds), which can be converted to actual time via the following website:
https://esqsoft.com/javascript_examples/date-to-epoch.htm
The Python code for converting the time format is as follows:
from datetime import datetime |
Note:
Different versions of Firefox save records in different file names, with specific differences as follows:
- Version greater than or equal to 32.0, the file for saving records is logins.json
- Version greater than or equal to 3.5, less than 32.0, the file for saving records is signons.sqlite
For more detailed file descriptions, refer to:
http://kb.mozillazine.org/Profile_folder_-_Firefox |
0x04 Open-source Python Script
---
Reference code:
https://github.com/unode/firefox_decrypt
https://github.com/Kerisa/BrowserPasswordDump/blob/master/MozillaPwd.py
My test code has been uploaded to GitHub, the address is as follows:
An open-source project
Test environment:
- 64-bit Windows operating system with 64-bit Firefox browser installed
- The default installation path for Firefox is "C:\Program Files\Mozilla Firefox"
- The profile path is "C:\\Users\\a\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\2yi8qmhz.default-beta", including the following three files:
- cert9.db
- key4.db
- logins.json
The code supports two functions:
1. Verify Master Password
Corresponding sub-function checkMasterPassword(MasterPassword)
If the MasterPassword is correct, display the correct MasterPassword and return TRUE
If the MasterPassword is incorrect, return FALSE
This can be used to implement brute-force attacks on the Master Password
2. Export saved passwords from Firefox browser
Corresponding sub-function ExportData(MasterPassword)
If no Master Password is set, set the MasterPassword parameter to ""
If a Master Password is set, the correct Master Password must be entered to decrypt and obtain the actual data
Specifically, the following information can be exported:
- url
- username
- password
- timeCreated
- timePasswordChanged
- timeLastUsed
0x05 Summary
---
This article introduces the method of exporting Firefox browser passwords by calling Network Security Services via Python, sharing script development details.