翼度科技»论坛 编程开发 .net 查看内容

用C#破解Chrome浏览器cookie值

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
背景
最近小编接到一个获取网站请求数据的需求,要求抓取网站某个页面请求的数据。我使用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加密算法。我们不需要知道这个算法,只需要知道此算法需要一个秘钥,通过这个秘钥就可以进行加密和解密,代码如下。
实现代码
关键代码如下:
  1.   using (SqliteConnection connection = new SqliteConnection())
  2.             {
  3.                 //1、获取google Chrome浏览器目录
  4.                 var userprofilePath = Environment.GetEnvironmentVariable("USERPROFILE");
  5.                  var sourceFile= $@"{userprofilePath}\AppData\Local\Google\Chrome\User Data\Default\Network\Cookies";
  6.                 //var sourceFile = $@"{userprofilePath}\Desktop\11111111.txt";
  7.                 var targetFile = $@"{Directory.GetCurrentDirectory()}\GoogleFile\Cookies";
  8.                 //2、拷贝文件到本地目录,防止文件被占用
  9.                 FileInfo file = new FileInfo(sourceFile);
  10.                 if(!Directory.Exists($@"{Directory.GetCurrentDirectory()}\GoogleFile"))
  11.                     Directory.CreateDirectory($@"{Directory.GetCurrentDirectory()}\GoogleFile");
  12.                 if (file.Exists)
  13.                 {
  14.                     file.CopyTo(targetFile, true);
  15.                 }
  16.                 //3、链接sqlite数据库
  17.                 connection.ConnectionString = $@"DataSource="+ targetFile;
  18.                  connection.Open();
  19.                 //4、通过select查询相关的语句
  20.                 SqliteCommand command = new SqliteCommand("select host_key,name,encrypted_value from cookies where name='public-token' and host_key='.cponline.cnipa.gov.cn'", connection);
  21.                 SqliteDataReader dataReader = command.ExecuteReader();
  22.                 dataReader.Read();
  23.                 byte[] encryptedValue = (byte[])dataReader["encrypted_value"];
  24.                 //5、解密数据
  25.                 int keyLength = 256 / 8;
  26.                 int nonceLength = 96 / 8;
  27.                 String kEncryptionVersionPrefix = "v10";
  28.                 int GCM_TAG_LENGTH = 16;
  29.                 //字符串内容取自C:\Users\用户名\AppData\Local\Google\Chrome\User Data\Local State文件的encrypted_key
  30.                 byte[] encryptedKeyBytes = Convert.FromBase64String("RFBBUEkBAAAA0Iyd3wEV0RGMegDAT8KX6wEAAACVAmSA/y7+TLs+3WWdDv1ZAAAAAAIAAAAAABBmAAAAAQAAIAAAABV7dDMB8p+vKnLEjnrhnWB4DAbB/k5XAtjWGFnci/3qAAAAAA6AAAAAAgAAIAAAAH/pnc+fF6dhG8Fpw6yQezIXtMw48xNvuyRub/cZ62XaMAAAAP1pl5QqRJmd1J4V++dhE63MEA9F4NzCHb1aOMgTnFCo1+xSHYovSTzCoYFvoDfIFUAAAAAZzDzWwwpUm6yZG9tpYu/ioRSO8V16MetQy2s7L9HHO03Q6bO8Nr05Erl1QbjCVoSgSOU4krcerUsngMwIYFyb");
  31.                 encryptedKeyBytes = encryptedKeyBytes.Skip("DPAPI".Length).Take(encryptedKeyBytes.Length - "DPAPI".Length).ToArray();
  32.                 var keyBytes = System.Security.Cryptography.ProtectedData.Unprotect(encryptedKeyBytes, null, System.Security.Cryptography.DataProtectionScope.CurrentUser);
  33.                 var nonce = encryptedValue.Skip(kEncryptionVersionPrefix.Length).Take(nonceLength).ToArray();
  34.                 encryptedValue = encryptedValue.Skip(kEncryptionVersionPrefix.Length + nonceLength).Take(encryptedValue.Length - (kEncryptionVersionPrefix.Length + nonceLength)).ToArray();
  35.                 var str = System.Web.HttpUtility.UrlDecode(AesGcmDecrypt(keyBytes, nonce, encryptedValue));
  36.                 //6、获得值
  37.                 Console.WriteLine($"{dataReader["host_key"]}-{dataReader["name"]}-{str}");
  38.                 //7、关闭数据
  39.                 connection.Close();
  40.             }
复制代码
以上代码列出了解密步骤,大家可以根据自己的项目情况调整。
AesGcmDecrypt解密的方法:
  1.         public static string AesGcmDecrypt(byte[] keyBytes, byte[] nonce, byte[] encryptedValue)
  2.         {
  3.             GcmBlockCipher gcmBlockCipher = new GcmBlockCipher(new AesEngine());
  4.             AeadParameters aeadParameters = new AeadParameters(
  5.                 new KeyParameter(keyBytes),
  6.                 128,
  7.                 nonce);
  8.             gcmBlockCipher.Init(false, aeadParameters);
  9.             byte[] plaintext = new byte[gcmBlockCipher.GetOutputSize(encryptedValue.Length)];
  10.             int length = gcmBlockCipher.ProcessBytes(encryptedValue, 0, encryptedValue.Length, plaintext, 0);
  11.             gcmBlockCipher.DoFinal(plaintext, length);
  12.             return Encoding.UTF8.GetString(plaintext);
  13.         }
复制代码
注:本案例.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值的方法,并用代码实现了功能,大家可以根据自己项目的情况使用。本案例涉及到隐私问题,建议不要用本案例做违规的操作。希望本文对你有所帮助,同时欢迎留言或吐槽。
  1. 来源公众号:DotNet开发跳槽
复制代码
来源:https://www.cnblogs.com/xbhp/archive/2023/04/18/17329162.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具