Pentesting gRPC-Web

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Σύντομη ανασκόπηση πρωτοκόλλου και επιφάνειας επίθεσης

  • Μεταφορά: gRPC‑Web χρησιμοποιεί μια browser‑συμβατή παραλλαγή του gRPC πάνω από HTTP/1.1 ή HTTP/2 μέσω proxy (Envoy/APISIX/grpcwebproxy/etc.). Υποστηρίζονται μόνο unary και server‑streaming κλήσεις.
  • Content-Types you will see:
  • application/grpc-web (binary framing)
  • application/grpc-web-text (base64-encoded framing for HTTP/1.1 streaming)
  • Framing: κάθε μήνυμα έχει πρόθεμα με 5‑byte gRPC header (1‑byte flags + 4‑byte length). Στο gRPC‑Web, τα trailers (grpc-status, grpc-message, …) στέλνονται μέσα στο σώμα ως ειδικό frame: πρώτο byte με MSB ενεργοποιημένο (0x80) ακολουθούμενο από μήκος και ένα header block σε στυλ HTTP/1.1.
  • Συνηθισμένα request headers: x-grpc-web: 1, x-user-agent: grpc-web-javascript/…, grpc-timeout, grpc-encoding. Οι απαντήσεις αποκαλύπτουν grpc-status/grpc-message μέσω trailers/body frames και συχνά μέσω Access-Control-Expose-Headers για browsers.
  • Security‑relevant middleware που συχνά υπάρχει:
  • Envoy grpc_web filter και gRPC‑JSON transcoder (HTTP<->gRPC bridge)
  • Nginx/APISIX gRPC‑Web plugins
  • CORS πολιτικές στον proxy

Τι σημαίνει αυτό για επιτιθέμενους:

  • Μπορείτε να κατασκευάσετε αιτήματα χειροκίνητα (binary ή base64 text), ή να αφήσετε tooling να τα δημιουργήσει/κωδικοποιήσει.
  • Λάθη CORS στον proxy μπορούν να επιτρέψουν cross‑site, authenticated gRPC‑Web κλήσεις (παρόμοιο με κλασικά CORS ζητήματα).
  • Οι JSON transcoding bridges μπορεί να αποκαλύψουν κατά λάθος gRPC methods ως unauthenticated HTTP endpoints αν τα routes/auth είναι λανθασμένα διαμορφωμένα.

Testing gRPC‑Web from the CLI

Easiest: buf curl (speaks gRPC‑Web natively)

  • List methods via reflection (if enabled):
# list methods (uses reflection)
buf curl --protocol grpcweb https://host.tld --list-methods
  • Καλέστε μια μέθοδο με JSON είσοδο, με αυτόματη διαχείριση του gRPC‑Web framing και των headers:
buf curl --protocol grpcweb \
-H 'Origin: https://example.com' \
-d '{"field":"value"}' \
https://host.tld/pkg.svc.v1.Service/Method
  • Εάν το reflection είναι απενεργοποιημένο, παρέχετε ένα schema/descriptor set με –schema ή δείξτε σε τοπικά αρχεία .proto. Δείτε buf help curl.

Raw με curl (manual headers + framed body)

Για binary mode (application/grpc-web), στείλτε ένα framed payload (5‑byte prefix + protobuf message). Για text mode, κωδικοποιήστε το framed payload σε base64.

# Build a protobuf message, then gRPC-frame it (1 flag byte + 4 length + msg)
# Example using protoscope to compose/edit the message and base64 for grpc-web-text
protoscope -s msg.txt | python3 grpc-coder.py --encode --type grpc-web-text | \
tee body.b64

curl -i https://host.tld/pkg.svc.v1.Service/Method \
-H 'Content-Type: application/grpc-web-text' \
-H 'X-Grpc-Web: 1' \
-H 'X-User-Agent: grpc-web-javascript/0.1' \
--data-binary @body.b64

Συμβουλή: Αναγκάστε χρήση base64/text mode με application/grpc-web-text όταν οι ενδιάμεσοι κόμβοι HTTP/1.1 διακόπτουν το binary streaming.

Έλεγχος συμπεριφοράς CORS (preflight + response)

  • Preflight:
curl -i -X OPTIONS https://host.tld/pkg.svc.v1.Service/Method \
-H 'Origin: https://evil.tld' \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: content-type,x-grpc-web,x-user-agent,grpc-timeout'
  • Μια ευάλωτη ρύθμιση συχνά αντικατοπτρίζει αυθαίρετο Origin και στέλνει Access-Control-Allow-Credentials: true, επιτρέποντας cross‑site authenticated κλήσεις. Ελέγξτε επίσης ότι το Access-Control-Expose-Headers περιλαμβάνει grpc-status, grpc-message (πολλές υλοποιήσεις τα εκθέτουν για client libs).

Για γενικές τεχνικές κατάχρησης του CORS, δείτε CORS - Misconfigurations & Bypass.

Παραποίηση gRPC‑Web payloads

Το gRPC‑Web χρησιμοποιεί το Content-Type: application/grpc-web-text ως base64‑wrapped gRPC frame stream για συμβατότητα με browsers. Μπορείτε να αποκωδικοποιήσετε/τροποποιήσετε/κωδικοποιήσετε frames για να παραποιήσετε πεδία, να αλλάξετε flags ή να εισάγετε payloads.

Χρησιμοποιήστε το gprc-coder tool (και το Burp extension του) για να επιταχύνετε τις round‑trips.

Χειροκίνητο με το gGRPC Coder Tool

  1. Αποκωδικοποιήστε το payload:
echo "AAAAABYSC0FtaW4gTmFzaXJpGDY6BVhlbm9u" | python3 grpc-coder.py --decode --type grpc-web-text | protoscope > out.txt
  1. Επεξεργαστείτε το περιεχόμενο του decoded payload
nano out.txt
2: {"Amin Nasiri Xenon GRPC"}
3: 54
7: {"<script>alert(origin)</script>"}
  1. Κωδικοποιήστε το νέο payload
protoscope -s out.txt | python3 grpc-coder.py --encode --type grpc-web-text
  1. Χρησιμοποίησε την έξοδο στο Burp interceptor:
AAAAADoSFkFtaW4gTmFzaXJpIFhlbm9uIEdSUEMYNjoePHNjcmlwdD5hbGVydChvcmlnaW4pPC9zY3JpcHQ+

Εγχειρίδιο με gRPC‑Web Coder Burp Suite Extension

Μπορείτε να χρησιμοποιήσετε gRPC‑Web Coder Burp Suite Extension στο gRPC‑Web Pentest Suite το οποίο είναι ευκολότερο. Μπορείτε να διαβάσετε τις οδηγίες εγκατάστασης και χρήσης στο repo του.

Ανάλυση αρχείων JavaScript gRPC‑Web

Οι web εφαρμογές που χρησιμοποιούν gRPC‑Web περιλαμβάνουν τουλάχιστον ένα παραγόμενο JS/TS bundle. Κάντε αντίστροφη μηχανική για να εξάγετε υπηρεσίες, μεθόδους και δομές μηνυμάτων.

  • Δοκιμάστε να χρησιμοποιήσετε gRPC-Scan για να αναλύσετε τα bundles.
  • Αναζητήστε method paths όπως /./, message field numbers/types, και custom interceptors που προσθέτουν auth headers.
  1. Κατεβάστε το αρχείο JavaScript gRPC‑Web
  2. Σκανάρετέ το με grpc-scan.py:
python3 grpc-scan.py --file main.js
  1. Ανάλυσε το output και δοκίμασε τα νέα endpoints και services:
Output:
Found Endpoints:
/grpc.gateway.testing.EchoService/Echo
/grpc.gateway.testing.EchoService/EchoAbort
/grpc.gateway.testing.EchoService/NoOp
/grpc.gateway.testing.EchoService/ServerStreamingEcho
/grpc.gateway.testing.EchoService/ServerStreamingEchoAbort

Found Messages:

grpc.gateway.testing.EchoRequest:
+------------+--------------------+--------------+
| Field Name |     Field Type     | Field Number |
+============+====================+==============+
| Message    | Proto3StringField  | 1            |
+------------+--------------------+--------------+
| Name       | Proto3StringField  | 2            |
+------------+--------------------+--------------+
| Age        | Proto3IntField     | 3            |
+------------+--------------------+--------------+
| IsAdmin    | Proto3BooleanField | 4            |
+------------+--------------------+--------------+
| Weight     | Proto3FloatField   | 5            |
+------------+--------------------+--------------+
| Test       | Proto3StringField  | 6            |
+------------+--------------------+--------------+
| Test2      | Proto3StringField  | 7            |
+------------+--------------------+--------------+
| Test3      | Proto3StringField  | 16           |
+------------+--------------------+--------------+
| Test4      | Proto3StringField  | 20           |
+------------+--------------------+--------------+

grpc.gateway.testing.EchoResponse:
+--------------+--------------------+--------------+
|  Field Name  |     Field Type     | Field Number |
+==============+====================+==============+
| Message      | Proto3StringField  | 1            |
+--------------+--------------------+--------------+
| Name         | Proto3StringField  | 2            |
+--------------+--------------------+--------------+
| Age          | Proto3IntField     | 3            |
+--------------+--------------------+--------------+
| IsAdmin      | Proto3BooleanField | 4            |
+--------------+--------------------+--------------+
| Weight       | Proto3FloatField   | 5            |
+--------------+--------------------+--------------+
| Test         | Proto3StringField  | 6            |
+--------------+--------------------+--------------+
| Test2        | Proto3StringField  | 7            |
+--------------+--------------------+--------------+
| Test3        | Proto3StringField  | 16           |
+--------------+--------------------+--------------+
| Test4        | Proto3StringField  | 20           |
+--------------+--------------------+--------------+
| MessageCount | Proto3IntField     | 8            |
+--------------+--------------------+--------------+

grpc.gateway.testing.ServerStreamingEchoRequest:
+-----------------+-------------------+--------------+
|   Field Name    |    Field Type     | Field Number |
+=================+===================+==============+
| Message         | Proto3StringField | 1            |
+-----------------+-------------------+--------------+
| MessageCount    | Proto3IntField    | 2            |
+-----------------+-------------------+--------------+
| MessageInterval | Proto3IntField    | 3            |
+-----------------+-------------------+--------------+

grpc.gateway.testing.ServerStreamingEchoResponse:
+------------+-------------------+--------------+
| Field Name |    Field Type     | Field Number |
+============+===================+==============+
| Message    | Proto3StringField | 1            |
+------------+-------------------+--------------+

grpc.gateway.testing.ClientStreamingEchoRequest:
+------------+-------------------+--------------+
| Field Name |    Field Type     | Field Number |
+============+===================+==============+
| Message    | Proto3StringField | 1            |
+------------+-------------------+--------------+

grpc.gateway.testing.ClientStreamingEchoResponse:
+--------------+----------------+--------------+
|  Field Name  |   Field Type   | Field Number |
+==============+================+==============+
| MessageCount | Proto3IntField | 1            |
+--------------+----------------+--------------+

Προβλήματα με Bridging και JSON transcoding

Πολλές αναπτύξεις τοποθετούν έναν Envoy (ή παρόμοιο) proxy μπροστά από τον gRPC server:

  • Το φίλτρο grpc_web μετατρέπει HTTP/1.1 POSTs σε HTTP/2 gRPC.
  • Ο gRPC‑JSON Transcoder εκθέτει μεθόδους gRPC ως HTTP JSON endpoints όταν οι .proto options (google.api.http) είναι παρούσες.

Από την άποψη του pentesting:

  • Δοκίμασε απευθείας HTTP JSON κλήσεις προς /./ με application/json όταν ένας transcoder είναι ενεργός (οι auth/route mismatches είναι συνηθισμένα):
curl -i https://host.tld/pkg.svc.v1.Service/Method \
-H 'Content-Type: application/json' \
-d '{"field":"value"}'
  • Ελέγξτε αν άγνωστες μέθοδοι/παράμετροι απορρίπτονται ή προωθούνται. Ορισμένες ρυθμίσεις προωθούν μη-ταιριασμένες διαδρομές upstream, περιστασιακά παρακάμπτοντας auth ή την επαλήθευση αιτήματος.
  • Παρατηρήστε το x-envoy-original-path και τις σχετικές κεφαλίδες που προστίθενται από proxies. Τα Upstreams που τα εμπιστεύονται μπορεί να είναι εκμεταλλεύσιμα αν ο proxy δεν τα φιλτράρει σωστά.

Αναφορές

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks