Google Translation API Hacking

Google, Google Cloud'un bir parçası olarak Google Translation API'yi kullanıma dayalı bir maliyet yapısıyla sunmaktadır . Ayrıca, anahtarsız kullanılabilen, ancak birkaç istekten sonra çalışmayı reddeden belgelenmemiş bir API de vardır. Google Chrome'un web sitesi çeviri işlevini kullanırken, sayfaların önemli bir sınırlama olmaksızın çok iyi kalitede çevrilebildiği dikkat çekicidir.


Görünüşe göre gelişmiş nmt modeli burada zaten kullanılıyor. Ancak Google Chrome, içeriği çevirmek için dahili olarak hangi API'yi kullanıyor ve bu API, sunucu tarafında bile doğrudan adreslenebilir mi? Ağ trafiğini analiz etmek için şifreli trafiği de analiz edebilen Wireshark veya Telerik Fiddler gibi araçlar önerilir. Ancak Chrome, sayfa çevirisi için gönderdiği istekleri de ücretsiz olarak sunar: Bunlar, Chrome DevTools kullanılarak kolayca görüntülenebilir.:

Bir çeviri gerçekleştirirseniz, "Kopyala> cURL (bash) olarak kopyala" yoluyla https://translate.googleapis.com için önemli POST isteğini yakalayın ve bunu Postman gibi bir araçta çalıştırın, örneğin, isteği sorunsuz bir şekilde tekrar gönderebilirsiniz:

URL parametrelerinin anlamı da büyük ölçüde açıktır:

AnahtarÖrnek değerAnlam
Anno3Ek açıklama modu (dönüş biçimini etkiler)
müşterite_libMüşteri bilgileri (değişiklik gösterir, değer Google Translate web arayüzü üzerinden "webapp" dır; iade biçimi ve oran sınırlaması üzerinde etkisi vardır)
biçimhtmlDize biçimi (HTML etiketlerini çevirmek için önemlidir)
v1.0Google Translate sürüm numarası
anahtarAIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgwAPI anahtarı (aşağıya bakın)
logldvTE_20200210_00Protokol versiyonu
sldeKaynak dil
tlenHedef dil
spnmtML modeli
tc1Bilinmeyen
sr1Bilinmeyen
tk709408.812158Jeton (aşağıya bakın)
Moda1Bilinmeyen

Bazı istek başlıkları da ayarlanmıştır - ancak bunlar çoğunlukla göz ardı edilebilir. Kullanıcı aracısından olanlar da dahil olmak üzere tüm başlıkların seçimi manuel olarak kaldırıldıktan sonra, özel karakterler girilirken bir kodlama sorunu keşfedilir (burada " Merhaba Dünya " çevirilirken):

Kullanıcı aracısını yeniden etkinleştirirseniz (ki bu genellikle herhangi bir zarar vermez), API UTF-8 kodlu karakterler sunar:

Zaten orada mıyız ve bu API'yi Google Chrome dışında kullanmak için tüm bilgilere sahip miyiz? Çevrilecek dizeyi (POST isteğinin veri alanı q ) değiştirirseniz, örneğin, "Merhaba dünya" dan "Merhaba dünya ! ", Bir hata mesajı alıyoruz:

Şimdi bu değiştirilmiş olanı web sitesi çeviri işlevini kullanarak Google Chrome'da tekrar çeviriyoruz ve q parametresine ek olarak tk parametresinin de değiştiğini gördük (diğer tüm parametreler aynı kaldı):

Görünüşe göre, dizgeye bağlı olan ve yapısının görülmesi kolay olmayan bir belirteç. Web sitesi çevirisine başladığınızda aşağıdaki dosyalar yüklenir:

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

İki JavaScript dosyası gizlenmiş ve küçültülmüştür. JS Nice ve de4js gibi araçlar artık bu dosyaları daha okunaklı hale getirmemize yardımcı oluyor. Bunlarda canlı olarak hata ayıklamak için, uzaktaki dosyaları anında yerel olarak tünelleyen Chrome Uzantı İsteği'ni öneririz.:

Artık kodda hata ayıklayabiliriz ( CORS önce yerel sunucuda etkinleştirilmelidir). Jetonu oluşturmak için ilgili kod bölümü element_main.js dosyasında bu bölümde gizli görünüyor:

b7739bf50b2edcf636c43a8f8910def9

Burada metin, bazı bit kaydırmalarının yardımıyla karma hale getirilir. Ancak maalesef bulmacanın bir parçasını hala kaçırıyoruz: a argümanına ek olarak (çevrilecek metin), başka bir argüman b de Bp () fonksiyonuna geçirildi - zaman zaman değişiyor gibi görünen ve aynı zamanda bunu da içeren bir tür tohum karma işlemin içine akar. Ama nereden geliyor? Bp () işlev çağrısına atlarsak , aşağıdaki kod bölümünü buluruz:

b7739bf50b2edcf636c43a8f8910def9

Hq işlevi önceden aşağıdaki gibi bildirilmiştir:

b7739bf50b2edcf636c43a8f8910def9

Deobfuscater burada biraz çöp bıraktı; String.fromCharCode ('...') 'yi ilgili karakter dizeleriyle değiştirdikten sonra, kullanılmayan a () ' yı kaldırın ve [c (), c ()] işlev çağrılarını bir araya getirin, sonuç:

b7739bf50b2edcf636c43a8f8910def9

Veya daha da kolay:

b7739bf50b2edcf636c43a8f8910def9

Yq işlevi daha önce şu şekilde tanımlanmıştır::

b7739bf50b2edcf636c43a8f8910def9

Çekirdek , çalışma zamanında kullanılabilen google.translate._const._ctkk genel nesnesinde görünüyor. Ama nereye ayarlandı? Diğerinde , önceden yüklenmiş JS dosyası main_de.js, en azından başlangıçta da mevcuttur. Başına aşağıdakileri ekliyoruz:

b7739bf50b2edcf636c43a8f8910def9

Konsolda aslında mevcut tohumu alıyoruz:

Bu, son seçenek olarak görünüşe göre tohumu sağlayan Google Chrome'un kendisini bırakır. Neyse ki, kaynak kodu (Chromium, Translate bileşeni dahil) açık kaynaktır ve bu nedenle halka açıktır. Depoyu yerel olarak çekiyoruz ve Components / translate / core / browser klasöründeki translate_script.cc dosyasında TranslateScript :: GetTranslateScriptURL işlevinin çağrısını buluyoruz:

b7739bf50b2edcf636c43a8f8910def9

URL'li değişken aynı dosyada sabit olarak tanımlanmıştır:

b7739bf50b2edcf636c43a8f8910def9

Şimdi element.js dosyasını daha yakından incelersek (tekrar gizledikten sonra), sabit ayarlanmış c._ctkk girişini buluruz - google.translate nesnesi de buna göre ayarlanır ve daha önce keşfetmiş olduğumuz tüm ilgili varlıkların yüklenmesi tetiklenir:

b7739bf50b2edcf636c43a8f8910def9

Şimdi parametre anahtarı dikkate alınmak üzere kalır (AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw değeriyle). Bu, genel bir tarayıcı API anahtarı gibi görünüyor (bazı Google sonuçlarında da bulunabilir). Bileşenler / translate / core / browser klasöründeki translate_url_util.cc dosyasında Chromium'da ayarlanmıştır.:

b7739bf50b2edcf636c43a8f8910def9

Anahtar, google_apis / google_api_keys.cc'de sahte bir değerden oluşturulur:

b7739bf50b2edcf636c43a8f8910def9

Ancak bir test, API çağrılarının bu anahtar parametresi olmadan aynı şekilde çalıştığını gösterir. API ile deneme yaparsanız, başarılı olursanız 200 durum kodunu geri alırsınız. Daha sonra bir sınırla karşılaşırsanız, 411 durum kodunu " POST istekleri bir içerik uzunluğu başlığı gerektirir " mesajıyla geri alırsınız. Bu nedenle , bu başlığın dahil edilmesi önerilir (bu, otomatik olarak Postman'da geçici bir başlık olarak ayarlanır).

Tercüme edilen dizelerin dönüş biçimi, bir istekte birden fazla cümle olduğunda alışılmadık bir durumdur. Bireysel cümleler i- / b-HTML etiketlerinin içine alınır:

Ayrıca, Google Chrome HTML'nin tamamını API'ye göndermez, ancak istekte href gibi öznitelik değerlerini kaydeder (ve bunun yerine etiketlerin daha sonra istemci tarafında atanabilmesi için dizinleri ayarlar):

POST anahtar istemcisinin değerini te_lib'den (Google Chrome) değiştirirseniz webapp (on yapıldı web sitesi ), son çevrilen dize almak:

Sorun şu ki, te_lib üzerinden oran sınırlamasıyla karşılaşma olasılığınız çok daha yüksektir (karşılaştırma için: webapp ile buna 40.000 karakterden sonra ulaşılır, te_lib ile hız sınırlaması yoktur). Bu nedenle, Chrome'un sonucu nasıl ayrıştırdığına daha yakından bakmamız gerekiyor. Burada element_main.js'de bulacağız:

b7739bf50b2edcf636c43a8f8910def9

HTML kodunun tamamını API'ye gönderirseniz, öznitelikleri çevrilmiş yanıtta bırakır. Bu nedenle, tüm ayrıştırma davranışını taklit etmemiz gerekmez, yalnızca yanıttan son, çevrilmiş dizeyi çıkarırız. Bunu yapmak için, içerikleri dahil en dıştaki <i> etiketlerini atan ve en dıştaki <b> etiketlerini kaldıran küçük bir HTML etiketi ayrıştırıcısı oluşturuyoruz. Bunu göz önünde bulundurarak, artık çeviri API'sinin sunucu tarafı bir sürümünü oluşturabiliriz:

b7739bf50b2edcf636c43a8f8910def9

Aşağıdakiler, farklı bant genişliklerine ve IP adreslerine sahip beş farklı sistemde gerçekleştirilen ilk testin sonuçlarıdır.:

Karakterİstek başına karakterSüresiHata oranıResmi API üzerinden maliyet
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 €

Not: Tüm komut dosyalarını içeren bu blog gönderisi yalnızca test amacıyla yazılmıştır. Üretken kullanım için komut dosyalarını kullanmayın, bunun yerine resmi ile çalışmak yapıldı API .

Geri