Order Of Six Angles

Main Logo

A security researcher's blog about reverse-engineering, malware and malware analysis

Home | RU | Translations | Tools | Art | About

3 April 2019

tags: android

Собираем базу номеров с приложения Pootin

Intro

Впервые я рассказал об этом в презентации на 2600-Qazaqstan (08.08.18), на тот момент приложение уже не функционировало и я свободно мог рассказать, как его парсить.

Все вы слышали о GetContact, приложении позволяющем посмотреть, как вы подписаны в телефонной книге у других людей. В свое время оно наделало много шума, например его заблокировали в Казахстане. Сразу же после выхода этого приложения, казахстанские разработчики выпустили свой аналог, под названием Pootin, с тем же функционалом, но с более обширной базой данной пользователей. На то время, защита от реверса в Pootin была на уровень выше, чем в GetContact, что немного удивило. Но ничего страшного!

Анализируя мобильные приложения, мы делаем все по классике, закидываем сертификат burp на эмулятор, и запускаем там приложение. SSL pinning отсутствовал. Функционал приложения прост - вы вводите номер телефона в поле, вам выдается список имен.

Вот так выглядит запрос по конкретному номеру телефона:

Сервер нам отвечает:

В запросе, нас особо интересует следующее:

AUTH TOKEN

CSRF TOKEN

Если мы посмотрим внимательней на CSRF токен

Похоже на unix timestamp, не правда ли?

Возьмем первые 10 цифр и сконвертируем

Да, похоже на правду! Если сделать несколько запросов, то можно заметить букву ‘a’ на конце

Итак, что имеем на данный момент?

Для этого, обратимся к исходникам. Получить их можно, декомпилировав apk.

Делаем поиск строки ‘csrf’ по исходникам (да, это total commander)

Видим вот такой вот метод AppConstants.INSTANCE.getCsrfToken()

Откроем же наконец исходник AppConstant

Внутри вызывается метод с модификатором native. Модификатор native означает, что реализация метода находится в библиотеках, написанных на других языках. Чтобы работать с такими библиотеками, используется механизм JNI (Java Native Interface). Это значит, что приложение использует внешнюю библиотеку, которая генерит csrf токен.

Делаем поиск по исходникам по слову ‘loadlibrary’ или же ‘lib’, в надежде найти место, где подгружаются какие-нибудь библиотеки.

Или же тупо распаковываем apk и смотрим папку lib

Открываем библиотеку в IDA, открываем окно Functions (Shift + F3), видим нашу функцию

Тело функции

После того, как мы получил UNIX timestamp, мы умножаем его на 1000, чтобы получить миллисекундную часть. Поэтому наш timestamp становится длиной 13 символов.

На предыдущем шаге мы соединили timestamp (включая секунды) с “TtaaTTaaRaUaNTTaaTTaab”. Затем вызываем метод getMd5() из AppConstants, хэшируем результирующую строку. В итоге получаем 32 байта хэша.

Длина всей строки с csrf токеном равна 46 Первые 10 символов — время запроса Последний символ — буква ‘а’ Откуда берутся остальные 35 символов?

Ответ:

Итоговый скрипт:

salt  = r"TTaaTTaaRaUaNTTaaTTaab"

def getSalt():

    ts = int(time.time()*1000)

    h = hashlib.md5()

    h.update(b"%d%s" % (ts, salt.encode()))

    return "%d%sa" % (ts, h.hexdigest())
Вверх