Google Translation API Hacking

A Google felhasználásalapú költségstruktúrával kínálja a Google Translation API -t a Google Cloud részeként. Van olyan dokumentálatlan API is , amely kulcs nélkül használható, de néhány kérés után nem hajlandó működni. A Google Chrome webhelyfordítási funkciójának használatakor észrevehető, hogy az oldalakat nagyon jó minőségben, észrevehető korlátozás nélkül lehet lefordítani.


Nyilvánvalóan itt már a fejlett nmt modellt használják. De melyik API-t használja a Google Chrome belsőleg a tartalom lefordításához, és közvetlenül is hozzá lehet férni ehhez az API-hoz – akár a szerver oldalon? A hálózati forgalom elemzéséhez olyan eszközöket ajánlunk, mint a Wireshark vagy a Telerik Fiddler , amelyek a titkosított forgalmat is elemezhetik. De a Chrome még az oldalak fordítása során küldött kéréseket is ingyenesen kézbesíti: azok könnyen megtekinthetők a Chrome DevTools segítségével:

Ha lefordít, akkor elkapja a kulcsfontosságú POST kérést, hogy https://translate.googleapis.com a "Másolás> Másolás cURL-ként (bash)" oldalon keresztül hajtsa végre, és például egy olyan eszközben hajtsa végre, mint például a Postman , problémamentesen elküldheti a kérést:

Az URL paraméterek jelentése is többnyire nyilvánvaló.:

KulcsPélda értékreJelentése
anno3Megjegyzés mód (befolyásolja a visszatérési formátumot)
ügyfélte_libÜgyféladatok (változók; a Google Fordító webes felületén keresztül az érték „webapp”; befolyásolja a visszatérési formátumot és a gyakoriságkorlátozást)
formátumhtmlKarakterlánc formátum (fontos a HTML-címkék fordításához)
v1.0A Google Fordító verziószáma
kulcsAIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgwAPI-kulcs (lásd alább)
logldvTE_20200210_00Protokoll verzió
sldeForrás nyelv
tlhuCélnyelven
spnmtML modell
tc1ismeretlen
sr1ismeretlen
tk709408.812158Token (lásd alább)
Divat1ismeretlen

Néhány kérés fejléc is be van állítva - de ezeket többnyire figyelmen kívül lehet hagyni. Miután az összes fejlécet manuálisan törölte, beleértve a felhasználói ügynököt is , kódolási probléma merül fel a speciális karakterek beírásakor (itt a " Hello World " fordításakor):

Ha újraaktiválja a felhasználói ügynököt (amely általában nem árt), az API UTF-8 kódolású karaktereket küld:

Elértük most a célunkat, és minden információval rendelkezünk ahhoz, hogy ezt az API-t a Google Chrome-on kívül is használhassuk? Ha azonban a lefordítandó karakterláncot (a POST kérés q adatmezőjét) például a „Hello World”-ről a „Hello World ! ”-re módosítjuk, hibaüzenetet kapunk.:

Most a módosított karakterlánc egy újabb fordítását végezzük el a Google Chrome-ban a weboldalfordító függvény segítségével, és azt tapasztaljuk, hogy a q paraméter mellett a tk paraméter is megváltozott (az összes többi paraméter változatlan maradt).:

Nyilvánvaló, hogy ez egy olyan karakter, amely függ a karakterlánctól, amelynek felépítése nem könnyen látható. A webhelyfordítás elindításakor a következő fájlok töltődnek be:

  • 1 CSS fájl: translateelement.css
  • 4 grafika: translate_24dp.png (2x), gen204 (2x)
  • 2. JS fájlok: main_de.js, element_main.js

A két JavaScript-fájl homályos és tömörített. Az olyan eszközök, mint a JS Nice és a de4js , most segítenek nekünk abban, hogy ezeket a fájlokat olvashatóbbá tegyük. Az élő hibakereséshez javasoljuk a Chrome Extension Requestly alkalmazást, amely menet közben a távoli fájlokat helyben alagutazza:

Most hibakereshetjük a kódot (a CORS- t először a helyi szerveren kell aktiválni). Úgy tűnik, hogy a token előállításához szükséges kódrész el van rejtve ebben a szakaszban az element_main.js fájlban:

b7739bf50b2edcf636c43a8f8910def9

Itt a szöveget néhány biteltolás segítségével kivonatolják. De sajnos még mindig hiányzik egy darab a puzzle: Amellett, hogy az érv olyan (ami a fordítandó szöveg), egy másik érv b jut el a funkció Bp () - egyfajta mag, amely úgy tűnik, hogy változik időről időre, és amely magában foglalja hashba folyik. De honnan származik? Ha a Bp () függvényhívására ugrunk , akkor a következő kódrészletet találjuk meg:

b7739bf50b2edcf636c43a8f8910def9

A Hq függvényt előzetesen a következőképpen deklaráljuk:

b7739bf50b2edcf636c43a8f8910def9

A deobfuszkátor hagyott itt némi szemetet; miután a String.fromCharCode('...')- t lecseréltük a megfelelő karakterláncokra, eltávolítottuk az elavult a()-t és összeraktuk a [c(), c()] függvényhívásokat, azt kapjuk,:

b7739bf50b2edcf636c43a8f8910def9

Vagy még könnyebb:

b7739bf50b2edcf636c43a8f8910def9

Az yq függvényt korábban úgy definiáltuk:

b7739bf50b2edcf636c43a8f8910def9

Tehát úgy tűnik, hogy a mag a google.translate._const._ctkk globális objektumban található, amely futás közben elérhető. De hol van elhelyezve? Legalábbis az elején elérhető a másik, korábban betöltött JS fájl main_de.js . Az elejére a következőket adjuk hozzá:

b7739bf50b2edcf636c43a8f8910def9

A konzolban valóban megkapjuk az aktuális magot:

Ez maga a Google Chrome, amely nyilvánvalóan a magot biztosítja, az utolsó lehetőség. Szerencsére a forráskódja (Chromium, a Translate komponenssel együtt) nyílt forráskódú, ezért nyilvánosan elérhető. Helyileg húzzuk meg a lerakatot , és megtaláljuk a TranslateScript :: GetTranslateScriptURL függvény hívását a translate_script.cc fájlban a components / translate / core / browser böngészőben.:

b7739bf50b2edcf636c43a8f8910def9

Az URL-t tartalmazó változó ugyanabban a fájlban keményen definiálható:

b7739bf50b2edcf636c43a8f8910def9

Ha most alaposabban megvizsgáljuk az element.js fájlt (további deobfuszkálás után), megtaláljuk a c._ctkk hard set bejegyzést - a google.translate objektum is ennek megfelelően van beállítva, és az összes releváns eszköz betöltése (amit korábban már felfedeztünk) elindul.:

b7739bf50b2edcf636c43a8f8910def9

Most a paraméter gomb továbbra is megfontolásra (az érték AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw). Úgy tűnik, hogy ez egy általános böngésző API-kulcs (amely megtalálható a Google egyes eredményeiben is ). A Chromiumban van megadva a translate_url_util.cc fájlban a / translate / core / browser böngészőben.:

b7739bf50b2edcf636c43a8f8910def9

A kulcs a google_apis / google_api_keys.cc fájlban generálódik egy dummy értékből:

b7739bf50b2edcf636c43a8f8910def9

A tesztelés azonban azt mutatja, hogy az API-hívások e kulcsparaméter nélkül is ugyanolyan jól működnek. Az API-val végzett kísérletek során mostantól 200-as állapotkódot adnak vissza sikeres hívások esetén. Ha elérik a korlátot, 411-es állapotkódot ad vissza a következő üzenettel: „ A POST kérésekhez tartalomhosszúságú fejléc szükséges ”. Ezért ajánlott ezt a fejlécet is belefoglalni (amely automatikusan ideiglenes fejlécként van beállítva a Postmanban).

A lefordított karakterláncok visszatérési formátuma szokatlan, ha egy kérésben több mondat van. Az egyes mondatokat az i- / b-HTML címkék határolják:

Ezenkívül a Google Chrome nem küldi el a teljes HTML-t az API-nak, hanem az attribútumértékeket, például a href-et elmenti a kérésbe (ehelyett indexeket állít be, hogy a címkék később az ügyfél oldalán hozzárendelhetők legyenek):

Ha a POST kulcs kliens értékét megváltoztatja te_lib értékről (Google Chrome) a webappon (a Google Fordítás webhelyén ) megkapja az utolsó lefordított karakterláncot:

A probléma az, hogy sokkal nagyobb eséllyel ütközik be a sebességkorlátozásba, mint a te_lib segítségével (összehasonlításképpen: a webapp alkalmazással ez 40 000 karakter után érhető el, a te_lib esetében nincs sebességkorlátozás). Ezért közelebbről meg kell vizsgálnunk, hogy a Chrome hogyan elemzi az eredményt. Megtaláljuk itt az element_main.js fájlban:

b7739bf50b2edcf636c43a8f8910def9

Ha a teljes HTML-kódot elküldi az API-nak, akkor az attribútumokat a lefordított válaszban hagyja. Ezért nem kell a teljes elemzési viselkedést utánoznunk, hanem csak a végső, lefordított karakterláncot kell kivonnunk a válaszból. Ehhez egy kis HTML címkeelemzőt építünk, amely elveti a legkülső <i> címkéket, beleértve azok tartalmát, és eltávolítja a legkülső <b> címkéket. Ezzel a tudással most már (a függőségek telepítése után a composer szükséges fzaninotto / faker vielhuber / stringhelper segítségével ) elkészíthetjük a fordítási API szerveroldali verzióját.:

b7739bf50b2edcf636c43a8f8910def9

Az alábbiakban egy kezdeti teszt eredményei láthatók, amelyet öt különböző rendszeren végeztek, különböző sávszélességgel és IP-címekkel:

KarakterKarakterek kérésenkéntIdőtartamHibaarányKöltség a hivatalos API-n keresztül
13.064.662~25003: 36: 17h0%237,78 €
24.530.510~25011: 09: 13h0%446,46 €
49.060.211~25020: 39: 10h0%892,90 €
99.074.487~100061: 24: 37h0%1803,16 €
99.072.896~100062: 22: 20h0%1803,13 €
Σ284.802.766~ Ø550159: 11: 37h0%5183,41 €

Megjegyzés: Ez az összes szkriptet tartalmazó blogbejegyzés csak tesztelési célokra készült. Ne használja a szkriptek termelési célra, hanem dolgozni a hivatalos Google Translation API .

Vissza