Аналіз трафіку Android-програм обхід certificate pinning без реверс-інжинірингу
Іноді потрібно дослідити роботу бекенда мобільного додатка. Добре, якщо творці програми не морочилися і всі запити йдуть по голому HTTP. А що, якщо додаток для запитів використовує HTTPS, і відмовляється приймати сертифікат вашого кореневого центру, що засвідчує, який ви дбайливо впровадили в сховище операційної системи? Звичайно, можна пошукати запити в декомпільованому додатку або за допомогою реверс-інжинірингу взагалі відключити застосування шифрування, але хотілося б простіше.

Що таке certificate pinning?
Навіть при використанні HTTPS користувач не захищений від атак "Людина посередині", тому що при ініціалізації з'єднання зловмисник може підмінити сертифікат сервера на свій. Трафік при цьому буде доступний зловмиснику.
Впоратися з такою атакою допоможе certificate pinning. Цей захисний захід полягає в тому, що розробник «зашиває» додаток довірений сертифікат. Під час встановлення захищеного з'єднання програма перевіряє, що сертифікат, надісланий сервером, збігається з (або підписаний) сертифікатом зі сховища програми.
Обхід certificate pinning
Як піддослідний виберемо додаток Uber. Для аналізу HTTP-трафіку будемо використовувати Burp Suite. Також нам знадобиться JDK та Android SDK (я використовую усі останній версії). З Android SDK нам знадобиться лише утиліта zipalign, так що за бажання можна не завантажувати весь SDK, а знайти її на просторах інтернету. Заздалегідь полегшимо собі життя, додавши наступні шляхи до потрібних утиліт в змінну оточення PATH:
Відкриваємо Burp, заходимо в Proxy – Options – Add та додаємо Proxy Listener на інтерфейсі, який будедоступний піддослідному Android-пристрою (або емулятор). На пристрої в свою чергу налаштовуємо мережу, що використовується Wi-Fi на використання щойно включеного проксі.

У логах Burp Suite (вкладка Alerts) при цьому ми побачимо численні звіти про невдалі SSL-рукостискання. Зверніть увагу на перший рядок – саме через сервер cn-geo1.uber.com у моєму випадку здійснюється аутентифікація, тому і не вдається увійти до програми.
Справа в тому, що Burp Suite при перехопленні HTTPS-з'єднань (а ми пам'ятаємо, що всі з'єднання пристрою проксуються через нього) замінює сертифікат веб-сервера на свій, який, звичайно, не входить до списку довірених. Щоб пристрій довіряв сертифікату, виконуємо такі дії. У Burp заходимо в Proxy – Options та натискаємо Import/export CA certificate. Далі у діалозі вибираємо Export Certificate. Копіюємо сертифікат на пристрій, переходимо в Налаштування – Безпека – Встановити сертифікати та встановлюємо наш сертифікат як сертифікат для VPN та додатків.

Відкриємо програму у вашому улюбленому архіваторі як zip-архів. У папці res/raw можна помітити файл з назвою ssl_pinning_certs_bk146.bks.

З його розширення можна зрозуміти, що Uber використовує сховище ключів у форматі BouncyCastle (BKS). Через це не можна просто замінити сертифікат у програмі. Спочатку потрібно згенерувати BKS-сховище. Для цього качаємо jar для роботи з BKS.
Тепер генеруємо BKS-сховище, яке міститиме наш сертифікат:
На питання довіри сертифікату відповідаємо «yes». Знову відкриваємо apk в архіваторі та замінюємо оригінальне сховище на наше (зберігаємо при цьому оригінальну назву).
Але на цьому все не закінчується. Кожен apk має бутипідписано сертифікатом розробника. На щастя, це робиться не для безпеки, а для ідентифікації додатків, тому для наших дослідницьких цілей ми цілком можемо використовувати і недовірений сертифікат.
Видаляємо з apk папку META-INF зі старим підписом програми та приступаємо до генерації нової. Створюємо сховище ключів і генеруємо ключ для підпису apk:
Підписуємо щойно згенерованим ключем наш APK:
Тепер залишилося вирівняти дані в архіві по чотирибайтному кордоні: