هک کردن API ترجمه Google

Google به عنوان بخشی از Google Cloud خود ، API ترجمه Google را با ساختار هزینه مبتنی بر استفاده ارائه می دهد. همچنین یک API فاقد سند وجود دارد که می تواند بدون کلید استفاده شود ، اما فقط پس از چند درخواست از کار خودداری می کند. هنگام استفاده از عملکرد ترجمه وب سایت Google Chrome ، قابل توجه است که صفحات را می توان بدون هیچ محدودیت قابل توجهی با کیفیت بسیار خوب ترجمه کرد.


ظاهراً در اینجا از مدل پیشرفته nmt استفاده شده است. اما Google Chrome از کدام API به صورت داخلی برای ترجمه محتوا استفاده می کند و آیا این API می تواند مستقیماً مورد خطاب قرار گیرد - حتی در سمت سرور؟ برای تجزیه و تحلیل ترافیک شبکه ، ابزارهایی مانند Wireshark یا Telerik Fiddler ، که می توانند ترافیک رمزگذاری شده را نیز تجزیه و تحلیل کنند ، توصیه می شود. اما Chrome حتی درخواست هایی را که برای ترجمه صفحه ارسال می کند به صورت رایگان تحویل می دهد: با استفاده از Chrome DevTools می توان به راحتی آنها را مشاهده کرد:

اگر ترجمه ای انجام دادید ، درخواست POST مهم را از طریق "Copy> Copy as cURL (bash)" به https://translate.googleapis.com برسانید و آن را در ابزاری مانند Postman اجرا کنید ، به عنوان مثال ، می توانید دوباره درخواست را بدون مشکل ارسال کنید:

معنای پارامترهای URL نیز کاملاً واضح است:

کلیدمقدار مثالمعنی
دلخوری3حالت حاشیه نویسی (بر شکل بازگشت تأثیر می گذارد)
مشتریte_libاطلاعات مشتری (متفاوت است ، مقدار از طریق رابط وب Google Translate "webapp" است ؛ در قالب بازده و محدودیت نرخ تأثیر دارد)
قالبhtmlقالب رشته (برای ترجمه برچسب های HTML مهم است)
v1.0شماره نسخه Google Translate
کلیدAIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgwکلید API (زیر را ببینید)
logldvTE_20200210_00نسخه پروتکل
اسلدزبان مبدا
tlenزبان مقصد
spnmtمدل ML
تی سی1ناشناخته
sr1ناشناخته
tk709408.812158نشانه (نگاه کنید به زیر)
روش1ناشناخته

برخی از عناوین درخواست نیز تنظیم شده اند - اما این موارد عمدتا قابل چشم پوشی هستند. پس از لغو انتخاب دستی همه عناوین ، از جمله عناوین مربوط به عامل کاربر ، هنگام وارد کردن نویسه های خاص ، مشکلی در رمزگذاری کشف می شود (اینجا هنگام ترجمه " سلام به جهان "):

اگر عامل کاربری را دوباره فعال کنید (که به طور کلی هیچ آسیبی نمی رساند) ، API نویسه های رمزگذاری شده UTF-8 را ارائه می دهد:

آیا ما در حال حاضر آنجا هستیم و آیا همه اطلاعات استفاده از این API در خارج از Google Chrome را داریم؟ اگر رشته کاراکتر ترجمه شده (فیلد داده q درخواست POST) را از مثلاً "Hello world" به "Hello world ! " تغییر دهید . "، ما یک پیام خطا دریافت می کنیم:

ما اکنون با استفاده از عملکرد ترجمه وب سایت ، این مورد تغییر یافته را مجدداً در گوگل کروم ترجمه کرده و متوجه می شویم که علاوه بر پارامتر q ، پارامتر tk نیز تغییر کرده است (سایر پارامترها ثابت مانده اند):

بدیهی است که این توکن به رشته ای بستگی دارد که ساختار آن به راحتی قابل مشاهده نیست. هنگام شروع ترجمه وب سایت ، فایل های زیر بارگیری می شوند:

  • 1 پرونده CSS: translateelement.css
  • 4 گرافیک: translate_24dp.png (2x) ، gen204 (2x)
  • 2 پرونده JS: main_de.js ، element_main.js

دو فایل جاوا اسکریپت مبهم و کوچک شده اند. ابزارهایی مانند 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

به نظر می رسد این دانه در شی global جهانی google.translate._const._ctkk قرار دارد که در زمان اجرا در دسترس است. اما کجا تنظیم شده است؟ در پرونده اصلی ، پرونده JS main_de.js که قبلاً بارگیری شده است ، حداقل در ابتدای آن نیز موجود است. موارد زیر را در ابتدا اضافه می کنیم:

b7739bf50b2edcf636c43a8f8910def9

در کنسول ما واقعاً دانه فعلی را بدست می آوریم:

این خود گوگل کروم ، که ظاهراً دانه را ارائه می دهد ، به عنوان آخرین گزینه باقی می ماند. خوشبختانه کد منبع آن (Chromium ، از جمله ملفه Translate) منبع باز است و بنابراین در دسترس عموم است. ما مخزن را به صورت محلی می کشیم و فراخوانی عملکرد TranslateScript :: GetTranslateScriptURL را در فایل translate_script.cc در پوشه کامپوننت ها / ترجمه / هسته / مرورگر پیدا می کنیم:

b7739bf50b2edcf636c43a8f8910def9

متغیر دارای URL در همان پرونده به سختی تعریف شده است:

b7739bf50b2edcf636c43a8f8910def9

اگر اکنون پرونده element.js را با دقت بیشتری مورد بررسی قرار دهیم (پس از رفع اشکال دوباره آن) ، ورودی سخت تنظیم شده c._ctkk را پیدا خواهیم کرد - شی google.translate نیز بر این اساس تنظیم شده و بارگیری تمام دارایی های مربوطه (که قبلاً قبلاً کشف کرده ایم) شروع می شود:

b7739bf50b2edcf636c43a8f8910def9

اکنون کلید پارامتر برای بررسی باقی مانده است (با مقدار AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw). به نظر می رسد این یک کلید عمومی API مرورگر است (که در برخی از نتایج Google نیز یافت می شود). این در Chromium در فایل translate_url_util.cc در پوشه کامپوننت ها / ترجمه / هسته / مرورگر تنظیم شده است:

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> از جمله محتوای آنها را کنار می گذارد و بیرونی ترین برچسب ها را حذف می کند. با این حساب ، اکنون می توانیم نسخه سمت سرور API ترجمه را بسازیم:

b7739bf50b2edcf636c43a8f8910def9

در زیر نتایج یک آزمایش اولیه است که روی پنج سیستم مختلف با پهنای باند و آدرس IP مختلف انجام شده است:

شخصیتکاراکتر در هر درخواستمدت زماننرخ خطاهزینه از طریق API رسمی
13.064.662~25003: 36: 17 ساعت0%237,78€
24.530.510~25011: 09: 13 ساعت0%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

توجه: این پست وبلاگ شامل همه اسکریپت ها فقط برای اهداف آزمون نوشته شده است. هنوز اسکریپت برای استفاده از مولد استفاده کنید، به جای با رسمی کار API ترجمه گوگل .

بازگشت