Exporting saved passwords from Firefox browser via Network Security Services

Onedaysec
4 min read
2 views
Exporting saved passwords from Firefox browser via Network Security Services — One Day Sec default thumbnail

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:

  1. Load the nss3.dll required by Network Security Services
  2. Call NSS_Init() for initialization
  3. Call PK11_GetInternalKeySlot() to obtain the internal slot (used for verifying the Master Password)
  4. Call PK11_CheckUserPassword() to verify the Master Password
  5. Read logins.json to obtain encrypted data
  6. 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
firefoxPath = "C:\Program Files\Mozilla Firefox"
os.environ["PATH"] = ';'.join([firefoxPath, os.environ["PATH"]])

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
NssDll = ctypes.CDLL("nss3.dll")

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"
NssDll.NSS_Init(profilePath)

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
def timestamp_to_strtime(timestamp):
return datetime.fromtimestamp(timestamp / 1000.0).strftime('%Y-%m-%d %H:%M:%S')
print timestamp_to_strtime(1580901797579)

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.

Related Questions & Answers

How do you ensure compatibility between Python and Firefox when using NSS to export passwords?

Both Python and Firefox must have matching bitness (both 32-bit or both 64-bit). Additionally, the Firefox installation path (containing nss3.dll) should be added to the system's PATH environment variable to allow Python to load the DLL via `ctypes.CDLL`

What files are required for NSS initialization when exporting Firefox passwords, and how do they differ across Firefox versions?

NSS initialization requires three files: `cert9.db`, `key4.db`, and `logins.json`, all located in the Firefox profile folder (e.g., `%APPDATA%\Mozilla\Firefox\Profiles\xxxxxxxx.default`). For Firefox versions 32.0 and above, login data is stored in `logins.json`; for versions 3.5 to 32.0, the file is `signons.sqlite`. The article notes that the Python code sets the profile path and calls `NSS_Init(profilePath)` using these files.

How does the script verify the Firefox Master Password, and what can it be used for?

The script includes a `checkMasterPassword()` function that calls `PK11_CheckUserPassword()`. If the provided password is correct, it returns TRUE and prints the valid Master Password; otherwise it returns FALSE. This allows for brute-force attacks on the Master Password, similar to techniques used in [Penetration Techniques - Exporting Saved Passwords from Firefox Browser](/news/penetration-techniques-exporting-saved-passwords-from-firefox-browser). For an analogous approach with Chrome, see [Penetration Techniques - Offline Export of Passwords Saved in Chrome Browser](/news/penetration-techniques-offline-export-of-passwords-saved-in-chrome-browser).

What are the key steps to export Firefox passwords using Python and NSS?

The process involves: loading the nss3.dll via Python's ctypes, calling `NSS_Init()` to initialize NSS with the profile path containing cert9.db, key4.db, and logins.json, obtaining the internal key slot with `PK11_GetInternalKeySlot()`, verifying the Master Password using `PK11_CheckUserPassword()`, reading encrypted data from logins.json, base64-decoding it, and finally calling `PK11SDR_Decrypt()` to retrieve plaintext credentials. The full implementation is demonstrated in the open-source test code linked in the article.

What is Network Security Services (NSS) and how does Firefox use it for password management?

Network Security Services (NSS) is a set of libraries for cross-platform secure client/server applications. Firefox uses NSS as its foundational library for encryption algorithms and secure network protocols, employing the PKCS#11 standard for credential encryption and decryption. As detailed in the article, NSS is leveraged to export saved passwords via Python by calling nss3.dll and using functions like `PK11_CheckUserPassword()` and `PK11SDR_Decrypt()`. For a deeper dive into the penetration technique, see [Penetration Techniques - Exporting Saved Passwords from Firefox Browser](/news/penetration-techniques-exporting-saved-passwords-from-firefox-browser).

Continue Reading