Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Гайд Скажи НЕТ хттп дебаггеру

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
17 Июн 2024
Сообщения
36
Реакции
29

Что такое MITM-атака?

Man-in-the-Middle (MITM) — атака, при которой злоумышленник встаёт между клиентом и сервером, перехватывая и потенциально подменяя трафик. Даже HTTPS не является абсолютной защитой: если атакующий может подсунуть клиенту свой сертификат (например, через поддельный корневой CA), TLS-соединение будет установлено с ним, а не с настоящим сервером. А использование своего кустарного шифрования как по мне глупо и не безопасно так как https уже предоставляет отличное AES шифрование и RSA шифрование для передачи ключа.

Стандартная проверка сертификата в TLS выглядит так:
  • Клиент получает сертификат сервера
  • Проверяет цепочку доверия до одного из корневых CA в системном хранилище
  • Если цепочка валидна — соединение считается безопасным
Проблема: любой доверенный CA может выпустить сертификат для любого домена. Корпоративные прокси, государственные CA и скомпрометированные центры сертификации активно этим пользуются.

Что такое SSL Pinning?

SSL Pinning (или Certificate / Public Key Pinning) — техника, при которой приложение не просто доверяет системному хранилищу CA, а проверяет конкретный сертификат или публичный ключ сервера, жёстко прописанный в коде.

Существует два варианта привязки:

  • Certificate Pinning — привязка к конкретному сертификату (ломается при его обновлении)
  • Public Key Pinning — привязка к хэшу публичного ключа (сертификат можно перевыпускать, сохраняя ключ)
Public Key Pinning является предпочтительным подходом: он устойчив к плановой ротации сертификатов и при этом даёт полноценную защиту от подмены.

Получение PIN'a сертификата домена:
Expand Collapse Copy
openssl s_client -connect libomath.org:443 -servername libomath.org 2>/dev/null \
  | openssl x509 -pubkey -noout \
  | openssl pkey -pubin -outform DER \
  | openssl dgst -sha256 -binary \
  | openssl enc -base64

Реализация на C++ с CPR и libcurl

Рассмотрим конкретную реализацию с использованием библиотеки CPR (C++ Requests), которая является обёрткой над libcurl:


C++:
Expand Collapse Copy
#include <cpr/cpr.h>
#include <print>
#include <string>
#include <format>

#include <VMProtectSDK.h>
int main() {

  auto r = cpr::Get(
      cpr::Url{"https://libomath.org"},
      cpr::Ssl(cpr::ssl::VerifyPeer(true),
               cpr::ssl::VerifyHost(true),
               cpr::ssl::PinnedPublicKey(
                   VMProtectDecryptStringA("sha256//LRaA1V5K6VB1abkO1XdpYSaGuStJG1vYiJAsdevSPjA=")))
  );

  if (r.error) {
    std::println("Error: {}", r.error.message);
  } else {
    std::println("Status: {}", r.status_code);
  }
}

Разберём каждый компонент:



VerifyPeer(true) — стандартная проверка сертификата через цепочку CA. Отключать нельзя.

VerifyHost(true) — проверка соответствия имени хоста в сертификате и запрошенного домена. Защищает от подстановки сертификата другого домена.

PinnedPublicKey("sha256//...") — ключевой параметр. libcurl вычисляет SHA-256 хэш публичного ключа из полученного сертификата и сравнивает с указанным значением. Если хэши не совпадают — соединение немедленно разрывается.

VMProtectDecryptStringA(...) — строка с pin-значением обфусцирована и зашифрована в бинаре с помощью VMProtect. Это предотвращает тривиальное извлечение pin'а из исполняемого файла и его подмену в памяти.

Результат:

1772825722525.png

Как мы видим приложение яро отказывается устанавливать соединение даже с сертификатом которому доверяет ОС. Если http debugger закрыть то всё будет работать нормально и вернётся код 200.

Как это защищает от MITM?

При установке TLS-соединения происходит следующая цепочка проверок:
  • Сервер присылает свой сертификат
  • libcurl проверяет цепочку доверия (VerifyPeer)
  • libcurl проверяет имя хоста (VerifyHost)
  • libcurl извлекает публичный ключ из сертификата и вычисляет его SHA-256 хэш
  • Хэш сравнивается с pin-значением, расшифрованным VMProtect
  • Только при совпадении всех трёх проверок соединение считается безопасным
Даже если атакующий имеет доверенный CA и может выпустить валидный сертификат для нужного домена — его публичный ключ будет другим. Хэш не совпадёт, и соединение не установится.

ИТОГ​

Скомпрометированный центр сертификации: Заблокировано — ключ будет другой
Компрометация самого сервера (утечка приватного ключа): Не защищает — нужна ротация pin
Атака на уровне ОС (патч libcurl в памяти, ring0) : Не защищает — обход на системном уровне (однако в целях усложнения жизни реверсеру можно накинуть виртуализацию на всё что связанно с сетью: cpr, OpenSSL, curl и тд)
Отсутствие резервного pin при плановой ротации ключа: Приложение перестанет работать
 

Что такое MITM-атака?

Man-in-the-Middle (MITM) — атака, при которой злоумышленник встаёт между клиентом и сервером, перехватывая и потенциально подменяя трафик. Даже HTTPS не является абсолютной защитой: если атакующий может подсунуть клиенту свой сертификат (например, через поддельный корневой CA), TLS-соединение будет установлено с ним, а не с настоящим сервером. А использование своего кустарного шифрования как по мне глупо и не безопасно так как https уже предоставляет отличное AES шифрование и RSA шифрование для передачи ключа.

Стандартная проверка сертификата в TLS выглядит так:
  • Клиент получает сертификат сервера
  • Проверяет цепочку доверия до одного из корневых CA в системном хранилище
  • Если цепочка валидна — соединение считается безопасным
Проблема: любой доверенный CA может выпустить сертификат для любого домена. Корпоративные прокси, государственные CA и скомпрометированные центры сертификации активно этим пользуются.

Что такое SSL Pinning?

SSL Pinning (или Certificate / Public Key Pinning) — техника, при которой приложение не просто доверяет системному хранилищу CA, а проверяет конкретный сертификат или публичный ключ сервера, жёстко прописанный в коде.

Существует два варианта привязки:

  • Certificate Pinning — привязка к конкретному сертификату (ломается при его обновлении)
  • Public Key Pinning — привязка к хэшу публичного ключа (сертификат можно перевыпускать, сохраняя ключ)
Public Key Pinning является предпочтительным подходом: он устойчив к плановой ротации сертификатов и при этом даёт полноценную защиту от подмены.

Получение PIN'a сертификата домена'a сертификата домена:
Expand Collapse Copy
openssl s_client -connect libomath.org:443 -servername libomath.org 2>/dev/null \
  | openssl x509 -pubkey -noout \
  | openssl pkey -pubin -outform DER \
  | openssl dgst -sha256 -binary \
  | openssl enc -base64

Реализация на C++ с CPR и libcurl

Рассмотрим конкретную реализацию с использованием библиотеки CPR (C++ Requests), которая является обёрткой над libcurl:


C++:
Expand Collapse Copy
#include <cpr/cpr.h>
#include <print>
#include <string>
#include <format>

#include <VMProtectSDK.h>
int main() {

  auto r = cpr::Get(
      cpr::Url{"https://libomath.org"},
      cpr::Ssl(cpr::ssl::VerifyPeer(true),
               cpr::ssl::VerifyHost(true),
               cpr::ssl::PinnedPublicKey(
                   VMProtectDecryptStringA("sha256//LRaA1V5K6VB1abkO1XdpYSaGuStJG1vYiJAsdevSPjA=")))
  );

  if (r.error) {
    std::println("Error: {}", r.error.message);
  } else {
    std::println("Status: {}", r.status_code);
  }
}

Разберём каждый компонент:



VerifyPeer(true) — стандартная проверка сертификата через цепочку CA. Отключать нельзя.

VerifyHost(true) — проверка соответствия имени хоста в сертификате и запрошенного домена. Защищает от подстановки сертификата другого домена.

PinnedPublicKey("sha256//...") — ключевой параметр. libcurl вычисляет SHA-256 хэш публичного ключа из полученного сертификата и сравнивает с указанным значением. Если хэши не совпадают — соединение немедленно разрывается.

VMProtectDecryptStringA(...) — строка с pin-значением обфусцирована и зашифрована в бинаре с помощью VMProtect. Это предотвращает тривиальное извлечение pin'а из исполняемого файла и его подмену в памяти.

Результат:

Посмотреть вложение 329587
Как мы видим приложение яро отказывается устанавливать соединение даже с сертификатом которому доверяет ОС. Если http debugger закрыть то всё будет работать нормально и вернётся код 200.

Как это защищает от MITM?

При установке TLS-соединения происходит следующая цепочка проверок:
  • Сервер присылает свой сертификат
  • libcurl проверяет цепочку доверия (VerifyPeer)
  • libcurl проверяет имя хоста (VerifyHost)
  • libcurl извлекает публичный ключ из сертификата и вычисляет его SHA-256 хэш
  • Хэш сравнивается с pin-значением, расшифрованным VMProtect
  • Только при совпадении всех трёх проверок соединение считается безопасным
Даже если атакующий имеет доверенный CA и может выпустить валидный сертификат для нужного домена — его публичный ключ будет другим. Хэш не совпадёт, и соединение не установится.

ИТОГ​

Скомпрометированный центр сертификации: Заблокировано — ключ будет другой
Компрометация самого сервера (утечка приватного ключа): Не защищает — нужна ротация pin
Атака на уровне ОС (патч libcurl в памяти, ring0) : Не защищает — обход на системном уровне (однако в целях усложнения жизни реверсеру можно накинуть виртуализацию на всё что связанно с сетью: cpr, OpenSSL, curl и тд)
Отсутствие резервного pin при плановой ротации ключа: Приложение перестанет работать
бро, ты *(DWORD*)0 = 0; и т.д.
В целом норм тема, для общего развития майнкрафтеров пойдёт
 
Назад
Сверху Снизу