本帖最后由 杀鸡的骚年 于 2024-4-2 17:55 编辑
更新 2024-04-02
新版的 Chrome 浏览器,在浏览器运行时会锁定 cookies 数据库。
v0.0.2 版本只有关闭浏览器后,运行 gcookie 不会报错。
最新版本 v0.0.4,可以使用管理员权限运行。
处理方法是参考这里: https://github.com/ColinFinck/ntfs/blob/master/examples/ntfs-shell/main.rs#L34
以及这里: https://github.com/pkptzx/rawcopy-rs/blob/master/src/lib.rs rawcopy 这个项目基本大部分的代码也是使用的 ColinFinck/ntfs 的例子。
对于在 Rust 里面检测管理权限的思路是参考的这里: https://users.rust-lang.org/t/how-do-i-determine-if-i-have-admin-rights-on-windows/35710/3
不过我使用的是微软官方的 windows-rs 这个库。核心代码贴在的下面
[C] 纯文本查看 复制代码 fn is_elevated() -> bool {
let mut result = false;
let mut handle: HANDLE = HANDLE(0);
unsafe {
if OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &mut handle).is_ok() {
let elevation = TOKEN_ELEVATION::default();
let size = std::mem::size_of::<TOKEN_ELEVATION>() as u32;
let mut ret_size = size;
let raw_ptr = &elevation as *const _ as *mut c_void;
if GetTokenInformation(
handle,
TokenElevation.into(),
Some(raw_ptr),
size,
&mut ret_size,
)
.is_ok()
{
result = elevation.TokenIsElevated != 0;
}
}
let _ = CloseHandle(handle);
}
result
}
平时写小工具的时候,有些网站需要cookie。平常都是 F12 查看 HTTP 报文,手动复制 header 里面的 cookie。
有些网站关了浏览器就会丢登录信息,每次复制有点繁琐。所以自己写了命令行工具读取 cookie。
项目地址: https://github.com/zhifengle/gcookie
下载:https://github.com/zhifengle/gcookie/releases
注意:支持的 Chrome 系浏览器 80以上的版本。
注意2:你想拿 "52pojie.cn" 的 cookie 时,需要输入 gcookie "52pojie.cn"。gcookie "https://www.52pojie.cn/" 是拿的 www.52pojie.cn 的 cookie
使用方法也很简单比如需要读取 52pojie 的 cookie
[Shell] 纯文本查看 复制代码 gcookie "https://www.52pojie.cn/"
# 或者
gcookie "www.52pojie.cn"
# 支持Windows下面的 Chrome Edge Chromium
# 读取 Edge 的 cookie
gcookie -c Edge "bing.com"
# 火狐浏览器需要指定配置路径
gcookie -f /path/to/profiles/xx.p "bing.com"
# 帮助
gcookie -h
在其它语言调用读取标准输出流就可以了。
这是 Python 的调用例子
[Python] 纯文本查看 复制代码 from subprocess import check_output
site = 'bing.com'
cookie = check_output(['gcookie', '-c', 'Edge', site]).decode("utf-8")
这是 Nodejs 的调用例子
[JavaScript] 纯文本查看 复制代码 const { execSync } = require('child_process');
let site = 'bing.com';
const cookie = execSync(`gcookie ${site}`).toString();
其实网上也有类似的工具比如这个 https://github.com/moonD4rk/HackBrowserData
这是用 golang 写的,能够导出所有的浏览器数据。我这个工具的逻辑就是参考的它。
本着学习的目的,用 Rust 实现了一下。
参考的 Windows 的 API 文档:https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectdata
用到了 Windows API CryptUnprotectData。
核心解密是创建两个 CRYPTOAPI_BLOB。 一个用来输入和一个用来输出 https://github.com/22earth/gcookie/blob/0a72b7fbe578cf162e047898face20418556a7f8/src/browser/windows.rs#L92
[C] 纯文本查看 复制代码 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.pbData as isize);
LocalFree(blob_out.pbData as isize);
Ok(slice.to_vec())
}
注意解密后,需要释放内存 LocalFree(blob_out.pbData as isize),不然内存泄漏会导致偶发性的解密失败.
因为前面在 unsafe 里面调用了 std::slice::from_raw_parts(blob_out.pbData, blob_out.cbData as usize); 这个内存 Rust 已经无法自动处理。
因为 Rust 的生命周期管理, blob.pbData 是 Rust 自动释放的,所以不需要手动释放。
核心思路是需要参考 Chrome 的加密方式进行解密。需要查阅 chromium 源码
然后调用 SQLite 查询数据,然后生成 cookie 字符串。 |