杀鸡的骚年 发表于 2022-7-22 22:49

【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 字符串。

xiaohuohuo 发表于 2023-10-7 11:52

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


求助

杀鸡的骚年 发表于 2022-7-23 08:53

lammysoft 发表于 2022-7-23 07:52
F12然后document.cookie不好了吗。。。

看需求和用途。document.cookie 是需要打开浏览器的。其次httponly 的 cookie 是不能通过 document.cookie 读取。

再者,有高级的需求的人,可能用到无头浏览器,所以也不需要我的这个工具。

简单的需求,不需要安装使用比较大的 headerless browser. 就可以使用这个工具

lammysoft 发表于 2022-7-23 07:52

F12然后document.cookie不好了吗。。。

unnyfan 发表于 2022-7-23 09:31

正在看rust,去了解下,感谢楼主

zhangsan2022 发表于 2022-7-23 11:06

多谢楼主,热心分享,点赞。

laris 发表于 2022-8-23 08:46

Rust写命令行小公举,是利器啊
正在学习中

askwind 发表于 2022-10-6 18:46

测试了下,不能获取B站的cookie

angelo7930 发表于 2022-10-8 04:14

不会用啊

杀鸡的骚年 发表于 2022-10-13 21:57

askwind 发表于 2022-10-6 18:46
测试了下,不能获取B站的cookie

你需要使用host.   gcookie.exe "bilibili.com"

gcookie "https://www.bilibili.com/"拿到的是 www.bilibili.com 域名

杀鸡的骚年 发表于 2022-10-13 21:59

angelo7930 发表于 2022-10-8 04:14
不会用啊

命令行运行的。加上exe 文件在当前目录,Windows下面的 cmd 。.\gcookie.exe "bilibili.com"
页: [1] 2 3
查看完整版本: 【Rust】读取浏览器Cookie的命令行工具