Обсудить проект

gRPC пентест: когда Burp плачет, а ты нет

09.09.2026

Burp Suite — король HTTP/1.1, но как только на сцену выходит gRPC — бинарный протобаф поверх HTTP/2 — он грустит в углу и делает вид, что всё под контролем. Спойлер: не под контролем. На момент написания Burp вообще нативно не умеет в gRPC, только в gRPC-Web через сторонние экстеншены. Так что доставай терминал, сейчас будем ломать бинарь руками, как настоящие 0day-фрики.

Почему Burp плачет

Проблема простая: gRPC гоняет сообщения Protocol Buffers по HTTP/2-стримам, а это не текстовый JSON, который Burp щёлкает как орешки — это бинарная каша с полями по номерам, без имён и без человекочитаемой структуры. Прокси видит HTTP/2 фреймы, но payload внутри — это protobuf, и без .proto-схемы Burp просто рисует тебе иероглифы в Repeater. WAF, кстати, та же история: многие фильтры заточены под текстовые паттерны (SQLi-строки, XSS-теги), а бинарный protobuf они банально не парсят.

Разведка: reflection — твой лучший друг

Первым делом проверяем, не оставил ли админ дверь нараспашку — server reflection API, который позволяет клиенту (тебе) вытащить полную схему сервисов без единого .proto файла.

# Есть ли рефлексия вообще
grpcurl -plaintext target.com:443 list

# Список методов конкретного сервиса
grpcurl -plaintext target.com:443 list myapp.UserService

# Полное описание метода: поля, типы, вложенность
grpcurl -plaintext target.com:443 describe myapp.UserService.GetUser

# Дёргаем метод руками
grpcurl -plaintext -d '{"user_id": 1}' target.com:443 myapp.UserService.GetUser

Если reflection выключен (грамотный админ, бывает) — не расстраивайся, схему можно вытащить из веб-бандлов клиента (webpack chunks с gRPC-Web стабами), из бинарников мобильного приложения или из текстов ошибок сервера. Для веб-фронта есть отдельный скрипт grpc_scan, который парсит JS-бандлы и выдёргивает эндпоинты, сервисы и типы полей.

Для более удобного визуального ковыряния поднимай grpcui — это веб-интерфейс поверх grpcurl, красиво рисует схему и формы для вызова методов:

grpcui -plaintext target.com:443

Ломаем протобаф руками

Когда у тебя нет .proto и reflection закрыт — начинается настоящий underground. Захватываешь сырой HTTP/2 body (через mitmproxy или Burp как прокси-обёртку) и идёшь смотреть, что там внутри без схемы вообще:

cat request.bin | protoc --decode=myapp.GetUserRequest user.proto

А если и .proto нет — тащи protoscope, он разбирает protobuf-фреймы на голые field number + wire type + значение, без знания схемы вообще:

protoscope < raw_message.bin

Ещё один зверь из арсенала NCC Group — Blackbox Protobuf: библиотека (и Burp-экстеншен) для работы с protobuf-сообщениями вслепую, когда .proto тебе никто не даст. Ставится как расширение прямо в Burp и позволяет редактировать бинарные поля в Repeater почти как JSON — жизнь заиграла новыми красками.

Для gRPC-Web конкретно есть связка grpc-coder.py + protoscope, которая декодит grpc-web-text в читаемый вид, ты правишь payload и кодируешь обратно перед отправкой через Interceptor:

echo "AAAAABYSC0FtaW4gTmFzaXJpGDY6BVhlbm9u" | python3 grpc-coder.py --decode --type grpc-web-text | protoscope > out.txt
# правишь out.txt руками
python3 grpc-coder.py --encode --type grpc-web-text < out.txt

Burp всё же не бесполезен

Не спеши хоронить Burp — он умеет в HTTP/2 транспорт, просто нужны экстеншены-переводчики. Вот что реально работает:

  • gRPC-Web Coder из BApp Store — автоматом декодит/кодит application/grpc-web-text и application/grpc-web+proto, есть отдельная вкладка с декодированным protobuf прямо в Message Editor.
  • gRPC-Web Pentest Suite (nxenon) — комбо из grpc_scan (парсинг JS-бандлов) и Burp-экстеншена grpc_coder, заточено конкретно под gRPC-Web в вебе.
  • bRPC-Web — свежий (октябрь 2025) экстеншен от Compass Security, обрабатывает gRPC-Web трафик; авторы прямо пишут, что чистый gRPC Burp пока не тянет, но логика декодинга уже готова к переносу.
  • Blackbox Protobuf — та самая NCC-либа, ставится и как Burp-плагин для слепой работы с protobuf.

Важно: всё это работает нормально для gRPC-Web (через прокси-gateway типа Envoy). Для чистого gRPC (HTTP/2 без обёртки) Burp по-прежнему в основном полезен только для заголовков, метадаты и анализа gateway-поведения — основную дойку делаешь через grpcurl/grpcui.

Векторы атаки и лайфхаки

Теперь самое вкусное — куда бить:

  • Object-level authorization / IDOR — меняешь user_id в запросе, который прилетел через grpcurl, и смотришь, отдаст ли сервер чужие данные. Protobuf не спасает от логических дыр.
  • Deprecated / legacy поля — в схеме через describe часто видно поля с комментами вроде «legacy» или «deprecated», которые сервер всё ещё мержит в модель без allowlist — классика privilege escalation.
  • Metadata trust — gRPC гоняет auth-токены и служебные флаги в HTTP/2 headers (metadata), а не в body; проверяй, не доверяет ли сервер клиентским metadata-полям без валидации (роли, admin-флаги).
  • Reflection в проде — если сервер отдаёт полную схему в паблик, это уже находка: инвентаризация всей внутренней API-поверхности бесплатно.
  • TLS-мисконфиг — gRPC часто гоняют на mTLS, но проверь, не откатывается ли сервер на plaintext (-plaintext флаг в grpcurl либо отвечает), слабые шифры, невалидируемые сертификаты.
  • Fuzzing бинарных полей — automатизируй через grpc-fuzz или свои скрипты поверх protoscope-декодированных сообщений: буфер-оверфлоу, инъекции в string-полях, неожиданные wire types.
  • CORS/CSRF на gRPC-Web gateway — Envoy-прокси иногда криво настраивает CORS для gRPC-Web эндпоинтов, отсюда межсайтовые вызовы.

Чеклист-минимум на стол: grpcurl listdescribe каждого метода → протестировать auth boundaries (аноним vs юзер vs админ) → погонять IDOR по числовым/UUID полям → проверить metadata на предмет доверия клиенту → зафаззить строковые поля через protoscope-редактированные payload’ы → добить TLS-чеком.