Tag Archives: crypto

Reveal saved Mozilla Firefox passwords

Firefox stores website, user name and password information in encrypted form in the logins.json file located in ~/mozilla/firefox/*.default directory. This is how passwords can be revealed (assuming you know the password) quickly on command line if no Firefox happens to be around.

Pretty printed using jq (a handy Swiss knife of json), logins.json file looks like this:

% jq . < logins.json
 "version": 1,
 "nextId": 2,
 "logins": [
     "id": 1,
     "hostname": "http://acme.dot.com",
     "httpRealm": null,
     "formSubmitURL": "http://acme.dot.com",
     "usernameField": "username",
     "passwordField": "password",
     "encryptedPassword": "MDoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECHw9Rnls6h9IBBCjpngvOZX25Hbpvmne2qEr",
     "guid": "{e611000f-e3a3-49cb-b24e-c3c1f898398b}",
     "encType": 1,
     "timeCreated": 1479141437109,
     "timeLastUsed": 1479141437109,
     "timePasswordChanged": 1479141437109,
     "timesUsed": 1
 "disabledHosts": []

The entries encryptedUsername and encryptedPassword are encrypted with keys in cert8.db and key3.db (both are encrypted Sqlite database files). Dealing with encrypted sqlite db on shell is sort of challenging, but fortunately there is an utility pwdecrypt (from libnss3-tools Debian package). It will dig out the keys from those db-files and decrypt encrypted lines, other lines are output in verbatim.

Relevant attributes should be extracted first from the json with jq

% jq -r -S '.logins[] | .hostname, .encryptedUsername, .encryptedPassword' logins.json

then each line can be fed to pwdecrypt (-d gives the directory where db-files are located). If passwords are stored with master password, that should be given with -p (here master password is foobar):

% jq -r -S '.logins[] | .hostname, .encryptedUsername, .encryptedPassword' logins.json | pwdecrypt -d . -p foobar
Decrypted: "JoeLoser"
Decrypted: "verysekret"

With little more shell around whole file can be decrypted and printed out in clear text:

% jq -r -S '.logins[] | .hostname, .encryptedUsername, .encryptedPassword' logins.json |
 pwdecrypt -d . -p foobar |
 while read H && read U && read P ; do
   printf "%40s %20s %s\n" "$H" "${${U#Decrypted: \"}:0:-1}" "${${P#Decrypted: \"}:0:-1}"
                     http://acme.dot.com             JoeLoser verysekret

If you get a cryptic error message from like

pwdecrypt: NSS_Init failed: SEC_ERROR_LEGACY_DATABASE: The certificate/key database is in an old, unsupported format.

Then change all occurrences of option -d . to -d sql:. (note the dot at the end) in pwdecrypt command, i.e. as to

pwdecrypt -d sql:. -p foobar