Extrakt Server Name Indication (SNI) aus TLS-client-hello
Wie würden Sie extrahieren Sie die Server Name Indication von einem TLS-Client-Hello-Nachricht. Ich bin curently kämpfen, um das zu verstehen sehr kryptische RFC 3546 auf TLS-Erweiterungen, in denen die SNI definiert ist.
Dinge, die ich verstanden habe bisher:
- Der host ist utf8-codiert und lesbar, wenn Sie utf8 enocde den Puffer.
- Theres ein byte, bevor der host, bestimmt die Länge.
Wenn ich finden konnte die genaue position der Länge byte, das extrahieren der SNI wäre ziemlich einfach. Aber wie bekomme ich das byte in den ersten Platz?
- Der einfache Ansatz, den Sie versuchen zu nehmen, ist falsch. Sie müssen zum Parsen der Anfrage einschließlich seiner Erweiterungen, und dann bekommst du die Daten aus der entsprechenden Erweiterung.
- Ja, ich bin sicher, dass, aber ich weiß wirklich nicht, wie zu analysieren. Verstehen Sie, wie das TLS-handshake funktioniert?
- Klar will ich, denn wir bieten eine security-Bibliothek als eines unserer wichtigsten Produkte. Sie benötigen zum öffnen der RFC ( tools.ietf.org/html/rfc5246 ) und es umsetzen.
- Haha, gut danke, das ist wie 100 Seiten pure tech. Ich denke, die Sache wird interessant auf Seite 41. Dies ist, wo die Erweiterungen erwähnt werden, dass im Gegenzug sind beschrieben in RFC 3546. Oh mein, Oh mein. 😀
- Hey schau, dass eine andere Antwort, wo Eugene verkauft 20 tausend-dollar-Produkt als Antwort. Ich denke, indem Menschen zu einem riesigen RFC und die Aufgabe, das Gefühl überwältigend entmutigend ist eine Verkaufstaktik?
- Verwandte: serverfault.com/questions/574405/...
- stackoverflow.com/questions/39624745/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Habe ich diese in sniproxy, die Prüfung einer TLS client hello-Paket in Wireshark beim Lesen von diesem RFC ist ein ziemlich guter Weg zu gehen. Es ist nicht zu schwer, nur viele Felder variabler Länge, die Sie haben, zu überspringen und überprüfen Sie überprüfung, wenn Sie die richtigen element-Typ.
Ich bin auf meine tests jetzt, und haben in diesem kommentierten Beispiel-Paket, das vielleicht helfen könnte:
WireShark und der capture nur TLS (SSL) - Pakete durch hinzufügen eines filters
tcp port 443
. Dann finden Sie einen "Client-Hello" - Nachricht. Sie können sehen, seine raw-Daten unten.Erweitern
Secure Socket Layer
->
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
->
...
und Sie werden sehen
Extension: server_name
->
Server Name Indication extension
. Die server-Namen in der Handshake-Paket ist nicht verschlüsselt.http://i.stack.imgur.com/qt0gu.png
Bemerkte ich, dass die domain immer voranstellen von zwei null-bytes und eine Länge byte. Vielleicht ist es vorzeichenlose 24-bit-integer, aber ich kann es nicht testen, da mein DNS-server nicht zulassen, domain-Namen, jenseits von 77 Zeichen.
Auf, dass wissen, das ich kam mit dieser (Node.js -) code.
Sieht dieser code für eine Folge von zwei bytes null. Wenn er eine findet, nimmt er das nächste byte ist die Länge der parameter. Es wird überprüft ob die Länge noch in der Grenze des Puffers und wenn ja, liest die byte-Sequenz UTF-8. Später könnte man die RegEx array, und extrahieren Sie die Domäne.
Funktioniert erstaunlich gut! Noch bemerkte ich etwas merkwürdiges.
Immer, egal welche subdomain ich wählen, die domain ist gezielte zweimal. Es scheint, wie die SNI-Feld geschachtelt innerhalb eines anderen Feldes.
Ich bin offen für Anregungen und Verbesserungen! 🙂
Wandte ich diese in ein Node-Modul, für alle, die ' s interessiert: sni.
Für alle interessierten, dies ist eine vorläufige version des C/C++ - code. Es hat soweit funktioniert. Die Funktion gibt die position an den server-Namen in ein byte-array mit den Client-Hello und die Länge der Namen in der
len
parameter.