Penggodaman API Terjemahan Google

Google menawarkan API Terjemahan Google dengan struktur biaya berdasarkan penggunaan sebagai sebahagian dari Google Cloudnya. Terdapat juga API tanpa dokumen yang dapat digunakan tanpa kunci , tetapi menolak untuk bekerja setelah hanya beberapa permintaan. Semasa menggunakan fungsi terjemahan laman web Google Chrome, dapat dilihat bahawa halaman dapat diterjemahkan dalam kualiti yang sangat baik tanpa batasan yang nyata.


Nampaknya model nmt canggih sudah digunakan di sini. Tetapi API mana yang digunakan Google Chrome secara dalaman untuk menterjemahkan kandungan dan dapatkah API ini juga ditangani secara langsung - bahkan di sisi pelayan? Untuk menganalisis lalu lintas rangkaian, disyorkan alat seperti Wireshark atau Telerik Fiddler , yang juga dapat menganalisis lalu lintas yang dienkripsi. Tetapi Chrome bahkan menyampaikan permintaan yang dihantarnya untuk terjemahan halaman secara percuma: Mereka dapat dilihat dengan mudah menggunakan Chrome DevTools:

Sekiranya anda menjalankan terjemahan, kemudian tangkap permintaan POST penting untuk https://translate.googleapis.com melalui "Salin> Salin sebagai cURL (bash)" dan jalankannya dalam alat seperti Postman , misalnya, anda dapat mengirim permintaan itu lagi tanpa masalah:

Makna parameter URL juga jelas jelas:

KunciNilai contohMakna
anno3Mod anotasi (mempengaruhi format pengembalian)
pelanggante_libMaklumat pelanggan (berbeza-beza, nilainya adalah "webapp" melalui antara muka web Google Translate; mempunyai pengaruh pada format pengembalian dan pembatasan kadar)
formathtmlFormat rentetan (penting untuk menterjemahkan tag HTML)
v1.0Nombor versi Terjemahan Google
kunciAIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgwKunci API (lihat di bawah)
kayu bulatvTE_20200210_00Versi protokol
sldeBahasa sumber
tlenBahasa sasaran
spnmtModel ML
tc1tidak diketahui
sr1tidak diketahui
tk709408.812158Token (lihat di bawah)
Fesyen1tidak diketahui

Beberapa tajuk permintaan juga ditetapkan - tetapi kebanyakannya boleh diabaikan. Setelah menyahpilih semua tajuk secara manual, termasuk dari ejen pengguna , masalah pengekodan ditemui semasa memasukkan watak khas (di sini semasa menerjemahkan " Hello World "):

Sekiranya anda mengaktifkan semula ejen pengguna (yang umumnya tidak membahayakan), API memberikan watak yang dikodkan UTF-8:

Adakah kita sudah ada dan adakah kita mempunyai semua maklumat untuk menggunakan API ini di luar Google Chrome? Sekiranya anda menukar rentetan watak untuk diterjemahkan (bidang data q permintaan POST) dari, misalnya, "Hello world" ke "Hello world ! ", Kami mendapat mesej ralat:

Kami sekarang menerjemahkan ini diubah semula dalam Google Chrome menggunakan fungsi terjemahan laman web dan mendapati bahawa, selain parameter q , parameter tk juga telah berubah (semua parameter lain tetap sama):

Jelas, itu adalah token yang bergantung pada rentetan, strukturnya tidak mudah dilihat. Apabila anda memulakan terjemahan laman web, fail berikut dimuat:

  • 1 fail CSS: translateelement.css
  • 4 grafik: translate_24dp.png (2x), gen204 (2x)
  • 2 fail JS: main_de.js , element_main.js

Kedua-dua fail JavaScript dikaburkan dan dikurangkan. Alat seperti JS Nice dan de4js kini membantu kami menjadikan fail ini lebih mudah dibaca. Untuk men-debugnya secara langsung, kami mengesyorkan Chrome Extension Requestly, yang menala fail jauh secara tempatan secara cepat:

Sekarang kita boleh menyahpepijat kod ( CORS mesti diaktifkan terlebih dahulu di pelayan tempatan). Bahagian kod yang berkaitan untuk menghasilkan token nampaknya tersembunyi dalam fail element_main.js di bahagian ini:

b7739bf50b2edcf636c43a8f8910def9

Di sini teksnya dicincang dengan bantuan beberapa pergeseran sedikit . Tetapi sayangnya kita masih belum memiliki satu teka-teki: Selain argumen a (yang merupakan teks yang akan diterjemahkan), argumen lain b diteruskan ke fungsi Bp () - sejenis benih yang nampaknya berubah dari semasa ke semasa dan itu juga termasuk mengalir ke hashing. Tetapi dari mana dia datang? Sekiranya kita beralih ke fungsi panggilan Bp () , kita dapati bahagian kod berikut:

b7739bf50b2edcf636c43a8f8910def9

Fungsi Hq dinyatakan sebelumnya seperti berikut:

b7739bf50b2edcf636c43a8f8910def9

Di sini Deobfuscater meninggalkan beberapa sampah; Setelah kita menggantikan String.fromCharCode ('...') dengan rentetan watak masing-masing, lepaskan a () yang usang dan satukan fungsi panggilan [c (), c ()] , hasilnya:

b7739bf50b2edcf636c43a8f8910def9

Atau lebih mudah:

b7739bf50b2edcf636c43a8f8910def9

Fungsi yq sebelumnya ditakrifkan sebagai:

b7739bf50b2edcf636c43a8f8910def9

Benih nampaknya berada di objek global google.translate._const._ctkk , yang tersedia pada waktu runtime. Tetapi di mana ia ditetapkan? Dalam fail JS main_de.js yang dimuat sebelumnya , sekurang-kurangnya ia juga tersedia pada awalnya. Kami menambah yang berikut pada awalnya:

b7739bf50b2edcf636c43a8f8910def9

Di konsol kita benar-benar mendapat benih semasa:

Ini menjadikan Google Chrome sendiri, yang nampaknya memberikan pilihan, sebagai pilihan terakhir. Nasib baik, kod sumbernya (Chromium, termasuk komponen Terjemahan) adalah sumber terbuka dan oleh itu tersedia untuk umum. Kami menarik repositori secara tempatan dan menemui panggilan ke fungsi TranslateScript :: GetTranslateScriptURL dalam fail translate_script.cc dalam folder komponen / translate / core / browser:

b7739bf50b2edcf636c43a8f8910def9

Pemboleh ubah dengan URL sukar didefinisikan dalam fail yang sama:

b7739bf50b2edcf636c43a8f8910def9

Sekiranya kita sekarang memeriksa fail element.js dengan lebih dekat (setelah mendefokusnya lagi), kita dapati entri yang sukar diatur c._ctkk - objek google.translate juga ditetapkan dengan sewajarnya dan pemuatan semua aset yang relevan (yang telah kita ketahui sebelumnya) dicetuskan:

b7739bf50b2edcf636c43a8f8910def9

Sekarang kunci parameter masih dipertimbangkan (dengan nilai AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw). Itu nampaknya merupakan kunci API penyemak imbas umum (yang juga terdapat dalam beberapa hasil Google ). Ia ditetapkan dalam Chromium dalam fail translate_url_util.cc dalam folder folder / translate / core / browser:

b7739bf50b2edcf636c43a8f8910def9

Kuncinya dihasilkan di google_apis / google_api_keys.cc dari nilai dummy:

b7739bf50b2edcf636c43a8f8910def9

Walau bagaimanapun, ujian menunjukkan bahawa panggilan API berfungsi sama tanpa parameter utama ini. Sekiranya anda bereksperimen dengan API, anda akan mendapat kod status 200 kembali jika berjaya. Sekiranya anda mengalami had, anda akan mendapat kod status 411 dengan mesej " Permintaan POST memerlukan tajuk panjang kandungan ". Oleh itu, disarankan untuk memasukkan header ini (yang secara automatik ditetapkan sebagai header sementara di Postman).

Format kembali rentetan yang diterjemahkan tidak biasa apabila terdapat beberapa ayat dalam satu permintaan. Ayat masing-masing dilampirkan oleh tag i- / b-HTML:

Juga, Google Chrome tidak mengirim keseluruhan HTML ke API, tetapi menyimpan nilai atribut seperti href dalam permintaan (dan sebaliknya menetapkan indeks sehingga tag dapat diberikan kemudian di pihak klien):

Sekiranya anda menukar nilai klien kunci POST dari te_lib (Google Chrome) di webapp ( laman web Terjemahan Google ), anda mendapat rentetan terjemahan terakhir:

Masalahnya adalah bahawa anda lebih cenderung mengalami pembatasan kadar daripada melalui te_lib (untuk perbandingan: dengan webapp ini dicapai setelah 40,000 karakter, dengan te_lib tidak ada batasan kadar). Oleh itu, kita perlu melihat lebih dekat bagaimana Chrome menguraikan hasilnya. Kami akan menemuinya di element_main.js:

b7739bf50b2edcf636c43a8f8910def9

Jika anda menghantar keseluruhan kod HTML ke API, ia meninggalkan atribut dalam respons yang diterjemahkan. Oleh itu, kami tidak perlu meniru keseluruhan tingkah laku parse, tetapi hanya mengekstrak rentetan terjemahan terakhir daripada respons. Untuk melakukan ini, kami membina penghurai teg HTML kecil yang membuang teg <i> paling luar termasuk kandungannya dan mengalih keluar teg <b> paling luar. Dengan pengetahuan ini kita kini boleh (selepas memasang kebergantungan dengan komposer memerlukan fzaninotto / faker vielhuber / stringhelper ) membina versi bahagian pelayan API terjemahan:

b7739bf50b2edcf636c43a8f8910def9

Berikut ini adalah hasil ujian awal yang dilakukan pada lima sistem yang berbeza dengan lebar jalur dan alamat IP yang berbeza:

WatakWatak setiap permintaanJangka masaKadar ralatKos melalui API rasmi
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~ Ø550Σ159: 11: 37h0%€ 5183.41

Catatan: Catatan blog ini termasuk semua skrip ditulis untuk tujuan ujian sahaja. Tidak menggunakan skrip untuk digunakan secara produktif, bukan bekerja dengan rasmi API Google Terjemahan .

Belakang