00:00:00(Tastaturgeklapper)
00:00:03Ich wollte mir mal diesen großen Honey-Skandal ansehen,
00:00:12der gerade die Runde macht.
00:00:12Falls ihr Honey nicht kennt:
00:00:13Das ist eine dieser Coupon-Erweiterungen für Chrome.
00:00:16Das bedeutet, dass der gesamte Code für mich einsehbar ist.
00:00:19Ich kann mir also anschauen, was in diesen
00:00:22YouTube-Videos eigentlich behauptet wird,
00:00:24und selbst prüfen, ob das wirklich so stimmt.
00:00:26Aber noch wichtiger: Bei Erweiterungen kann ich
00:00:28die Entwicklung über die Zeit verfolgen und sehen,
00:00:31ob diese fragwürdigen Entscheidungen Absicht waren
00:00:34und ob Software-Entwickler Änderungen vorgenommen haben,
00:00:37um nicht nur so weiterzumachen,
00:00:39sondern dieses Fehlverhalten noch effizienter und robuster zu gestalten.
00:00:44Ja, genau das haben sie getan.
00:00:45Und ich werde euch zeigen, wie.
00:00:47Ich weiß, viele von euch haben wahrscheinlich
00:00:48keine Ahnung, was da eigentlich los ist.
00:00:50Ihr kennt Honey vielleicht nicht einmal richtig
00:00:52und seid deshalb nicht auf dem Laufenden.
00:00:55Es geht hier um eine sehr spezifische Funktionsweise
00:00:58von Honey, die ich genauer erklären möchte.
00:00:59Wir schauen uns jetzt einen dreiminütigen Ausschnitt
00:01:01aus diesem aktuellen Honey-Enthüllungsvideo an.
00:01:05Danach spreche ich darüber, wie ich den minifizierten Code
00:01:08analysiert habe, was ich genau fand und welche Absicht dahintersteckt –
00:01:11was übrigens ziemlich überraschend ist.
00:01:12Wenn es etwas gibt, das Leute noch mehr hassen als Täuschung,
00:01:14dann ist es Diebstahl.
00:01:15In meinem ersten Video habe ich gezeigt,
00:01:16wie Honey Influencern das Geld gestohlen hat.
00:01:19Was ich euch aber nicht gesagt habe, ist, dass dieses Verhalten
00:01:22in den meisten Fällen streng verboten ist.
00:01:24Die Unternehmen, die diese Branche dominieren –
00:01:26die Affiliate-Netzwerke –
00:01:28wissen ganz genau, dass Coupon-Erweiterungen wie Honey
00:01:30eine hohe Wahrscheinlichkeit haben, Provisionen von
00:01:33Influencern, Bloggern und anderen
00:01:34Content-basierten Affiliates abzugreifen.
00:01:37Vor allem verstehen sie, dass das nicht fair ist,
00:01:40besonders unter der "Last Click Wins"-Regel,
00:01:43die immer noch Industriestandard ist.
00:01:46Um diese Art von Provisionsdiebstahl zu verhindern,
00:01:48erzwingen die meisten großen Affiliate-Netzwerke die sogenannte
00:01:51"Stand-Down-Policy".
00:01:53Ich zeige euch mal, wie das bei Honey aussieht.
00:01:55Besuchen wir newegg.com zuerst ohne Affiliate-Link.
00:01:58Wie ihr sehen könnt,
00:01:59meldet sich Honey sofort mit einem Cashback-Angebot.
00:02:02Machen wir das Ganze noch einmal,
00:02:03diesmal aber über meinen Affiliate-Link für Newegg.
00:02:05Ihr merkt, dass Honey jetzt gar nicht auftaucht.
00:02:08Und wenn wir auf das Honey-Icon klicken,
00:02:10sehen wir, dass Honey deaktiviert ist.
00:02:12So sollte sich Honey eigentlich verhalten,
00:02:14wenn ein Nutzer bereits auf den
00:02:15Affiliate-Link von jemand anderem geklickt hat.
00:02:17Wo also liegt dann der angebliche Betrug?
00:02:19Nun, wie sich herausstellt,
00:02:21hat Honey zwar immer ein Stand-Down-System
00:02:23in der App integriert gehabt,
00:02:24aber sie haben selektiv entschieden,
00:02:26wann und bei wem sie die Regeln anwenden.
00:02:28Testen wir meinen Newegg-Affiliate-Link noch einmal.
00:02:31Diesmal habe ich zwei völlig separate Chrome-Browser
00:02:34gleichzeitig offen,
00:02:36und jeder ist in einem anderen Honey-Account eingeloggt.
00:02:38Der linke Honey-Account hat null Cashback-Punkte,
00:02:41während der Account auf der rechten Seite
00:02:43bereits Punkte gesammelt hat.
00:02:45Achtet darauf, was passiert, wenn ich den
00:02:46Newegg-Affiliate-Link in beiden Browsern öffne.
00:02:49Der linke Honey-Account hält sich zurück (
00:02:51Stands Down), genau wie beim ersten Mal.
00:02:52Aber seht euch das an: Der rechte Account,
00:02:54der Cashback-Punkte hat, ist aktiv geblieben.
00:02:58Warum ist das so?
00:02:58Genau das wollte ich testen.
00:03:01Ich wollte der Sache auf den Grund gehen, denn das ist Code.
00:03:03Code verstehe ich.
00:03:04Ich kann mir die JSON-Daten ansehen,
00:03:07die da geladen werden, und sie analysieren.
00:03:09Zudem erlaubt mir die Power von KI,
00:03:11minifizierten Code in einer Geschwindigkeit zu durchsuchen,
00:03:13die ich in meiner gesamten Laufbahn als Programmierer
00:03:16so noch nicht erlebt habe.
00:03:18Wir haben uns also zuerst verschiedene Versionen
00:03:21von Honey besorgt.
00:03:22Die Versionen, die ich untersucht habe,
00:03:23reichten von etwa Februar 2019
00:03:25bis zum heutigen Tag.
00:03:28Dabei wollte ich wissen: Erstens, gibt es diese Logik,
00:03:30dass der Punktestand entscheidet,
00:03:33wann das Stand-Down-Menü angezeigt wird
00:03:36und wann nicht, überhaupt?
00:03:38Ja, sie existiert definitiv.
00:03:40Die eigentliche Frage war: Hat sie sich verändert?
00:03:43Ich habe in großen Firmen gearbeitet –
00:03:45vielleicht habt ihr das auch –
00:03:46und man weiß, dass Code manchmal einfach hängen bleibt.
00:03:48Nach dem Motto: "Hoppla, der ist ja immer noch da."
00:03:50Niemand hat ihn seit fünf Jahren angefasst,
00:03:52so ist das eben manchmal.
00:03:54Danach habe ich gesucht:
00:03:55Ist der Code einfach nur alt,
00:03:57oder gab es signifikante Änderungen?
00:04:00Ich rede nicht von kleinen Fehlerbehebungen.
00:04:03Um Copyright-Probleme zu vermeiden –
00:04:05anscheinend mahnen die PayPal-Anwälte
00:04:07jeden per DMCA ab, der den eigentlichen Code zeigt –
00:04:10muss ich dieses kleine Theaterstück an der
00:04:13Tafel aufführen, um euch zu zeigen, was passiert.
00:04:15In Version 11 (ca. 2019) gab es bereits
00:04:18die Stand-Down-Logik.
00:04:22Es gab sogar Dinge, die explizit
00:04:25"SSD stand down logics" hießen.
00:04:27Sie passten zur JSON-Datei,
00:04:29die mit jeder Menge Daten geliefert wurde.
00:04:31Hier ist zum Beispiel die Stand-Down-Regel
00:04:32für einen nicht eingeloggten Nutzer – ganz simpel.
00:04:35Hier steht "UP" für User Points (Nutzerpunkte).
00:04:38"ADB" ist wohl der letzte Einsatz des Werbeblockers.
00:04:41Dann gibt es noch "is account logged in".
00:04:45Und noch ein paar andere Felder,
00:04:47die hin und wieder auftauchen.
00:04:48Interessanterweise sah das 2019 in Version 11
00:04:50oft so aus:
00:04:53Es gab ein riesiges Switch-Statement
00:04:55mit Fällen wie: "Prüfen wir auf eine E-Mail?"
00:04:57Und ja, da stand wortwörtlich ein String:
00:04:59Enthält diese E-Mail das Wort "test"?
00:05:02Falls ja: Immer Stand-Down. Was übrigens extrem zwielichtig ist.
00:05:04Damit werden Test-Accounts der Netzwerke umgangen,
00:05:06die prüfen wollen, ob das System
00:05:10überhaupt ordnungsgemäß funktioniert.
00:05:13Denn seien wir ehrlich:
00:05:15Wer nutzt keinen Test-Account,
00:05:16der das Wort "Test" im Namen trägt?
00:05:17Ich jedenfalls schon.
00:05:19Das war eine explizite Prüfung.
00:05:20Sobald "test" irgendwo in der E-Mail vorkommt,
00:05:22wird die Erweiterung deaktiviert.
00:05:24Aber noch verwirrender waren die
00:05:27darauffolgenden Prüfungen.
00:05:29Es hieß zum Beispiel: "Ist der aktuelle Provider
00:05:31gleich 'LS' (LinkShare)?"
00:05:32Wenn ja, wende genau diese Regeln an.
00:05:35Später gab es eine Schleife,
00:05:39die alle ermittelten Regeln nacheinander durchging
00:05:41und prüfte, ob eine davon fehlschlägt.
00:05:44Falls ja, erfolgte der Stand-Down.
00:05:47Das war ein ziemlich hartcodierter Prozess," wie man sieht,
00:05:49mit Zeilen wie: "Wenn LinkShare, dann diese Aktion."
00:05:51Oder: "Bei diesem Provider mache etwas anderes."
00:05:53Ich war schon in vielen Projekten,
00:05:55in denen so etwas passiert. Das ist völlig normal.
00:05:57Man fängt an und sagt: "Okay,
00:06:00wir haben vielleicht ein oder zwei Provider."
00:06:01Also baut man ein paar hartcodierte Sonderfälle ein
00:06:06und stellt sicher, dass alles irgendwie passt.
00:06:08Man geht für eine gewisse Zeit in den Stand-Down,
00:06:11was übrigens oft nicht sehr lange war.
00:06:12Schaut euch das Video von MegaLega an, um zu sehen,
00:06:14wie furchtbar diese Regeln eigentlich waren.
00:06:15Aber mein Ziel war herauszufinden:
00:06:18Haben sie den Code verbessert? Gab es Bugfixes?
00:06:20Was ist passiert?
00:06:23Hier wird es etwas verwirrend,
00:06:24denn zwischen den Versionen 11 und 14
00:06:25(also bis etwa 2022) blieb fast alles gleich.
00:06:27Kaum Änderungen, nichts Nennenswertes.
00:06:30Aber ab Version 16 (im Jahr 2024)
00:06:34gab es ein umfassendes Refactoring,
00:06:36um diese Entscheidungen über einen Endpunkt
00:06:39in Honey steuerbar zu machen.
00:06:39Dieser Endpunkt liefert ein Objekt mit einem Basiswert,
00:06:42gefolgt von weiteren Werten unter 'X'.
00:06:45In der alten Version gab es noch
00:06:49eine Reihe von If-Statements,
00:06:52um das gewünschte Verhalten festzulegen.
00:06:54Dann folgte die Regelauswertung,
00:06:56um ein "True" oder "False" zu erhalten.
00:06:58In Version 16 haben sie sich jedoch für
00:07:03einen technisch anspruchsvolleren Weg entschieden.
00:07:05Wir wissen alle, was man tut,
00:07:07wenn man zig If-Statements hat,
00:07:09die nur Daten umschichten und Objekte leicht verändern.
00:07:14Man möchte das über eine Konfiguration steuern.
00:07:16Man will es dynamischer machen,
00:07:18um es leichter handhabbar zu machen.
00:07:20Und genau das haben sie getan.
00:07:22Schauen wir uns die Daten an, die für mich als
00:07:23nicht eingeloggten Honey-Nutzer reinkommen.
00:07:26Hier sieht man eine Basisklasse.
00:07:28Diese bildet die Grundlage dafür,
00:07:30wie Honey entscheidet.
00:07:34Für diese Basisklasse eines nicht eingeloggten Nutzers
00:07:36werden 65.000 Punkte benötigt, damit Honey aktiv bleibt.
00:07:38Habe ich weniger als 65.000 Punkte –
00:07:40und da ich nicht eingeloggt bin, habe ich null –
00:07:42heißt es: "Sorry, Stand-Down. Ich halte mich raus."
00:07:45Nachdem diese Basis feststeht,
00:07:48prüft das System: Wie sind wir hierher gekommen?
00:07:49Warum sind wir hier?
00:07:52Die nächste Prüfung lautet: Kam der Zugriff
00:07:53von einem dieser Affiliate-Netzwerke?
00:07:55Dann werden die Werte angepasst.
00:07:58Komme ich zum Beispiel von LinkShare,
00:08:00werden plötzlich nur noch 5.001 Punkte benötigt." Das Basis-Objekt wird also überschrieben.
00:08:04Das ist technisch viel ausgereifter.
00:08:05Es sind keine hartcodierten If-Statements mehr.
00:08:08Stattdessen heißt es: "Nimm die Basis.
00:08:13Gibt es einen Provider? Wenn ja, füge die Werte
00:08:15des Providers per Spread-Operator ein."
00:08:17Und dann kommt das wirklich Verrückte:
00:08:18all diese Werte unter 'X'.
00:08:20Das sind shop-spezifische Werte.
00:08:22Dann wird geprüft: "In welchem Shop bin ich gerade?"
00:08:25Diese Werte werden ebenfalls hinzugefügt.
00:08:27Danach folgt die normale Regellogik.
00:08:28Das zeigt, dass das System nicht mehr nur im
00:08:30Wartungsmodus läuft.
00:08:32Es ist kein hartcodierter Hack mehr,
00:08:33der da seit einem Jahrzehnt rumliegt.
00:08:35Stattdessen haben sie 2024 entschieden:
00:08:39"Wir müssen robuster werden."
00:08:41Sie wollten Entscheidungen für mehr Shops
00:08:43und mehr Provider wartungsfreundlicher gestalten.
00:08:44Das war echtes Software-Engineering – und sie haben es durchgezogen.
00:08:48Wenn ich mir das ansehe, erkenne ich,
00:08:51dass sie ihr System über die Zeit verbessert haben.
00:08:55Da steckt also eine Absicht dahinter.
00:08:58Sie wollen das System am Laufen halten,
00:09:01egal ob es nun betrügerisch ist oder nicht.
00:09:03Das müssen andere beurteilen,
00:09:07aber ich kann sagen, dass sie es
00:09:09robuster und besser gemacht haben.
00:09:13Angesichts der Tatsache, dass das System allgemein
00:09:16als ziemlich zwielichtig wahrgenommen wird,
00:09:20haben sie ihr zwielichtiges System technisch stark aufgewertet.
00:09:22Aber das war noch nicht alles.
00:09:23Ich habe noch etwas gefunden, das mein Interesse weckte.
00:09:26Immer wieder tauchte das Wort "VIM" auf.
00:09:29Ich dachte: "VIM? Was hat ein Texteditor im Code zu suchen?"
00:09:31Als ich Claude dazu befragte, hieß es:
00:09:33"Meinst du den VIM Instance Manager,
00:09:36der in Honey gefunden wurde?"
00:09:39Ich dachte: "VIM Instance Manager?"
00:09:43Das kann es nicht sein.
00:09:46Auf keinen Fall.
00:09:49Doch beim genaueren Hinsehen stellte sich heraus,
00:09:52dass eine komplette JavaScript-in-JavaScript-Engine
00:09:54innerhalb des Honey-Plugins läuft.
00:09:57Das ist das Seltsamste, was ich je gesehen habe.
00:09:59Ich habe versucht, mich einzulesen.
00:10:01Ich bin kein Experte für Chrome-Plugins,
00:10:04also hatte ich keine Ahnung, warum jemand
00:10:07JavaScript innerhalb von JavaScript ausführen sollte.
00:10:10Honey nutzt Acorn, einen JavaScript-Parser,
00:10:11der aus validem JavaScript einen AST (Abstract Syntax Tree) erzeugt.
00:10:16Dieser wird ausgewertet und dann
00:10:17in diese VIM-Engine eingespeist.
00:10:19Es gibt mehrere Referenzen im Code auf
00:10:23Objekte namens "cart ops retrieval JS"
00:10:26und "product ops retrieval JS", die echten Code enthalten.
00:10:29Und es gibt Verweise auf diesen JS-Code,
00:10:32der manchmal – wie hier –
00:10:34echtes, funktionsfähiges JavaScript ist.
00:10:35Soweit ich das beurteilen konnte,
00:10:37wird dieser Code momentan nicht aktiv ausgeführt.
00:10:38Ich habe Breakpoints gesetzt,
00:10:40aber konnte keinen Auslöser finden.
00:10:45Dennoch: Die Infrastruktur ist da.
00:10:49Sie haben das System so vorbereitet, dass sie
00:10:54Remote-Code auf eurem Rechner ausführen können,
00:10:56basierend auf dem, was Honey zurückgibt –
00:10:59und das auf eine extrem verschleierte Weise.
00:11:04JavaScript in JavaScript.
00:11:05Sie haben einen Parser und eine virtuelle Maschine.
00:11:09Es ist wirklich JavaScript in JavaScript.
00:11:12Es gibt auch einen Abschnitt
00:11:14mit massenweise stringifizierten Funktionen.
00:11:17Da ist jede Menge Inline-JavaScript drin,
00:11:19mit dem sie wohl Seiten durchsuchen und Ähnliches.
00:11:22Aber da diese mit dem Produkt selbst kommen,
00:11:24verstoßen sie technisch gesehen nicht gegen
00:11:28die alten Google-Nutzungsbedingungen.
00:11:31Denn schaut man sich die Anforderungen für
00:11:33Manifest V3 an, sieht man,
00:11:36dass JavaScript-'eval' eigentlich verboten ist.
00:11:38Alles klar, wir nutzen also kein 'eval'.
00:11:39Stattdessen hartcodieren wir Operationen,
00:11:41von denen andere Plugins nichts wissen sollen.
00:11:42Und dann bauen wir eine komplette JavaScript-Engine ein,
00:11:45um das Ganze noch weiter zu verschleiern.
00:11:47Witzigerweise scheint Manifest V3
00:11:49fast wie für Honey gemacht zu sein.
00:11:52Es verbietet das Bauen eines Interpreters,
00:11:54um komplexe Befehle von einer Remote-Quelle auszuführen –
00:11:57selbst wenn diese Befehle als Daten getarnt sind.
00:11:59Aber sie umgehen das.
00:12:00Das sind keine Remote-Befehle.
00:12:03Es sind Strings, die direkt
00:12:06in der Honey-Erweiterung stecken.
00:12:08Aber Mann, was für eine Verschleierungstaktik.
00:12:11Das ist wirklich schräg.
00:12:13Ich persönlich sehe keinen einzigen legitimen Grund,
00:12:15warum man so etwas tun sollte.
00:12:18Wie gesagt, angeblich liegt es an Interaktionen
00:12:22mit anderen Erweiterungen, sprich Werbeblockern.
00:12:24Anscheinend blockieren Werbeblocker Honey,
00:12:26wenn es bestimmte Funktionen direkt ausführt.
00:12:28Über diesen seltsamen Interpreter
00:12:30kann man aber Dinge laufen lassen,
00:12:33ohne entdeckt zu werden.
00:12:34Keine Ahnung, für mich sieht das nach einem Riesenchaos aus.
00:12:35Ich fand das jedenfalls extrem spannend,
00:12:38da ich vorher noch nie Reverse Engineering gemacht habe.
00:12:40Ich habe mir noch nie fremden Quellcode angesehen,
00:12:44schon gar nicht minifizierten.
00:12:47Ich wollte euch das einfach mal zeigen.
00:12:50Das ist vielleicht die ungewöhnlichste Software-Architektur,
00:12:52die mir je untergekommen ist.
00:12:54Ich habe an Codebasen gearbeitet,
00:12:57die über 10.000 Zeilen lang waren,
00:12:59mit wirren State-Machines, unmöglich zu warten.
00:13:00Aber das hier setzt dem Ganzen die Krone auf.
00:13:01Das ist das komplexeste, seltsamste
00:13:03Rube-Goldberg-Konstrukt, das ich je gesehen habe.
00:13:05Und diese dynamischen Regeln
00:13:07für das Stand-Down-Verhalten...
00:13:09sie sind verdammt robust.
00:13:12Was auch immer der Zweck ist – betrügerisch oder nicht –,
00:13:14es ist so konzipiert, dass es dynamisch per JSON
00:13:16pro Shop, pro Provider und pro Nutzer steuerbar ist.
00:13:19Wie auch immer, ein riesiges Dankeschön an Magalega.
00:13:22Das war echt klasse.
00:13:25Ich konnte mit ihm chatten,
00:13:27und er hat mir bei der Analyse geholfen.
00:13:29Schaut euch unbedingt sein Video an.
00:13:31Der Link ist in der Beschreibung.
00:13:33Es ist wirklich super gemacht.
00:13:35Es gibt mehrere Teile davon,
00:13:37und ich empfehle euch, alle anzusehen.
00:13:39Sie sind wirklich sehr gut.
00:13:41Hat euch das Video gefallen?
00:13:42Wie findet ihr dieses Format?
00:13:45Ich weiß es nicht,
00:13:46es ist mal was Neues.
00:13:48Ich habe einfach Zeit im Stream verbracht,
00:13:50Spaß gehabt und berichte euch nun davon.
00:13:53Wenn ihr im Stream dabei gewesen wärt,
00:13:57hättet ihr das alles live miterlebt.
00:14:01Hätte euch sicher noch mehr Spaß gemacht.
00:14:03Ich bin zwar kein Profi im Reverse Engineering,
00:14:05aber es hat verdammt viel Spaß gemacht.
00:14:07Ich verstehe jetzt, warum Leute das tun.
00:14:08A-gen.
00:14:11Hey, ist das etwa HTTP?
00:14:14Weg damit.
00:14:17So bestellt man keinen Kaffee.
00:14:19Kaffee bestellt man per SSH über terminal.shop.
00:14:21Ihr wollt ein echtes Erlebnis?
00:14:22Richtig guten Kaffee?
00:14:23Ein tolles Abo,
00:14:25damit ihr nie wieder selbst dran denken müsst?
00:14:26Exklusive Mischungen, exklusiven Kaffee
00:14:27und exklusiven Content?
00:14:28Dann schaut bei CRON vorbei.
00:14:29Ihr wisst nicht, was SSH ist?
00:14:30Na ja, vielleicht ist der Kaffee dann nichts für euch.
00:14:32♪ Terminal-Kaffee in der Hand ♪
00:14:33♪ Lebe den Traum ♪
00:14:35Do you like this format?
00:14:36I don't know.
00:14:37This is kind of new.
00:14:38This is just me spending some time on stream,
00:14:40having fun and then reporting back to you.
00:14:42If you were on stream, you would have saw this happen live.
00:14:44Could have been a lot more fun for you.
00:14:45The name is I'm not a reverse engineer,
00:14:49but this was a lot of fun.
00:14:50I can see why people do it.
00:14:51A gen.
00:14:52Hey, is that HTTP?
00:14:55Get that out of here.
00:14:56That's not how we order coffee.
00:14:57We order coffee via SSH, terminal.shop.
00:15:00Yeah, you want a real experience?
00:15:02You want real coffee?
00:15:03You want awesome subscription
00:15:04so you never have to remember again?
00:15:06Oh, you want exclusive blends with exclusive coffee
00:15:10and exclusive content?
00:15:12Then check out CRON.
00:15:13You don't know what SSH is?
00:15:14Well, maybe the coffee's not for you.
00:15:18♪ Terminal coffee in hand ♪
00:15:22♪ Live in the dream ♪