• XSS.stack #1 – первый литературный журнал от юзеров форума

[Статья] Как реверсить Protobuf

KERNELRW

RAM
Пользователь
Регистрация
25.10.2020
Сообщения
134
Реакции
64
0x00 Введение

Иногда при реверсе мобильных приложений в отснифанном трафике встречаются непонятные зашифрованные запросы и если вы раньше не сталкивались с ними то вам будет очень тяжело понять что же делать.

Что такое Protobuf?

Protocol Buffers — протокол сериализации структурированных данных предложенный Google.
На странице проекта Google Protocol Buffers описывается как «не зависящий от языка и платформы расширяемый механизм для сериализации структурированных данных». Также там есть пояснение: «Как XML, но меньше, быстрее и проще».
И хотя одним из преимуществ Protocol Buffers является поддержка различных языков программирования, в этой статье речь пойдет про реверс инжиниринг этого протокола, который я часто встречаю в Java приложениях и скомпилированном C++ коде.


0x01 Как понять что приложение использует Protobuf?

Это бинарный формат. Для тех кто знаком с языком си, это почти тот же struct, отправляемый по сети. Информация о типах данных хранится в файле .proto, скомпилированном под нужную платформу и не передается в запросе, клиент и сервер уже имеют этот файл заранее.

Пример исходного кода файла .proto:

SCSS:
syntax = "proto3";

option java_outer_classname = "AlbumProtos";
option java_package = "com.examples.protobuf";

message Album {
    string title = 1;
    repeated string artist = 2;
    int32 release_year = 3;
    repeated string song_title = 4;
}

Здесь ключевое слово "message" определяет структуру "Album", которую мы хотим представить. В ней есть четыре поля, три из которых строки (string), а одно — целое число (int32). Два из них могут присутствовать в сообщении более одного раза, так как для них указано зарезервированное слово repeated.

После компиляции файл превращается в Java-класс в случае Java или в .pb.cc и .pb.h в случае C++, понять что используется данный протокол можно по наличию "com.google.protobuf" в декомпиляторе jadx, методов SerializeToString()/ParseFromString() в результатах декомпиляции IDA Pro, а так же по наличию заголовков Content-Type: application/x-protobuf или application/x-google-protobuf в отснифанных через Fiddler или Charles HTTP-запросах.

Окей, в чем тогда загвоздка? Поскольку исходный файл .proto не используется приложением напрямую, а используется только для создания шаблона, десериализовать фрагмент данных, не зная его формата, не так уж и просто.


0x02 Реверсим протокол как бог

Мы будем использовать библиотеку pbtk для реверс-инжиниринга и восстановления оригинальных структур .proto и Charles для просмотра расшифрованных сообщений

PBTK требует Python ≥ 3.5, PyQt 5, Python-Protobuf 3 и несколько программ (chromium, jad, dex2jar...) для запуска скриптов экстрактора.

Установка

Bash:
# linux:
sudo apt install python3-pip git openjdk-9-jre libqt5x11extras5 python3-pyqt5.qtwebengine python3-pyqt5

# macOS:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew tap AdoptOpenJDK/openjdk
brew install python git adoptopenjdk/openjdk/adoptopenjdk-openjdk9 qt@5

# Windows:
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "[System.Net.ServicePointManager]::SecurityProtocol = 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
choco install python3 git openjdk11 qt5-default

python3 -m ensurepip
pip3 install protobuf pyqt5 pyqtwebengine requests websocket-client

git clone https://github.com/marin-m/pbtk
cd pbtk
python3 ./gui.py

Для примера откроем Android-приложение. После недолгого изучения приложения с помощью своего любимого декомпилятора мы выяснили, что оно передает Protobuf как данные POST по HTTPS.

website


Первый шаг который нам нужно сделать — преобразовать файлы .proto в текстовый формат. Загрузим APK и подождем, PBTK выдаст результат.

website


После этого переходим в папку ~/.pbtk/protos/<ваш APK> (или %APPDATA%\pbtk\protos в Windows). Все .proto файлы действительно здесь.

Вернувшись в Jadx или любой другой декомпилятор, мы находим класс, который создает данные, отправляемые на интересующий нас HTTPS-адрес. Он сериализует сообщение Protobuf, вызывая класс из сгенерированного Java-кода.

Java:
package com.examples.protobuf;

import java.util.ArrayList;
import java.util.List;

/**
 * Music album.
 */
public class Album {
    private final String title;

    private final List < String > artists;

    private final int releaseYear;

    private final List < String > songsTitles;

    private Album(final String newTitle, final List < String > newArtists,
        final int newYear, final List < String > newSongsTitles) {
        title = newTitle;
        artists = newArtists;
        releaseYear = newYear;
        songsTitles = newSongsTitles;
    }

    public String getTitle() {
        return title;
    }
 
    ...

Этот класс будет соответствовать файлу .proto внутри папки ~/.pbtk/protos/<ваш APK> (т.е. com.foo.bar.a.b будет соответствовать com/foo/bar/a/b.proto).

Следующим шагом будет выбор желаемого входного .proto и заполнение информации о запросе.

website


Мы также можем засунуть образец необработанных данных Protobuf, которые были отправлены на сервер, вытащив их из пакетов Charles и вставив в шестнадцатеричном формате.

Теперь мы можем просмотреть древовидное представление, представляющее каждое поле в структуре Protobuf (повторяющиеся поля имеют суффикс «+», обязательные поля не имеют плюса).

website


И мы можем тыкать на разные кнопки, изменяя структуру и переименовывать поля щелкнув по ним.


0x03 Использование .proto

Отлично, мы извлекли .proto файлы, но для Charles нам нужны .desc. Для этого установим protoc и запустим команду

Bash:
# linux
sudo apt install protobuf-compiler

# macOS
brew install protobuf

# Windows
choco install protoc

~/.pbtk/protos/<ваш APK>/com/foo/bar/a/
protoc -oModel.desc Model.proto

Открываем Charles

Выберите Viewer Mappings в меню View.

Включите Viewer Mappings, добавьте новый маппинг и выберите Response Type: Protocol Buffers.

1*BerdlML7pumOMcBQSh8uqg.webp


Нажмите Open Descriptor Registry и добавьте сгенерированный файл .desc.

1*8CYgtGLdaV-Ni0jDp3v01w.webp


Выберите соответствующий тип сообщения из раскрывающегося меню типа сообщения.

1*ygAOUMXSzTJ17bMT-X92ow.webp


Бам! Наше ответное сообщение теперь отображается со всеми ключами, сопоставленными с их соответствующими значениями.

1*5aGvdXBl1drZuG2hFlceNw.webp


Удачного реверса!
 
Эта статья не взята из гитхаба ?
просто видел такую же очень схожую только на английском
На гитхабе проекта PBTK есть информация о работе, часть скриншотов оттуда
Данная же статья - руководство от А до Я для MacOS, Windows и Linux
Воду не лью, все кратко и по делу - что такое протобаф, как он компилируется,
как понять что это он, что делать если не знаете что делать
 
В большинстве новых приложений protobuf не ловит, хотя он там есть. Пробовал как на Windows, так и на Ubuntu. Удалось вытащить только из версии GooglePhotos 2020 года.
Возможно PBTK нужна докрутка, так как софт не обновляется с 2020 года, но это уже не решение из коробки, к сожалению. Мою задачу он не выполнил.

Гуглил что-то подобное, не нашёл. Если есть, подскажите.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх