воскресенье, 25 октября 2015 г.

Лето призов - реверс Flash и кодинг

В данной статье я буду реверсить Flash приложение от PepsiCo которые устроили акцию с азартными играми и куртизанками ценными призами. На этот раз всё будет на много интереснее и захватывающе.


В данной статье я расскажу как декомпилировать Flash приложения, реверсить алгоритмы подписи запросов и подменять данные в браузере.


Введение

 

Да, опять я ввязался в какую то авантюру, но на этот раз более интересную чем читос. Тут всё на много сложнее.  В начале акции был баг который позволял без особого труда вписать любые цифры, чем я и пользовался:



И не только я. Но потом это прикрыли, добавив странную подпись, хотя как видно на скрине выше - меня не выкинули из топа. Ну а раз они кладут на всех и вся - можно смело пилить вычислялку хеш-суммы которая нужна для подписи запросов.


Инструментарий 

 

  1. 7-zip с поддержкой LZMA (неожиданно?)
  2. Sothink SWF Decompiler (для анализа приложения)
  3. Tamper Data для Firefox (для перехвата запросов)
  4. HTTP Analyzer (для перехвата запросов)
  5. Delphi (но можно и руками)
  6. Download Flash для Firefox (для скачивания игры с сайта)
Ссылки на платные софтины не даю, торренты в помощь. 


Декомпиляция

 

Для начала необходимо скачать с сайта акции newmatch3.swf который весит 6,29мб и представляет собой архив! Да да, это флешка сжатая алгоритмом LZMA для уменьшения веса! на самом деле эта дрянь весит аж:


Ну ладно, спасибо что сжали. Далее извлекаем упакованную флешку и можно смело отправлять в декомпилятор:


После не долгих поисков я нашёл модуль отвечающий за взаимодействие с сайтом.  На скрине виден ключ подписи, забегая вперёд скажу, что только он не меняется, всё остальное нас не интересует т.к. это придётся получать и генерировать.

Анализ

 

Первым делом уходит запрос на _letoprizov.ru/api/games/start (опять API, да что же это такое!) и в результате мы получаем ответ следующего содержания:


Где token - новый токен для подписи запросов, по этому старый (который прописан в игре) нам был не нужен. На рисунке ниже представлен участок кода где происходит копирование нового токена в глобальную переменную:


Если запрос прошёл - игра передаёт управление второй функции под названием OnCompleteStartGame, которая парсит JSON и раскидывает параметры по соответствующим переменным, кстати, не фильтруя их (если вы понимаете о чём я).

Раз мы знаем все ключи, то что нам мешает сделать подпись? Давайте разбираться:


Мы знаем 4 параметра: globalScore (общий счёт), globalBonusPoint (бонусы), skey ("секретный" ключ) и token (уникальная строка).
На скриншоте выше видно, что из globalScore вычитается globalBonusPoint, затем это число переводится в строку, склеивается с skey и token, а результат всех этих телодвижений загоняется в SHA1 и передаётся дальше.
А дальше хеш-сумма полученная выше склеивается с какой то хренью (между прочим, самый распространённый вид хрени). По этому поищем переменную comb чуть выше, и найдём следующую функцию:

И на этом наши старые ниточки обрываются, зато появляется новая: AddComb - функция которая формирует эту строку. Давайте при помощи глобального поиска поищем где вызывается данная функция:


Сразу в трёх местах, но с разными значениями которые передаются в функцию ScoreComp_SymSend_Int32, давайте посмотрим эту функцию поближе:


А вот это уже интересно! Мы могли наблюдать в Tamper Data запрос с буквами из этих массивов, но что они значат? Давайте разберёмся:

В игре есть 3 комбинации кубиков - 3, 4 и 5. В зависимости от того, сколько кубиков мы собрали вместе - игра передаёт это число функции SymSend, а она, при помощи конструкции switch case, переходит в нужную ветку. Допустим мы собрали 4 кубика вместе (это 200 очков) и переходим в ветку 4, где из массива _loc_3 берётся рандомная буква/число которое обозначает 200 очков. Вот оно! Теперь мы знаем как генерируется эта строка и самое главное мы знаем набор букв/цифр которые обозначают количество очков 100, 200 и 300.

Осталось посмотреть как завершается игра, тут всё как всегда просто:



Практика

 


Вот и пришло время собрать все строки, знания и факты воедино.

1. Предположим мы получили такой токен:
Gm6iTQZOGgTOSRNqsDNkb9CLuHG7NnNL
gih8wPWnGv1rQaCgD/jA3WLo0md6+O+j03UVo
Hy9Jc8PIePEGCvmxw==

2. Придумаем количество очков, пусть будет 182200

3. Возьмём "секретный" ключ из приложения:

f18a9bb45287c96b568bc6fdf16e267b

4. Соберём строку из количества очков, секретного ключа и токена, в результате получим следующий результат:

182200f18a9bb45287c96b568bc6fdf16e267bTtXd2Muwsma
YiHGjOZFHOP0vLY081xBaxNgOYy32WwxXFb6w65eXc
1rIFiJaAkwK0wq7Pm1IxkaluMufM49Xyg==
 5. Получим хеш-сумму склеенной в пункте 4 строки:

SHA1:752b5dc67ece78b86cb2aec83fa8e69394c797ca
6. Тут придётся изрядно потрудится и составить строку из символов которые соответствуют количеству вписанных очков. Затем собственноручно сгенерированную строку склеить с хешем и отправить на сайт.


Пишем генератор



Алгоритм мы знаем, а значит нам не составит труда закодить не большую утилиту для генерации подписи. Но для начала давайте сделаем функцию проверки подписи:


Для работы этой функции требуются 3 массива:


Вот и всё! Далее напишем функцию которая будет склеивать введённый токен со всеми остальными значениями:


Данная функция очень умно распределяет комбинации, 100 очков всегда добавляются, 200 очков с меньшей вероятностью и 300 очков очень и очень редко потому что должно совпасть рандомное число от 50 и от 58, что происходит крайне редко - прям как в игре. Увеличивая числа - мы уменьшаем вероятность совпадения двух рандомных чисел.

Что бы получить SHA1 хеш я воспользовался бесплатной библиотекой DCPCrypt2, код отвечающий за генерацию подписи представлен на рисунке ниже:


Тут как писалось выше - склеивается 3 строки и вычисляется хеш.


Подделка запросов



Для того, что бы подделать запрос, необходимо его перехватить. Для перехвата можно воспользоваться плагином Tamper Data или другим подходящим инструментом.

Шаг первый. Запускаем любой сниффер (я использовал HTTPAnalyzer) и стартуем игру для того, что бы перехватить токен.

Шаг второй. Запускаем Tamper Data (Alt => инструменты => перехват данных)

Шаг третий. Вводим в программу желаемое кол-во очков и токен:


Нажимаем "Encode" и программа сгенерирует правдоподобную раскладку игры, всё это склеит и вычислит хеш сумму, останется только скопировать.

Шаг четвёртый. Запускаем перехват и наблюдаем следующее окно:


Снимаем галочку что бы нас не беспокоили и нажимаем "вмешаться".

Шаг пятый. Меняем данные POST запроса на свои, которые сгенерировала программа.


И нажимаем "ОК". В результате имеем довольно не плохие показатели! И самое главное - не забывайте ждать перед отправкой запроса, ведь заработать миллион очков за 5 минут не возможно и вы будете выкинуты из топа.


Заключение

 

Вот и закончилась акция, купоны были отданы нуждающимся... хотя кого я обманываю, все купоны которые были получены я толкнул за пол цены и получил не плохой доход. Ещё раз мы убеждаемся что нагнуть такие акционные сайты не составляет больших проблем когда есть знания flash и Delphi!

Ссылки на программу и флешку не прикладываю ибо это уже не актуально.

5 комментариев:

  1. Норм. Но фидлер по моему лучше будет.

    ОтветитьУдалить
  2. а можно из HTTP Analyzer подменить отправляемый запрос ?

    ОтветитьУдалить
  3. )) здорово!
    ___
    не понял где там написать, пишу тут
    нужен бот для сайта pumpyt.com , который бы с второго аккаунта плюсовал бы карму, дедики с кликером подыхают help!

    ОтветитьУдалить