یک بخش از اکوسیستم فنی ادونچر، Observerهایی هستن که شبکههای اجتماعی مختلف رو پایش میکنن و از درست اجرا شدن کمپینها اطمینان حاصل میکنن. همچنین بازخوردها رو جمعآوری میکنن و خلاصه بخش عظیمی از اطلاعاتی که جمعآوری میشن رو مدیون اونها هستیم.
اما برای پایش اینستاگرام، APIهای عمومیای که خودش میداد هم کافی نبود و هم دردسرهای زیادی داشت. اون موقع پس از کلی گشتن به یک Instagram Private API برخوردم که نسخهی PHPش کار ما رو حسابی راه انداخت. این آدرس Repository مربوط به اون API هست، ولی متاسفانه الان برید اونجا میبینید که به خاطر شکایت Facebook بستنش. اگر لازم داشتید با کلیدواژهی «mgp25 Instagram-API» جستوجو کنید و به احتمال زیاد یهجایی گیرش میآرید. این برنامه، با مهندسی معکوس اپلیکیشن اینستاگرام، تمامی ارتباطات اون رو درآورده و عملا شبیهساز اپلیکیشن اینستاگرامه. به عبارتی وقتی از اون استفاده میکنید، خودتون رو یک اپلیکیشن اینستاگرام معرفی میکنید و همون Requestهایی که اپلیکیشن میتونه داشته باشه، اینجا هم در دسترسه.
اما مسئله از جایی شروع شد که من یک Request Call جدید نیاز داشتم که توی اون Private API پیادهسازی نشده بود. ویژگیای که تازگیها به اینستاگرام اضافه شده و به همین دلیل اونجا موجود نبود. و اینجا بود که سفر معنوی ما شروع شد، سفری که گرچه از پشت میز ناهارخوری خونه آغاز شد و همونجا هم ختم، اما سفری بود منالجهل مع الخلق الی الحق!
یا بخت و یا اقبال
اولین کاری که به نظرم اومد، این بود که با توجه به Requestهایی که شبیه به درخواست مورد نیاز من بودن، حدس بزنم این یکی چه شکلیه. بالا پایین کردن آدرس و تغییر پارامترها و ... احتمالا همونطور که حدس میزنید راه به جایی نبرد اما خب آدم باید همهی راههای ممکن رو امتحان کنه :]
اما این مسیر یه مشکل بزرگ هم داشت که باعث میشد خیلی روش تلاش نکنم و به فکر یه روش دیگه باشم. چون شرکت Facebook همین جور هم خیلی خرسند نبود از این که یه عده ادای برنامهشو در میارن، وای به حال اینکه ببینه یکی داره با درخواستهای غلط غلوط این کارو میکنه. و خلاصه هرآینه احتمال داشت اون حساب کاربری رو معلق کنه. این شد که رفتم سراغ راه بعدی.
مکاتبات اداری یا Hello Dear Mgp25
اگر اون Repository معروف هنوز سر جاش بود، احتمالا یک Issue میزدم که این ویژگی رو بهش اضافه کنن. اما خب حالا که نبود باید چیکار میکردم؟ با کلیدواژهی mgp25 سعی کردم بگردم دنبال صاحب عزیزش. توییترش رو پیدا کردم که خب فایدهای نداشت؛ ولی ایمیلش رو از داخل سایتش گیر آوردم و با یک نامهی بلند بالا، ضمن تشکر بابت کد خوبش :] ازش خواستم تا اگه کمکی از دستش بر میاد دریغ نکنه. اما خب، این سنگ در تاریکی هم متاسفانه به هدف نخورد و امروز که سه روز از ایمیلی زدن میگذره، هنوز پاسخی نداده. من خیلی اورژانسیتر از این حرفها به اون ویژگی نیاز داشتم. پس بندهای دمپایی روفرشیم رو سفت کردم و رفتم سراغ راه بعدی.
«چیزی که اتفاق نیافتاده، ممکن است هرگز رخ ندهد؛ اما چیزی که اتفاق افتاد حتماً برای بار دوم هم رخ میدهد»
البته جملهی بالا، جملهای از کتاب «کیمیاگر» نیست، بلکه برداشت آزاد من از اون جملهس. به هر حال اگر کسی یک بار این مهندسی معکوس رو انجام داده، لابد من هم میتونم. شروع کردم به جستوجو در این باب که با برنامهی وزین Charles آشنا شدم. یک proxy عالی که میشینه وسط همهی درخواستهای Http و Https و ریز جزئیاتشون رو براتون مشخص میکنه. با کلی امکان دیگه منجمله Break Point و مداخله و تغییر دستی Requestها و از این دست امکانات. این برنامه خوشبختانه نسخهی رایگان هم داره. البته نسخهی رایگانش نیم ساعت که کار کرد، بسته میشه و باید دوباره اجراش کنید. و خب، واقعا خیال کردن با این کارا میشه از ما پول گرفت؟ :]
قدم بعد این بود که گوشیم رو به این پراکسی وصل کنم تا بتونم درخواستهایی که میفرسته رو ببینم. پس رفتم توی تنظیمات وایفای و شبکهی موجود رو اصلاح (update) کردم تا همهی ارتباطات گوشیم به Charles که روی لپتاپم در حال اجرا بود وصل بشه.
حالا وقت تست کردن فرا رسیده بود! رفتم توی اینستاگرام و اون اطلاعاتی که میخواستم رو با اپلیکیشن گرفتم و بله! توی Carles میتونستم ببینم که Requestهایی داره به دامنهی i.instagram.com ارسال میشه (که این همون دامنهایه که درخواستهای مربوط به private api اینستاگرام به اونجا میرن) همونطور که اگه در دقیقهی ۴۵ یک فیلم سینمایی مشکل حل بشه ما میفهمیم این نباید پایان قضیه باشه، با نگاه به نوار آبیرنگ بالای صفحه متوجه میشید که این پایان ماجرا نبود.
[یک آهنگ هیجانی با ضرب بالا]
وقتی روی درخواستها کلیک کردم دیدم همه <unknown> هستن و هیچی از جزئیاتشون نمیشه فهمید. چرا؟ چون ارتباط اینستاگرام با سرورش با پروتکل ssl امن شده و نمیشه جزئیات بستههای رد و بدل شده رو دید. اصولا قاعدهی Https همینه و چرا تا الان بهش فکر نکرده بودم؟ نکنه Charles با همهی امکاناتش فقط برای درخواستهای Http کارسازه؟ نکنه همهی مسیر غلط بود؟
همونطور که حدس میزنید، این پایان تراژیک ماجرا نبود. چون اگه اینجوری بود احتمالا من این پست وبلاگ رو نمینوشتم. این شد که رفتم دنبال این که چگونه درخواستهای https رو مانیتور کنم.
خوشخبتانه Charles این امکان رو داره که به شیوهی Man at the middle کلید خودش رو به جای سرور قالب کنه و بتونه جزئيات رو ببینه. کافیه روی دامنه راستکلیک کنید و گزینهی Enable SSL Proxying رو بزنید. اما همچنان درخواستها unknown بود، ولی این بار با یک دلیل جدید:
«وقتی در منجلاب جهل نسبت به حل یک مسئله هستم، هر تغییری برای من یک نشانهی مثبته. مطمئنا مسیر بیرون اومدن از منجلاب، چیزی شبیه به پله است و گرچه همچنان در منجلاب هستیم، ولی یک پله بالا رفتیم»
این دفعه چیزی که گفته بود این بود که اپلیکیشن شما، کلیدی که ما میدیم رو معتبر نمیدونه. خب این رو هم میدونستیم که هم Browserها هم اپلیکیشنها حواسشون به حملهی Man at the middle هست و اصولا CAها آفریده شدند تا کلیدها رو اعتبارسنجی کنن. آیا به بست خوردیم؟
[دام دام دیس]
خیر!
کافیه با Browser گوشی (درحالیکه به پراکسی وصل هستیم) آدرس chls.pro/ssl رو بزنیم و فایلی که دانلود میشه رو باز کنیم. اینطوری یک CA جدید تعریف میکنیم که در اصل همون Charles روی لپتاپمون هست. و اون وقت کلیدهایی که Charles میده دیگه معتبر به حساب میآن. محض اطمینان رفتم با کرومِ توی گوشیم یه چیزی رو سرچ کردم و دیدم که بله :) همه چیز درست کار میکنه و جزئيات اون درخواست هم مشخصه (چون میدونیم که جستوجوهای گوگل Https هست) به نظر میاد مسئله حل شده نه؟
[دام دام دیس] خیر!
همچنان با اینستاگرام مشکل داریم و همچنان درخواستها مشاهدهپذیر نیستن. چرا؟ شاید به خاطر کلیدِ پین باشه. خیلی از اپلیکیشنها کلید ارتباط رو درون خود برنامه میذارن تا مطمئن بشن هیچ نفوذی نمیشه. آیا ما به بنبست رسیدیم و همهچیز تمومه؟
«چیزی که اتفاق نیافتاده، ممکن است هرگز رخ ندهد؛ اما چیزی که اتفاق افتاد حتماً برای بار دوم هم رخ میدهد»
لابد نه! حتما یک راهی هست. پس دوباره شروع کردم به جستوجو در مورد مهندسی معکوس اینستاگرام. فهمیدم خوشبختانه Facebook یه امکان گذاشته برای همین مسئله، تا افراد بتونن باگ پیدا کنن و باگ گزارش کنن و این داستانا. برای این کار اول باید وارد Facebook بشید و بعد از ورود، برین به این آدرس:
https://www.facebook.com/whitehat/researcher-settings/
اونجام هرچی تیک دیدید بزنید :] البته من که شوخی کردم، ولی واقعا اگه همهی تیکها رو بزنید کار میکنه.
حالا باید توی اینستاگرامتون با Facebook لاگین کنید. خب از اونجا که ما در عصر عجیبی زندگی میکنیم، برای وصل شدن به Facebook نیاز به چیز عجیبی به نام فیلترشکن! داریم.
پس توی Charles رفتم به Proxy -> External Proxy Settings و اون رو به سایفونم وصل کردم و ... یه چیزی توی این مایهها:
با فیسبوکم لاگین کردم. البته با کلی دردسر و اکانت جدید ساختن و سروکله زدن با I'm not robot و این قبیل اباطیل، اما بالاخره موفق شدم گزینهی Internal رو در منوی Setting اینستاگرامم ببینم. از اونجا باید به بخش Whitehat Setting میرفتم و در نهایت اونجام همهچی رو تیک میزدم :]
بله دوستان. اینجا جا داره مارش پیروزی رو بزنیم. [دیش دارا دام دام دیش دارا دام دام دیش دارا دام]
همونطور که میتونید در تصویر زیر ببینید، من بالاخره به جزئيات درخواستهایی که اپلیکیشن اینستاگرام میداد دست یافتم. البته از اینجا به بعدش هم خودش داستانیه پر از آب چشم، که چگونه از روی جزئیاتی که بهش دست پیدا کردم، توی ساختار کد Mgp25 معروف دست بردم و این Request جدید رو بهش اضافه کردم که خب، در این مقال نگنجد :)