Те, про що я дізнався, зламавши гру Facebook Messenger Soccer

Нещодавно, під час останнього чемпіонату Європи з футболу, Facebook представив невеличку гру в програмі Messenger, яка змушує вас втрачати години і години, незважаючи на свою простоту.

Якщо ви цього не помітили, прочитайте цю статтю про Mashable.

Я повинен визнати ... Я цілком відмовляю цю гру, тому мій найкращий результат - 9 .

Але, як розробник, найкраще, що я міг зробити, це перемогти своїх друзів, зламавши гру.

Я справді думав, що це буде просто.

Перший спосіб: слухати запити HTTP (s)

Розробляючи програми, ви відразу розумієте, що вам потрібен інструмент налагоджувача HTTP для аналізу вхідного / вихідного трафіку для ваших API.

Чарльз- найкращий інструмент, який я знайшов для виконання цього завдання. Він має дуже інтуїтивно зрозумілий інтерфейс, і ви можете легко використовувати його для налагодження та зворотного інжинірингу.

Це мало закінчитися на цьому етапі: мені довелося б проаналізувати API, який використовував додаток Facebook, і просто відтворити його за допомогою CURL під час редагування даних та балів, що надсилаються на сервер.

Звичайно, виклики API знаходяться в протоколі HTTPS, тому вони зашифровані .. але Чарльза можна використовувати як проксі-сервер HTTPS, який надає можливість посередника, що дозволяє переглядати у звичайному тексті зв'язок між веб-браузером та веб-сервером SSL .

Ідеально! Тож я встановив на iPhone кореневий сертифікат Чарльза і спробував перевірити трафік. Але всі виклики HTTP до серверів Facebook були відхилені заздалегідь під час фази рукостискання SSL.

Проводячи деякі дослідження, я виявив, що деякі додатки компанії, такі як Facebook та Google, використовують додатковий рівень безпеки, щоб гарантувати, що сертифікат, наданий віддаленим сервером, є тим, який очікується. Цей прийом називається Закріплення сертифіката.

Ви можете легко це зробити, включивши у програму відкритий ключ сертифіката віддаленого сервера, щоб було легко перевірити ідентичність клієнта для кожного запиту HTTPS.

Цей прийом робить недійсним напад "Людина посередині" (MITM).

Чудова робота Facebook! Але ... (пам’ятайте, завжди є але, але) є спосіб відключити закріплення сертифіката SSL за допомогою деяких системних налаштувань, доступних лише на зламаному пристрої.

Перший спосіб (вдосконалений): розблокуйте пристрій і встановіть iOS SSL Kill Switch

Наразі на моєму iPhone працює iOS 9.x, тож на момент написання цієї статті втечу з в’язниці було неможливим. Тож я взяв старий iPad mini під управлінням iOS 8.3.x і легко розбив його за допомогою інструменту TaiG .

Шукаючи в Інтернеті, я знайшов SSL Kill Switch 2, інструмент Blackbox для відключення перевірки сертифіката SSL у програмах iOS та OS X.

Після завантаження в додаток iOS або OS X, SSL Kill Switch 2 виправляє певні низькорівневі функції SSL в API безпечного транспорту, щоб замінити та відключити перевірку сертифіката за замовчуванням, а також будь-яку перевірку власного сертифіката (наприклад, закріплення сертифіката).

Комутатор SSL Kill використовує MobileSubstrate для виправлення системних функцій, таких як API безпечного транспорту. Вони є найнижчим рівнем реалізації TLS на iOS.

Це означає, що вимкнення перевірки сертифіката SSL в API безпечного транспорту повинно вплинути на більшість (якщо не на всі) мережевих API, доступних у рамках iOS.

Будь ласка, зробіть собі послугу і дотримуйтесь цього блогу, який висвітлює всі ці поняття.

Отже, я підключився до iPad за допомогою SSH і встановив пакет:

wget //github.com/nabla-c0d3/ssl-kill-switch2/releases/download/0.10/com.nablac0d3.SSLKillSwitch2_0.10.deb --no-check-certificatedpkg -i com.nablac0d3.SSLKillSwitch2_0.10.debkillall -HUP SpringBoard

Після перезавантаження я очікував побачити простий трафік, але це було оптимістичне бачення: я отримав ті самі помилки.

Я пробував цей шлях ще годину. Я десь читав, що Facebook і Twitter використовують протокол SPDY для своїх дзвінків через API, і це може бути проблемою для Чарльза. Тож я встановив ще один твік, який (теоретично) відключив протокол SPDY, але він не спрацював.

Голод.

Переглядаючи проблеми проекту, я помітив, що хтось ще мав ту саму проблему (//github.com/nabla-c0d3/ssl-kill-switch2/issues/13), не маючи дозволу.

Пауза.

Другий спосіб: імітувати події дотику в додатку

Я зрозумів, що існує багато ігрових чітів, які використовують «людський» підхід: імітують сенсорні події (однією з найпопулярніших ігор, на якій багато ігрових чітів використовують цю стратегію, є Clash of Clans).

Переглядаючи Інтернет за допомогою інструменту, який автоматизує ці операції, я знайшов цей приголомшливий твік - AutoTouch. Він може записувати події людського дотику та зберігати дані у сценарії LUA. Потім ви можете редагувати цей створений сценарій і імітувати все, що завгодно, де завгодно на своєму пристрої.

Після встановлення разом із Cydia я зберег знімок екрана BMP програми Messenger із видимим кулькою та отримав координати, де слід натиснути.

Я думав, що, клацнувши точно в центрі осі X кульки, мені залишалося лише імітувати повторювані події дотику в тих самих координатах, а потім зупиняти сценарій, коли я мав оцінку, якою я був задоволений.

Ось що я написав для досягнення цієї мети:

adaptResolution(768, 1024);adaptOrientation(ORIENTATION_TYPE.PORTRAIT);
for i=1,2000 do
 touchDown(1, 544, 954); usleep(66000); touchUp(1, 544, 954);
 usleep(10000);
end

Ні, це не спрацювало.

Ймовірно, розробники Facebook ввели випадкову помилку в координатах дотику, щоб краще імітувати гру або запобігати сценаріям такого типу.

Або, можливо, я просто клацнув на неправильному пікселі.

Отже, для другого шансу я спробував змоделювати декілька клацань на більшій площі, але без удачі. Іноді я моделював стільки сенсорних подій, що трамплін просто розбивався через помилки пам'яті .

Замість того, щоб натискати однакові координати кожного разу, я спробував краще підійти.

Reading the AutoTouch documentation, I found the following two methods:

  • findColor (color, count, region) - Search the coordinates of the pixel points matching the specified color on the current screen.
  • getColor (x, y) - Get the color value of the pixel point of the specified coordinate on the current screen.

The idea was to find a unique color inside the ball, and use the findColor method to get the coordinates of the ball in that moment, to simulate a touch event.

adaptResolution(768, 1024);adaptOrientation(ORIENTATION_TYPE.PORTRAIT);
local c = getColor(544, 954);
for i=1,2000 do local r = findColor(c, 0, {400, 500, 768, 1024});
 for i, v in pairs(r) do touchDown(1, v[1], v[2]); usleep(66000); touchUp(1, v[1], v[2]); usleep(10000); end
end

I don’t know why, but it simply didn’t work. Maybe the findColor is too slow to intercept the ball, which then makes the script useless.

The third way: Reverse engineer the app

I don’t have good native skills in Objective C, but I remember (when I played with the jailbreak ~4 years ago) that there was a tool by Saurik that could inject itself into iOS processes.

It is released along with Cydia and was called Cycript.It allowed developers to explore and modify running applications on iOS, by injecting code at run time.

I read some basic tutorials on how to use it, and after a few struggles, I decided to follow this (another) way.

Once you login via SSH into your iOS device, you can easily attach to a process just by typing:

cycript -p Messenger

I tried to inspect some basic UI classes like UIApp, but didn’t find anything interesting. Then I made a complete class dump, filtering it for the keyword soccer.

var C = Object.keys(ObjectiveC.classes);var soccer_classes = []; for (var i = 0; i < C.length; i++) C[i].match(/soccer/i) && soccer_classes.push( C[i] );

It was a slow process.

Я виявив, що Facebook Messenger має дуже велику кількість класів.

Але, врешті-решт, я отримав невеликий список.

Отримавши імена класів, я використав сценарій для друку всіх методів класу, і, перевіривши клас MNSoccerGame , отриманими методами стали:

Примітка: Я все ще не розумію, що таке метод wasCheatDetected.

Тепер, коли у мене був повний перелік методів класу, я вирішив замінити метод _setScore , сподіваючись, що інші методи цього не помічають.

Для цього я використав MobileSubstrate та його метод MS.hookMessage .

@import com.saurik.substrate.MS; 
var _setScore_pointer = {}; MS.hookMessage(MNSoccerGame, @selector(_setScore:), function(arg0) { return _setScore_pointer->call(this, 9999); }, _setScore_pointer);

Тепер ви можете просто зіграти, програти і в будь-якому випадку забити новий рекорд.

Що я дізнався

Never stop yourself. Always try and discover new way to accomplish the same thing. I know, it’s just a game, but if you treat the problem you’re trying to solve like a challenge, you’ll get much more than the satisfaction of beating your friends.