BLOG

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

F5 Miniaturansicht
F5
Veröffentlicht am 17. September 2018


Bei Shape stoßen wir auf viele skizzenhafte Teile von JavaScript. Wir finden Skripte, die in böswilliger Absicht in Seiten eingeschleust wurden. Diese könnten von einem Kunden mit der Bitte um Rat gesendet worden sein, oder unsere Sicherheitsteams könnten im Internet auf eine Ressource stoßen, die sich scheinbar speziell auf bestimmte Aspekte unseres Dienstes bezieht. Es gehört zu unserer täglichen Routine, dass wir uns intensiv mit den Skripten befassen, um zu verstehen, was sie tun und wie sie funktionieren. Sie sind normalerweise minimiert, oft verschleiert und erfordern immer mehrere Änderungsebenen, bevor sie wirklich für eine gründliche Analyse bereit sind.

Bis vor Kurzem bestand die einfachste Möglichkeit für diese Analyse darin, entweder lokal zwischengespeicherte Setups zu verwenden, die manuelle Bearbeitungen ermöglichen, oder Proxys zu verwenden, um Inhalte im laufenden Betrieb neu zu schreiben. Die lokale Lösung ist die bequemste, aber Websites lassen sich nicht immer perfekt in andere Umgebungen übertragen und die Benutzer stürzen sich oft in eine lange Liste von Fehlerbehebungen, nur um produktiv zu werden. Proxys sind äußerst flexibel, aber normalerweise umständlich und nicht sehr portabel – jeder hat seine eigene benutzerdefinierte Konfiguration für seine Umgebung und manche Leute sind mit einem Proxy besser vertraut als mit einem anderen. Ich habe begonnen, Chrome und sein Devtools-Protokoll zu verwenden, um in Anfragen und Antworten einzusteigen, während sie auftreten, und sie im laufenden Betrieb zu ändern. Dies ist auf jede Plattform portierbar, auf der Chrome installiert ist, umgeht eine ganze Reihe von Problemen und lässt sich gut in gängige JavaScript-Tools integrieren. In diesem Beitrag erkläre ich, wie man mit dem Devtools-Protokoll von Chrome JavaScript im laufenden Betrieb abfängt und ändert.

Wir verwenden Node, aber ein Großteil des Inhalts lässt sich in die Sprache Ihrer Wahl portieren, vorausgesetzt, Sie haben einfachen Zugriff auf die Devtools-Hooks.

Wenn Sie sich noch nie mit der Skripterstellung für Chrome beschäftigt haben, sollten Sie zunächst wissen, dass Eric Bidelman eine hervorragende Anleitung für die ersten Schritte mit Headless Chrome geschrieben hat. Die dort aufgeführten Tipps gelten sowohl für Headless als auch für GUI Chrome (mit einer Eigenart, auf die ich im nächsten Abschnitt eingehen werde).

Chrome starten

Um dies zu vereinfachen, verwenden wir die Chrome-Launcher -Bibliothek von npm.

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Chrome-Launcher macht genau das, was Sie erwarten, und Sie können dieselben Befehlszeilenschalter, die Sie vom Terminal gewohnt sind, unverändert übergeben (eine ausführliche Liste wird hier gepflegt ). Wir übergeben die folgenden Optionen:

–Fenstergröße=1200,800

  • Stellen Sie die Fenstergröße automatisch auf einen sinnvollen Wert ein.

–auto-open-devtools-for-tabs

  • Öffnen Sie die Devtools automatisch, da wir sie häufig verwenden.

–user-data-dir=/tmp/chrome-testing

  • Legen Sie ein konstantes Benutzerdatenverzeichnis fest. (Idealerweise würden wir dies nicht benötigen, aber der Nicht-Headless-Modus unter Mac OSX scheint das Abfangen von Anfragen ohne dieses Flag nicht zuzulassen. Wenn Sie einen besseren Weg kennen, lassen Sie es mich bitte über Twitter wissen!)
Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Versuchen Sie, Ihr Skript auszuführen, um sicherzustellen, dass Sie Chrome öffnen können. Sie sollten ungefähr Folgendes sehen:

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Verwenden des Chrome Devtools-Protokolls

Dies wird auch als „Chrome-Debugger-Protokoll“ bezeichnet und beide Begriffe scheinen in den Dokumenten von Google synonym verwendet zu werden. Installieren Sie zunächst das Paket „chrome-remote-interface“ über npm, das uns praktische Methoden zur Interaktion mit dem Devtools-Protokoll bietet. Halten Sie die Protokolldokumente bereit, wenn Sie tiefer in die Materie eintauchen möchten.

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Um das CDP zu verwenden, müssen Sie eine Verbindung zum Debugger-Port herstellen. Da wir die Chrome-Launcher -Bibliothek verwenden, ist dieser bequem über chrome.port zugänglich.

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Viele der Domänen im Protokoll müssen zuerst aktiviert werden. Wir beginnen mit der Runtime- Domäne, damit wir uns in die Konsolen-API einklinken und alle Konsolenaufrufe im Browser an die Befehlszeile weiterleiten können.

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Wenn Sie Ihr Skript jetzt ausführen, erhalten Sie ein voll funktionsfähiges Chrome-Fenster, das auch alle seine Konsolenmeldungen an Ihr Terminal ausgibt. Das ist an sich schon großartig, insbesondere für Testzwecke!

Abfangen von Anfragen

Zuerst müssen wir registrieren, was wir abfangen möchten, indem wir eine Liste von RequestPatterns an setRequestInterception übermitteln. Sie können entweder in der Phase „Anforderung“ oder in der Phase „HeadersReceived“ eingreifen. Um eine Antwort tatsächlich zu ändern, müssen wir auf „HeadersReceived“ warten. Der Ressourcentyp entspricht den Typen , die Sie normalerweise im Netzwerkbereich der Devtools sehen.

Vergessen Sie nicht, die Netzwerkdomäne zu aktivieren, wie Sie es oben bei Runtime getan haben, indem Sie Network.enable() zum selben Array hinzufügen.

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Die Registrierung des Ereignishandlers ist relativ unkompliziert und jede abgefangene Anfrage verfügt über eine ​InterceptionId , die verwendet werden kann, um Informationen zur Anfrage abzufragen oder ggf. eine Fortsetzung auszugeben. Hier greifen wir einfach ein und protokollieren jede Anfrage, die wir abfangen, im Terminal.

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Ändern von Anforderungen

Um Anfragen zu ändern, müssen wir einige Hilfsbibliotheken installieren, die Base64-Zeichenfolgen kodieren und dekodieren. Es stehen zahlreiche Bibliotheken zur Verfügung. Wählen Sie einfach Ihre eigene aus. Wir verwenden atob und btoa .

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Die API zum Verarbeiten der Antworten ist etwas umständlich. Zum Verarbeiten von Antworten müssen Sie Ihre gesamte Antwortlogik in die Anforderungsabfangung einbeziehen (und nicht beispielsweise einfach eine Antwort abfangen) und dann den Textkörper anhand der Abfang-ID abfragen. Dies liegt daran, dass der Textkörper beim Aufruf Ihres Handlers möglicherweise nicht verfügbar ist. So können Sie explizit auf das warten, was Sie suchen. Der Textkörper kann auch Base64-codiert sein, Sie sollten ihn daher prüfen und decodieren, bevor Sie ihn blind weitergeben.

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

An diesem Punkt können Sie sich mit JavaScript völlig austoben. Ihr Code versetzt Sie in die Mitte einer Antwort, sodass Sie sowohl auf das vollständige angeforderte JavaScript zugreifen als auch Ihre geänderte Antwort zurücksenden können. Eindrucksvoll! Wir optimieren das JS einfach, indem wir am Ende ein console.log anhängen, sodass unser Terminal eine Nachricht erhält, wenn unser geänderter Code im Browser ausgeführt wird.

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Wir können einen geänderten Textkörper nicht einfach allein weitergeben, da der Inhalt möglicherweise mit den Headern in Konflikt steht, die mit der Originalressource gesendet wurden. Da Sie aktiv testen und optimieren, möchten Sie wahrscheinlich mit den Grundlagen beginnen, bevor Sie sich zu viele Gedanken über andere Header-Informationen machen, die Sie übermitteln müssen. Sie können bei Bedarf über ​responseHeaders auf die Antwortheader zugreifen, die an den Ereignishandler übergeben werden. Zunächst erstellen wir jedoch einfach unseren eigenen minimalen Satz in einem Array, um ihn später einfach manipulieren und bearbeiten zu können.

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Zum Senden der neuen Antwort muss eine vollständige, Base64-codierte HTTP-Antwort (einschließlich der HTTP-Statuszeile) erstellt und über eine RawResponse- Eigenschaft im an continueInterceptedRequest übergebenen Objekt gesendet werden.

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Wenn Sie nun Ihr Skript ausführen und im Internet navigieren, sehen Sie in Ihrem Terminal etwa Folgendes, da Ihr Skript JavaScript abfängt und auch Ihr geändertes JavaScript im Browser ausgeführt wird und die ​console.log() s durch den Hook nach oben sprudeln, den wir zu Beginn des Tutorials erstellt haben.

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Der vollständige Arbeitscode für das Basisbeispiel finden Sie hier:

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Wie geht es weiter?

Sie können mit dem hübschen Ausdrucken des Quellcodes beginnen. Dies ist immer eine nützliche Möglichkeit, mit dem Reverse Engineering zu beginnen. Ja, natürlich können Sie dies in den meisten modernen Browsern tun, aber Sie möchten jeden Änderungsschritt selbst steuern, um die Konsistenz über verschiedene Browser und Browserversionen hinweg zu gewährleisten und beim Analysieren der Quelle die Zusammenhänge erkennen zu können. Wenn ich mich in fremden, verschleierten Code vertiefe, benenne ich Variablen und Funktionen gerne um, sobald ich beginne, ihren Zweck zu verstehen. Das sichere Ändern von JavaScript ist keine Kleinigkeit und würde einen eigenen Blog-Beitrag erfordern. Für den Moment können Sie jedoch etwas wie ​unminify verwenden, um gängige Minimierungs- und Verschleierungstechniken rückgängig zu machen.

Sie können unminify über npm installieren und Ihren neuen JavaScript-Body mit einem Aufruf von ​unminify umschließen, um es in Aktion zu sehen:

Abfangen und Ändern von Antworten mit Chrome über das Devtools-Protokoll

Wir werden im nächsten Beitrag tiefer auf die Transformationen eingehen. Wenn Sie Fragen, Kommentare oder andere tolle Tricks haben, kontaktieren Sie mich bitte über Twitter!