Това, което научих, хаквайки играта 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 сертификата, като използвате някои системни ощипвания, достъпни само в затворено устройство.

Първият начин (подобрен): Jailbreak устройство и инсталирайте 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 на Secure Transport, за да замени и деактивира проверката на сертификата по подразбиране на системата, както и всякакъв вид валидиране на персонализирани сертификати (като например сертифициране).

SSL Kill Switch използва 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.