【Rust】读取浏览器Cookie的命令行工具
本帖最后由 杀鸡的骚年 于 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 这个库。核心代码贴在的下面
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
gcookie "https://www.52pojie.cn/"
# 或者
gcookie"www.52pojie.cn"
# 支持Windows下面的 Chrome EdgeChromium
# 读取 Edge 的 cookie
gcookie -c Edge "bing.com"
# 火狐浏览器需要指定配置路径
gcookie -f /path/to/profiles/xx.p "bing.com"
# 帮助
gcookie -h
在其它语言调用读取标准输出流就可以了。
这是 Python 的调用例子
from subprocess import check_output
site = 'bing.com'
cookie = check_output(['gcookie', '-c', 'Edge', site]).decode("utf-8")
这是 Nodejs 的调用例子
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 APICryptUnprotectData。
核心解密是创建两个 CRYPTOAPI_BLOB。 一个用来输入和一个用来输出 https://github.com/22earth/gcookie/blob/0a72b7fbe578cf162e047898face20418556a7f8/src/browser/windows.rs#L92
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 字符串。 error: failed to resolve: could not find `Chromium` in `browser`
--> src/lib.rs:39:32
|
39 | Some(path) => browser::Chromium::new(PathBuf::from(path)),
| ^^^^^^^^ could not find `Chromium` in `browser`
For more information about this error, try `rustc --explain E0433`.
error: could not compile `gcookie` (lib) due to previous error
求助 lammysoft 发表于 2022-7-23 07:52
F12然后document.cookie不好了吗。。。
看需求和用途。document.cookie 是需要打开浏览器的。其次httponly 的 cookie 是不能通过 document.cookie 读取。
再者,有高级的需求的人,可能用到无头浏览器,所以也不需要我的这个工具。
简单的需求,不需要安装使用比较大的 headerless browser. 就可以使用这个工具 F12然后document.cookie不好了吗。。。 正在看rust,去了解下,感谢楼主 多谢楼主,热心分享,点赞。 Rust写命令行小公举,是利器啊
正在学习中 测试了下,不能获取B站的cookie 不会用啊 askwind 发表于 2022-10-6 18:46
测试了下,不能获取B站的cookie
你需要使用host. gcookie.exe "bilibili.com"
gcookie "https://www.bilibili.com/"拿到的是 www.bilibili.com 域名 angelo7930 发表于 2022-10-8 04:14
不会用啊
命令行运行的。加上exe 文件在当前目录,Windows下面的 cmd 。.\gcookie.exe "bilibili.com"