Παραβίαση API μετάφρασης Google

Η Google προσφέρει το API Μετάφρασης Google με δομή κόστους βάσει χρήσης ως μέρος του Google Cloud. Υπάρχει επίσης ένα API χωρίς έγγραφα που μπορεί να χρησιμοποιηθεί χωρίς κλειδί , αλλά το οποίο αρνείται να λειτουργήσει μετά από λίγα μόνο αιτήματα. Όταν χρησιμοποιείτε τη λειτουργία μετάφρασης ιστότοπου του Google Chrome, είναι αξιοσημείωτο ότι οι σελίδες μπορούν να μεταφραστούν σε πολύ καλή ποιότητα χωρίς κανένα αισθητό περιορισμό.


Προφανώς το προηγμένο μοντέλο nmt χρησιμοποιείται ήδη εδώ. Αλλά ποιο API χρησιμοποιεί το Google Chrome εσωτερικά για να μεταφράσει το περιεχόμενο και μπορεί αυτό το API να αντιμετωπιστεί απευθείας - ακόμη και από την πλευρά του διακομιστή; Για την ανάλυση της κίνησης δικτύου, συνιστώνται εργαλεία όπως το Wireshark ή το Telerik Fiddler , τα οποία μπορούν επίσης να αναλύσουν την κρυπτογραφημένη κίνηση. Αλλά το Chrome παραδίδει ακόμη και τα αιτήματα που στέλνει για τη μετάφραση σελίδας δωρεάν: Μπορούν να προβληθούν εύκολα χρησιμοποιώντας τα Chrome DevTools:

Εάν εκτελέσετε μια μετάφραση, τότε πιάστε το κρίσιμο αίτημα POST για να https://translate.googleapis.com μέσω "Αντιγραφή> Αντιγραφή ως cURL (bash)" και να το εκτελέσετε σε ένα εργαλείο όπως ο Ταχυδρόμος , για παράδειγμα, μπορείτε να στείλετε ξανά το αίτημα χωρίς προβλήματα:

Η έννοια των παραμέτρων URL είναι επίσης σε μεγάλο βαθμό προφανής:

ΚλειδίΠαράδειγμα τιμήςΈννοια
anno3Λειτουργία σχολιασμού (επηρεάζει τη μορφή επιστροφής)
πελάτηςte_libΠληροφορίες πελάτη (ποικίλλει, η τιμή είναι "webapp" μέσω της διεπαφής ιστού της Μετάφρασης Google. Επηρεάζει τη μορφή επιστροφής και τον περιορισμό των τιμών)
μορφήhtmlΜορφή συμβολοσειράς (σημαντική για τη μετάφραση ετικετών HTML)
β1.0Αριθμός έκδοσης της Μετάφρασης Google
κλειδίAIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgwΚλειδί API (δείτε παρακάτω)
logldvTE_20200210_00Έκδοση πρωτοκόλλου
slντεΓλώσσα πηγής
τλenΓλώσσα προορισμού
spnmtΜοντέλο ML
tc1άγνωστος
δρ1άγνωστος
tk709408.812158Κουπόνι (δείτε παρακάτω)
Μόδα1άγνωστος

Ορισμένες κεφαλίδες αιτήσεων έχουν επίσης οριστεί - αλλά αυτές μπορούν κυρίως να αγνοηθούν. Αφού αποεπιλέξετε με μη αυτόματο τρόπο όλες τις κεφαλίδες, συμπεριλαμβανομένων εκείνων από τον πράκτορα χρήστη , εντοπίζεται ένα πρόβλημα κωδικοποίησης κατά την εισαγωγή ειδικών χαρακτήρων (εδώ κατά τη μετάφραση του " Hello World "):

Εάν επανενεργοποιήσετε τον πράκτορα χρήστη (που γενικά δεν κάνει κακό), το API παρέχει κωδικοποιημένους χαρακτήρες UTF-8:

Είμαστε ήδη εκεί και έχουμε όλες τις πληροφορίες για να χρησιμοποιήσουμε αυτό το API εκτός του Google Chrome; Εάν αλλάξετε τη συμβολοσειρά χαρακτήρων που πρόκειται να μεταφραστεί (πεδίο δεδομένων q του αιτήματος POST) από, για παράδειγμα, «Γεια σας κόσμος» σε «Γεια σας κόσμος ! ", Λαμβάνουμε ένα μήνυμα σφάλματος:

Τώρα μεταφράζουμε αυτό το τροποποιημένο ξανά στο Google Chrome χρησιμοποιώντας τη λειτουργία μετάφρασης ιστότοπου και διαπιστώνουμε ότι, εκτός από την παράμετρο q , η παράμετρος tk έχει επίσης αλλάξει (όλες οι άλλες παράμετροι έχουν παραμείνει οι ίδιες):

Προφανώς, είναι ένα διακριτικό που εξαρτάται από τη συμβολοσειρά, η δομή της οποίας δεν είναι ευδιάκριτη. Όταν ξεκινάτε τη μετάφραση του ιστότοπου, φορτώνονται τα ακόλουθα αρχεία:

  • 1 αρχείο CSS: translateelement.css
  • 4 γραφικά: translate_24dp.png (2x), gen204 (2x)
  • 2 αρχεία JS: main_de.js , element_main.js

Τα δύο αρχεία JavaScript ασαφή και ελαχιστοποιούνται. Εργαλεία όπως το JS Nice και το de4js μας βοηθούν τώρα να κάνουμε αυτά τα αρχεία πιο ευανάγνωστα. Για να τα εντοπίσετε ζωντανά, προτείνουμε το Chrome Extension Requestly, το οποίο συντονίζει απομακρυσμένα αρχεία τοπικά εν κινήσει:

Τώρα μπορούμε να διορθώσουμε τον κώδικα (το CORS πρέπει πρώτα να ενεργοποιηθεί στον τοπικό διακομιστή). Η σχετική ενότητα κώδικα για τη δημιουργία του διακριτικού φαίνεται να είναι κρυμμένη σε αυτήν την ενότητα στο αρχείο element_main.js:

b7739bf50b2edcf636c43a8f8910def9

Εδώ το κείμενο κατακερματιστεί με τη βοήθεια ορισμένων αλλαγών . Δυστυχώς, όμως, χάνουμε ένα κομμάτι του παζλ: Εκτός από το επιχείρημα a (που είναι το κείμενο που πρόκειται να μεταφραστεί), ένα άλλο επιχείρημα b μεταφέρεται στη συνάρτηση Bp () - ένα είδος σπόρου που φαίνεται να αλλάζει από καιρό σε καιρό και περιλαμβάνει επίσης ρέει σε κατακερματισμό. Αλλά από πού προέρχεται; Εάν μεταβούμε στη συνάρτηση Bp () , βρίσκουμε την ακόλουθη ενότητα κώδικα:

b7739bf50b2edcf636c43a8f8910def9

Η συνάρτηση Hq δηλώνεται εκ των προτέρων ως εξής:

b7739bf50b2edcf636c43a8f8910def9

Εδώ ο Deobfuscater άφησε κάποια σκουπίδια. Αφού αντικαταστήσουμε το String.fromCharCode ('...') με τις αντίστοιχες συμβολοσειρές χαρακτήρων, αφαιρέστε το ξεπερασμένο a () και τεμαχίστε τη συνάρτηση που καλεί [c (), c ()] μαζί, το αποτέλεσμα:

b7739bf50b2edcf636c43a8f8910def9

Ή ακόμα πιο εύκολο:

b7739bf50b2edcf636c43a8f8910def9

Η συνάρτηση yq ορίστηκε προηγουμένως ως:

b7739bf50b2edcf636c43a8f8910def9

Ο σπόρος φαίνεται να βρίσκεται στο παγκόσμιο αντικείμενο google.translate._const._ctkk , το οποίο είναι διαθέσιμο κατά το χρόνο εκτέλεσης. Αλλά πού είναι; Στο άλλο, το αρχείο JS main_de.js που φορτώθηκε προηγουμένως , τουλάχιστον είναι επίσης διαθέσιμο στην αρχή. Προσθέτουμε τα ακόλουθα στην αρχή:

b7739bf50b2edcf636c43a8f8910def9

Στην κονσόλα παίρνουμε πραγματικά τον τρέχοντα σπόρο:

Αυτό αφήνει το ίδιο το Google Chrome, το οποίο προφανώς παρέχει το σπόρο, ως την τελευταία επιλογή. Ευτυχώς, ο πηγαίος κώδικας του (Chromium, συμπεριλαμβανομένου του στοιχείου Translate) είναι ανοιχτού κώδικα και επομένως διαθέσιμος στο κοινό. Τραβήξουμε το αποθετήριο τοπικά και βρίσκουμε την κλήση της συνάρτησης TranslateScript :: GetTranslateScriptURL στο αρχείο translate_script.cc στο φάκελο components / translate / core / browser:

b7739bf50b2edcf636c43a8f8910def9

Η μεταβλητή με τη διεύθυνση URL ορίζεται σκληρά στο ίδιο αρχείο:

b7739bf50b2edcf636c43a8f8910def9

Εάν εξετάσουμε τώρα το αρχείο element.js πιο προσεκτικά (μετά την απενεργοποίηση ξανά), βρίσκουμε τη σκληρή καταχώριση c._ctkk - το αντικείμενο google.translate έχει επίσης ρυθμιστεί ανάλογα και ενεργοποιείται η φόρτωση όλων των σχετικών στοιχείων (τα οποία έχουμε ήδη ανακαλύψει νωρίτερα).:

b7739bf50b2edcf636c43a8f8910def9

Τώρα το κλειδί παραμέτρου παραμένει προς εξέταση (με την τιμή AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw). Αυτό φαίνεται να είναι ένα γενικό κλειδί API προγράμματος περιήγησης (το οποίο μπορεί επίσης να βρεθεί σε ορισμένα αποτελέσματα της Google ). Έχει ρυθμιστεί στο Chromium στο αρχείο translate_url_util.cc στα στοιχεία του φακέλου / translate / core / browser:

b7739bf50b2edcf636c43a8f8910def9

Το κλειδί δημιουργείται στο google_apis / google_api_keys.cc από πλαστή τιμή:

b7739bf50b2edcf636c43a8f8910def9

Ωστόσο, μια δοκιμή δείχνει ότι οι κλήσεις API λειτουργούν το ίδιο χωρίς αυτήν την βασική παράμετρο. Εάν πειραματιστείτε με το API, θα λάβετε ξανά τον κωδικό κατάστασης 200 εάν είστε επιτυχής. Εάν στη συνέχεια φτάσετε σε ένα όριο, θα λάβετε ξανά τον κωδικό κατάστασης 411 με το μήνυμα "Τα αιτήματα POST απαιτούν μια κεφαλίδα περιεχομένου ". Επομένως, συνιστάται να συμπεριλάβετε αυτήν την κεφαλίδα (η οποία ορίζεται αυτόματα ως προσωρινή κεφαλίδα στον Ταχυδρόμο).

Η μορφή επιστροφής των μεταφρασμένων χορδών είναι ασυνήθιστη όταν υπάρχουν πολλές προτάσεις σε ένα αίτημα. Οι μεμονωμένες προτάσεις περικλείονται από τις ετικέτες i- / b-HTML:

Επίσης, το Google Chrome δεν αποστέλλει ολόκληρο το HTML στο API, αλλά αποθηκεύει τιμές χαρακτηριστικών όπως href στο αίτημα (και αντίθετα ορίζει δείκτες έτσι ώστε οι ετικέτες να μπορούν να εκχωρηθούν αργότερα από την πλευρά του πελάτη):

Εάν αλλάξετε την τιμή του πελάτη κλειδιού POST από το te_lib (Google Chrome) στο webapp ( ιστότοπος Μετάφρασης Google ), λαμβάνετε την τελική μεταφρασμένη συμβολοσειρά:

Το πρόβλημα είναι ότι είναι πολύ πιο πιθανό να συναντήσετε περιορισμό ρυθμού παρά μέσω te_lib (για σύγκριση: με το webapp αυτό επιτυγχάνεται μετά από 40.000 χαρακτήρες, ενώ το te_lib δεν υπάρχει περιορισμός τιμών ). Επομένως, πρέπει να ρίξουμε μια πιο προσεκτική ματιά στο πώς το Chrome αναλύει το αποτέλεσμα. Θα το βρούμε εδώ στο element_main.js:

b7739bf50b2edcf636c43a8f8910def9

Εάν στείλετε ολόκληρο τον κώδικα HTML στο API, αφήνει τα χαρακτηριστικά στη μεταφρασμένη απάντηση. Επομένως, δεν χρειάζεται να μιμούμαστε ολόκληρη τη συμπεριφορά ανάλυσης, αλλά μόνο να εξαγάγουμε την τελική, μεταφρασμένη συμβολοσειρά από την απάντηση. Για να το κάνουμε αυτό, χτίζουμε έναν μικρό αναλυτή ετικετών HTML που απορρίπτει τις πιο εξωτερικές ετικέτες <i> συμπεριλαμβανομένου του περιεχομένου τους και αφαιρεί τις εξόχως εξωτερικές ετικέτες <b>. Με αυτή τη γνώση μπορούμε τώρα (μετά την εγκατάσταση εξαρτήσεων με τον συνθέτη απαιτείται fzaninotto / faker vielhuber / stringhelper ) να δημιουργήσουμε μια έκδοση διακομιστή του API μετάφρασης:

b7739bf50b2edcf636c43a8f8910def9

Ακολουθούν τα αποτελέσματα μιας αρχικής δοκιμής που πραγματοποιήθηκε σε πέντε διαφορετικά συστήματα με διαφορετικά εύρη ζώνης και διευθύνσεις IP:

ΧαρακτήραςΧαρακτήρες ανά αίτημαΔιάρκειαΠοσοστό σφάλματοςΚόστος μέσω επίσημου API
13.064.662~25003: 36: 17h0%237,78€
24.530.510~25011: 09: 13h0%446,46€
49.060.211~25020: 39: 10 ω0%892,90€
99.074.487~100061: 24: 37ω0%1803,16€
99.072.896~100062: 22: 20 ώρες0%1803,13€
Σ284.802.766~ Ø550Σ159: 11: 37 ώρες0%Σ € 5183,41

Σημείωση: Αυτή η ανάρτηση ιστολογίου που περιλαμβάνει όλα τα σενάρια γράφτηκε μόνο για δοκιμαστικούς σκοπούς. Μην χρησιμοποιείτε τα σενάρια για παραγωγική χρήση, αντί να συνεργαστεί με την επίσημη Μετάφραση Google API .

Πίσω