用C#破解Chrome浏览器cookie值

Posted .NET100

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用C#破解Chrome浏览器cookie值相关的知识,希望对你有一定的参考价值。

背景

最近小编接到一个获取网站请求数据的需求,要求抓取网站某个页面请求的数据。我使用Google Chrome浏览器查看了一下请求链接的传入参数,发现需要传入一个Token值才能获取数据。于是我在Chrome中登录后,通过Postman请求成功,并将Token存储到了Cookie中。然而问题又来了,在代码层面如何获取这个Token呢?

解决方案

小编在网上查了一圈,发现Chrome浏览器的Cookie存储在本地的sqlite数据库中。在Chrome的安装目录中找到了sqlite的文件,通过读取sqlite数据库即可获得了Cookie值。如下图:

其中name是cookie的名称, encrypted_value字段是加密的cookie值,host_key就是站点域名了。但是这个Cookie值是加密的。

存储cookie目录:

C:\\Users\\用户名\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Network\\Cookies

各个版本的目录可能不同,有的在Local State文件夹下。

小编继续搜索,发现Chrome浏览器是开源的,算法是公开的,用到的加密算法是aes加密算法。我们不需要知道这个算法,只需要知道此算法需要一个秘钥,通过这个秘钥就可以进行加密和解密,代码如下。

实现代码

关键代码如下:

  using (SqliteConnection connection = new SqliteConnection())
            
                //1、获取google Chrome浏览器目录
                var userprofilePath = Environment.GetEnvironmentVariable("USERPROFILE");
                 var sourceFile= $@"userprofilePath\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Network\\Cookies"; 
                //var sourceFile = $@"userprofilePath\\Desktop\\11111111.txt";
                var targetFile = $@"Directory.GetCurrentDirectory()\\GoogleFile\\Cookies";

                //2、拷贝文件到本地目录,防止文件被占用
                FileInfo file = new FileInfo(sourceFile);
                if(!Directory.Exists($@"Directory.GetCurrentDirectory()\\GoogleFile"))
                    Directory.CreateDirectory($@"Directory.GetCurrentDirectory()\\GoogleFile");
                if (file.Exists)
                
                    file.CopyTo(targetFile, true);
                

                //3、链接sqlite数据库
                connection.ConnectionString = $@"DataSource="+ targetFile;
                 connection.Open();
                //4、通过select查询相关的语句
                SqliteCommand command = new SqliteCommand("select host_key,name,encrypted_value from cookies where name=\'public-token\' and host_key=\'.cponline.cnipa.gov.cn\'", connection);
                SqliteDataReader dataReader = command.ExecuteReader();
                dataReader.Read();
                byte[] encryptedValue = (byte[])dataReader["encrypted_value"];

                //5、解密数据
                int keyLength = 256 / 8;
                int nonceLength = 96 / 8;
                String kEncryptionVersionPrefix = "v10";
                int GCM_TAG_LENGTH = 16;
                //字符串内容取自C:\\Users\\用户名\\AppData\\Local\\Google\\Chrome\\User Data\\Local State文件的encrypted_key
                byte[] encryptedKeyBytes = Convert.FromBase64String("RFBBUEkBAAAA0Iyd3wEV0RGMegDAT8KX6wEAAACVAmSA/y7+TLs+3WWdDv1ZAAAAAAIAAAAAABBmAAAAAQAAIAAAABV7dDMB8p+vKnLEjnrhnWB4DAbB/k5XAtjWGFnci/3qAAAAAA6AAAAAAgAAIAAAAH/pnc+fF6dhG8Fpw6yQezIXtMw48xNvuyRub/cZ62XaMAAAAP1pl5QqRJmd1J4V++dhE63MEA9F4NzCHb1aOMgTnFCo1+xSHYovSTzCoYFvoDfIFUAAAAAZzDzWwwpUm6yZG9tpYu/ioRSO8V16MetQy2s7L9HHO03Q6bO8Nr05Erl1QbjCVoSgSOU4krcerUsngMwIYFyb");
                encryptedKeyBytes = encryptedKeyBytes.Skip("DPAPI".Length).Take(encryptedKeyBytes.Length - "DPAPI".Length).ToArray();
                var keyBytes = System.Security.Cryptography.ProtectedData.Unprotect(encryptedKeyBytes, null, System.Security.Cryptography.DataProtectionScope.CurrentUser);
                var nonce = encryptedValue.Skip(kEncryptionVersionPrefix.Length).Take(nonceLength).ToArray();
                encryptedValue = encryptedValue.Skip(kEncryptionVersionPrefix.Length + nonceLength).Take(encryptedValue.Length - (kEncryptionVersionPrefix.Length + nonceLength)).ToArray();
                var str = System.Web.HttpUtility.UrlDecode(AesGcmDecrypt(keyBytes, nonce, encryptedValue));

                //6、获得值
                Console.WriteLine($"dataReader["host_key"]-dataReader["name"]-str");
                //7、关闭数据
                connection.Close();
            

以上代码列出了解密步骤,大家可以根据自己的项目情况调整。

AesGcmDecrypt解密的方法:

        public static string AesGcmDecrypt(byte[] keyBytes, byte[] nonce, byte[] encryptedValue)
        
            GcmBlockCipher gcmBlockCipher = new GcmBlockCipher(new AesEngine());
            AeadParameters aeadParameters = new AeadParameters(
                new KeyParameter(keyBytes),
                128,
                nonce);
            gcmBlockCipher.Init(false, aeadParameters);
            byte[] plaintext = new byte[gcmBlockCipher.GetOutputSize(encryptedValue.Length)];
            int length = gcmBlockCipher.ProcessBytes(encryptedValue, 0, encryptedValue.Length, plaintext, 0);
            gcmBlockCipher.DoFinal(plaintext, length);
            return Encoding.UTF8.GetString(plaintext);
        

注:本案例.NET项目使用的是.NET6,Chrome浏览器版本是v110。

Chrome开源地址:chromium.googlesource.com/chromium/src

解密加密地址:

https://cs.chromium.org/chromium/src/components/os_crypt/os_crypt_win.cc?q=OSCrypt&dr=CSs

输出str效果:

结语

本文介绍了用C#读取Chrome浏览器cookie值的方法,并用代码实现了功能,大家可以根据自己项目的情况使用。本案例涉及到隐私问题,建议不要用本案例做违规的操作。希望本文对你有所帮助,同时欢迎留言或吐槽。

来源公众号:DotNet开发跳槽

cookie,localStorage和SessionStorage

参考技术A

cookie就是通过浏览器在同域下交互的数据。
在chrome中,查看cookie的方法:打开控制台,Resources -> cookies。

语法:

如果只设置value值,那么在设置的时候,后面会把前面的覆盖。
如果有多个相同的key值即设置了key也设置了value值,这个时候,后面会把前面的覆盖。
cookie一般用于在浏览器中缓存数据用。

cookie的大小是有限制的 ,每个浏览器支持的都不一样,有的50条,有个20条..

默认的cookie的声明周期,当浏览器关闭之后,这个cookie的生命周期结束。这条cookie就会被删除。

设置cookie的生命周期

用上面的方式可以为这条cookie添加N天的生命周期

如果需要删除一条cookie,那么就设置他的生命周期比当前时间还小,那么就会被删除了。

cookie是即可读也可以写入的

在读取的时候,如果当前页面有多个cookie那么,是由;+空格链接的。

如果需要分割,那么使用 ; 作为分割符进行分割。

localstorag是HTML5的数据存储的新API,是一个没有时间限制的数据存储。在这之前,这些都是由 cookie 完成的。但是 cookie 不适合大量数据的存储,因为它们由每个对服务器的请求来传递,这使得 cookie 速度很慢而且效率也不高。
在 HTML5 中,数据不是由每个服务器请求传递的,而是只有在请求时使用数据。它使在不影响网站性能的情况下存储大量数据成为可能。
对于不同的网站,数据存储于不同的区域,并且一个网站只能访问其自身的数据。

localstorage大小一般限制在 5MB 左右,各个浏览器不同,以后或许还会增加
cookie 的大小只有 4KB

浏览器支持情况:
理论上支持IE8以上和标准浏览器。

虽然这个API是html5新添加的,但是在IE的仿真功能中测试的时候,即使是IE5都可以使用。

在标准浏览器中,可以在本地查看 localstorage
IE浏览器必须使用localhost查看

生命周期:
localstorage如果不删除就会一直存在

参数:
key:key值
value:value值
其中,value不能放入对象,如果放入数组会使用 , 将它链接字符串。
如果需要放入对象,需要使用JSON.stringify来转换成json格式在放入

参数:
key:key值
获取到的value都是一个字符串。
如果需要使用json格式的内容,那么就使用JSON.parse把它转化为对象

删除一条名字为key的localstorage信息。

删除所有的localstorage信息。

当操作了本地存储的数据的时候,会触发 storage 这个事件,这个事件不会在操作的页面上触发,只会在同浏览器的同源页面上触发(这两个页面都需要storage事件)。这相当与,可以在同浏览器的同源页面上监听当前页面的操作。

在 storage 对象下,有一些可以直接使用的属性,例如: ldValue , newValue , key 等等

注意:
storage 对象只能在localhost环境下才能进行监听

以上是关于用C#破解Chrome浏览器cookie值的主要内容,如果未能解决你的问题,请参考以下文章

chrome浏览器怎样设置才能支持cookies

自己用javascript设定cookie,可是为啥在chrome浏览器下却是无效的!

C#中操作单个cookie和cookie字典

简谈-Python爬虫破解JS加密的Cookie

如何在 Selenium 中使用 Chrome 查看 Flash cookie

cookie,localStorage和SessionStorage