5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TLS 1.3 の ClientHello を Wireshark で勉強した

Last updated at Posted at 2022-08-12

仕事で TLS 接続がなぜか強制RSTされる調査をするときに、TLS negotiation に関する知識不足で死にました。結局 Java の bug だったということで解決はしたのですが、後学のためにパケットを読めるようにしておきます。

test case

Mac Chrome Version 103.0.5060.53 から https://example.com へのアクセスを wireshark でキャプチャしました。ひとつずつパケットを見ていきます。HTTPSとは言っても最初は暗号化されていなかったりします。そういったところも勉強していきます。(と思いましたが、ClientHelloだけで終わりました)

all packets

今回の全パケットはこちらです。わかりやすいように src/dest IP address は名前にしてあります。

# time src dest protocol length TCP flags seq ack info
130 2.487113 localhost example.com TCP 78 ····CE····S· 0 0 58364 → 443 [SYN, ECN, CWR] Seq=0 Win=65535 Len=0 MSS=1460 WS=64 TSval=107391323 TSecr=0 SACK_PERM=1
133 2.641277 example.com localhost TCP 74 ·····E·A··S· 0 1 443 → 58364 [SYN, ACK, ECN] Seq=0 Ack=1 Win=65535 Len=0 MSS=1382 SACK_PERM=1 TSval=2936265566 TSecr=107391323 WS=512
134 2.641642 localhost example.com TCP 66 ·······A···· 1 1 58364 → 443 [ACK] Seq=1 Ack=1 Win=131520 Len=0 TSval=107391476 TSecr=2936265566
135 2.642373 localhost example.com TLSv1.3 583 ·······AP··· 1 1 Client Hello
139 2.805043 example.com localhost TCP 66 ·······A···· 1 518 443 → 58364 [ACK] Seq=1 Ack=518 Win=67072 Len=0 TSval=2936265726 TSecr=107391476
140 2.805047 example.com localhost TLSv1.3 165 ·······AP··· 1 518 Hello Retry Request, Change Cipher Spec
141 2.805283 localhost example.com TCP 66 ·······A···· 518 100 58364 → 443 [ACK] Seq=518 Ack=100 Win=131392 Len=0 TSval=107391638 TSecr=2936265727
142 2.80656 localhost example.com TLSv1.3 409 ·······AP··· 518 100 Change Cipher Spec, Client Hello
145 2.967469 example.com localhost TCP 66 ·······A···· 100 861 443 → 58364 [ACK] Seq=100 Ack=861 Win=68096 Len=0 TSval=2936265895 TSecr=107391639
146 2.96767 example.com localhost TLSv1.3 1436 ·······A···· 100 861 Server Hello, Application Data
147 2.972801 example.com localhost TCP 1436 ·······AP··· 1470 861 443 → 58364 [PSH, ACK] Seq=1470 Ack=861 Win=68096 Len=1370 TSval=2936265897 TSecr=107391639 [TCP segment of a reassembled PDU]
148 2.972935 example.com localhost TLSv1.3 1436 ·······A···· 2840 861 Application Data, Application Data
149 2.97294 example.com localhost TLSv1.3 117 ·······AP··· 4210 861 Application Data
150 2.973082 localhost example.com TCP 66 ·······A···· 861 2840 58364 → 443 [ACK] Seq=861 Ack=2840 Win=128768 Len=0 TSval=107391804 TSecr=2936265897
151 2.973117 localhost example.com TCP 66 ·······A···· 861 4261 58364 → 443 [ACK] Seq=861 Ack=4261 Win=127296 Len=0 TSval=107391804 TSecr=2936265897
152 2.997266 localhost example.com TCP 66 ·······A···· 861 4261 [TCP Window Update] 58364 → 443 [ACK] Seq=861 Ack=4261 Win=131072 Len=0 TSval=107391828 TSecr=2936265897
153 2.998117 localhost example.com TLSv1.3 140 ·······AP··· 861 4261 Application Data
154 2.998521 localhost example.com TLSv1.3 158 ·······AP··· 935 4261 Application Data
155 2.998889 localhost example.com TLSv1.3 534 ·······AP··· 1027 4261 Application Data
173 3.151537 example.com localhost TCP 66 ·······A···· 4261 935 443 → 58364 [ACK] Seq=4261 Ack=935 Win=68096 Len=0 TSval=2936266078 TSecr=107391828
174 3.15154 example.com localhost TLSv1.3 321 ·······AP··· 4261 935 Application Data
175 3.151542 example.com localhost TLSv1.3 321 ·······AP··· 4516 935 Application Data
176 3.151543 example.com localhost TLSv1.3 162 ·······AP··· 4771 935 Application Data, Application Data
177 3.151817 localhost example.com TCP 66 ·······A···· 1495 4516 58364 → 443 [ACK] Seq=1495 Ack=4516 Win=130816 Len=0 TSval=107391979 TSecr=2936266078
178 3.151817 localhost example.com TCP 66 ·······A···· 1495 4771 58364 → 443 [ACK] Seq=1495 Ack=4771 Win=130560 Len=0 TSval=107391979 TSecr=2936266078
179 3.151817 localhost example.com TCP 66 ·······A···· 1495 4867 58364 → 443 [ACK] Seq=1495 Ack=4867 Win=130432 Len=0 TSval=107391979 TSecr=2936266078
180 3.152917 localhost example.com TLSv1.3 97 ·······AP··· 1495 4867 Application Data
181 3.158304 example.com localhost TLSv1.3 97 ·······AP··· 4867 1027 Application Data
182 3.158506 localhost example.com TCP 66 ·······A···· 1526 4898 58364 → 443 [ACK] Seq=1526 Ack=4898 Win=131008 Len=0 TSval=107391985 TSecr=2936266080
183 3.171335 example.com localhost TLSv1.3 981 ·······AP··· 4898 1495 Application Data, Application Data, Application Data
184 3.171566 localhost example.com TCP 66 ·······A···· 1526 5813 58364 → 443 [ACK] Seq=1526 Ack=5813 Win=130112 Len=0 TSval=107391998 TSecr=2936266087
185 3.326376 example.com localhost TCP 66 ·······A···· 5813 1526 443 → 58364 [ACK] Seq=5813 Ack=1526 Win=69120 Len=0 TSval=2936266254 TSecr=107391980
1098 48.839818 localhost example.com TCP 54 ·······A···· 1525 5813 [TCP Keep-Alive] 58364 → 443 [ACK] Seq=1525 Ack=5813 Win=131072 Len=0
1108 48.992493 example.com localhost TCP 66 ·······A···· 5813 1526 [TCP Keep-Alive ACK] 443 → 58364 [ACK] Seq=5813 Ack=1526 Win=69120 Len=0 TSval=2936311918 TSecr=107391998
1369 64.549821 example.com localhost TCP 66 ·······A···· 5812 1526 [TCP Keep-Alive] 443 → 58364 [ACK] Seq=5812 Ack=1526 Win=69120 Len=0 TSval=2936327237 TSecr=107391998
1370 64.55017 localhost example.com TCP 66 ·······A···· 1526 5813 [TCP Keep-Alive ACK] 58364 → 443 [ACK] Seq=1526 Ack=5813 Win=131072 Len=0 TSval=107452954 TSecr=2936311918
2417 109.887607 localhost example.com TCP 54 ·······A···· 1525 5813 [TCP Keep-Alive] 58364 → 443 [ACK] Seq=1525 Ack=5813 Win=131072 Len=0
2418 110.041827 example.com localhost TCP 66 ·······A···· 5813 1526 [TCP Keep-Alive ACK] 443 → 58364 [ACK] Seq=5813 Ack=1526 Win=69120 Len=0 TSval=2936372958 TSecr=107452954
2790 125.889367 example.com localhost TCP 66 ·······A···· 5812 1526 [TCP Keep-Alive] 443 → 58364 [ACK] Seq=5812 Ack=1526 Win=69120 Len=0 TSval=2936388677 TSecr=107452954
2791 125.889583 localhost example.com TCP 66 ·······A···· 1526 5813 [TCP Keep-Alive ACK] 58364 → 443 [ACK] Seq=1526 Ack=5813 Win=131072 Len=0 TSval=107513834 TSecr=2936372958
4317 171.346262 localhost example.com TCP 54 ·······A···· 1525 5813 [TCP Keep-Alive] 58364 → 443 [ACK] Seq=1525 Ack=5813 Win=131072 Len=0
4318 171.522983 example.com localhost TCP 66 ·······A···· 5813 1526 [TCP Keep-Alive ACK] 443 → 58364 [ACK] Seq=5813 Ack=1526 Win=69120 Len=0 TSval=2936434446 TSecr=107513834
4366 183.843569 example.com localhost TLSv1.3 123 ·······AP··· 5813 1526 Application Data
4367 183.843575 example.com localhost TLSv1.3 90 ·······AP··· 5870 1526 Application Data
4368 183.843577 example.com localhost TCP 66 ·······A···F 5894 1526 443 → 58364 [FIN, ACK] Seq=5894 Ack=1526 Win=69120 Len=0 TSval=2936446685 TSecr=107513834
4369 183.844156 localhost example.com TCP 66 ·······A···· 1526 5870 58364 → 443 [ACK] Seq=1526 Ack=5870 Win=131008 Len=0 TSval=107571319 TSecr=2936446685
4370 183.844157 localhost example.com TCP 66 ·······A···· 1526 5894 58364 → 443 [ACK] Seq=1526 Ack=5894 Win=130944 Len=0 TSval=107571319 TSecr=2936446685
4371 183.8442 localhost example.com TCP 66 ·······A···· 1526 5895 58364 → 443 [ACK] Seq=1526 Ack=5895 Win=130944 Len=0 TSval=107571319 TSecr=2936446685
4372 183.846191 localhost example.com TCP 54 ·······A·R·· 1526 5895 58364 → 443 [RST, ACK] Seq=1526 Ack=5895 Win=131008 Len=0

各 TLSパケットの後にTCPでackが返ってきてますね。

解読開始

TCP 3-way handshake

冒頭は TCP 通信が3つ入ります。かの有名な 3-way handshakeで syn, syn+ack, ack で TCP接続を確立します。ここは TLS layerではないので本記事ではスキップします。当たり前ですが、localhostから通信が始まっています。

# src dest type length info
130 **localhost** example.com TCP 78 58364 → 443 [SYN, ECN, CWR] Seq=0 Win=65535 Len=0 MSS=1460 WS=64 TSval=107391323 TSecr=0 SACK_PERM=1
133 example.com **localhost** TCP 74 443 → 58364 [SYN, ACK, ECN] Seq=0 Ack=1 Win=65535 Len=0 MSS=1382 SACK_PERM=1 TSval=2936265566 TSecr=107391323 WS=512
134 **localhost** example.com TCP 66 58364 → 443 [ACK] Seq=1 Ack=1 Win=131520 Len=0 TSval=107391476 TSecr=2936265566

ClientHello

さあ、TLS通信の始まりです。まずはお互いに「どうやって暗号化するか」をネゴシエーションしていきます。ここはまだ平文通信というところがポイントです。最初に client が送るのが ClientHello です。

# src dest type length info
4 **localhost** example.com TLSv1.3 583 Client Hello

ClientHello 中身全部

Frame 135: 583 bytes on wire (4664 bits), 583 bytes captured (4664 bits) on interface en0, id 0
Ethernet II, Src: Apple_3f:65:ae (38:f9:d3:3f:65:ae), Dst: da:46:f8:db:b2:0a (da:46:f8:db:b2:0a)
Internet Protocol Version 4, Src: 192.168.61.86, Dst: 93.184.216.34
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x02 (DSCP: CS0, ECN: ECT(0))
    Total Length: 569
    Identification: 0x0000 (0)
    Flags: 0x40, Don't fragment
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 64
    Protocol: TCP (6)
    Header Checksum: 0x04e4 [validation disabled]
    [Header checksum status: Unverified]
    Source Address: 192.168.61.86
    Destination Address: 93.184.216.34
Transmission Control Protocol, Src Port: 58364, Dst Port: 443, Seq: 1, Ack: 1, Len: 517
    Source Port: 58364
    Destination Port: 443
    [Stream index: 6]
    [Conversation completeness: Complete, WITH_DATA (63)]
    [TCP Segment Len: 517]
    Sequence Number: 1    (relative sequence number)
    Sequence Number (raw): 4163027035
    [Next Sequence Number: 518    (relative sequence number)]
    Acknowledgment Number: 1    (relative ack number)
    Acknowledgment number (raw): 2279611937
    1000 .... = Header Length: 32 bytes (8)
    Flags: 0x018 (PSH, ACK)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 0... .... = Congestion Window Reduced (CWR): Not set
        .... .0.. .... = ECN-Echo: Not set
        .... ..0. .... = Urgent: Not set
        .... ...1 .... = Acknowledgment: Set
        .... .... 1... = Push: Set
        .... .... .0.. = Reset: Not set
        .... .... ..0. = Syn: Not set
        .... .... ...0 = Fin: Not set
        [TCP Flags: ·······AP···]
    Window: 2055
    [Calculated window size: 131520]
    [Window size scaling factor: 64]
    Checksum: 0x97d4 [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
        TCP Option - No-Operation (NOP)
            Kind: No-Operation (1)
        TCP Option - No-Operation (NOP)
            Kind: No-Operation (1)
        TCP Option - Timestamps: TSval 107391476, TSecr 2936265566
            Kind: Time Stamp Option (8)
            Length: 10
            Timestamp value: 107391476
            Timestamp echo reply: 2936265566
    [Timestamps]
        [Time since first frame in this TCP stream: 0.155260000 seconds]
        [Time since previous frame in this TCP stream: 0.000731000 seconds]
    [SEQ/ACK analysis]
        [iRTT: 0.154529000 seconds]
        [Bytes in flight: 517]
        [Bytes sent since last PSH flag: 517]
    TCP payload (517 bytes)
Transport Layer Security
    TLSv1.3 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 512
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 508
            Version: TLS 1.2 (0x0303)
            Random: a990959f0793ba1ff5a09d1a5eec06e87706c88ea969457fa59d9ba9dc0f0e32
            Session ID Length: 32
            Session ID: b1c8e600556b5561ceda33e4c9c0b59221e45d11fb5cc03de4c165861b34f642
            Cipher Suites Length: 32
            Cipher Suites (16 suites)
                Cipher Suite: Reserved (GREASE) (0x6a6a)
                Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
                Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
                Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
                Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
                Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
                Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
                Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
                Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
            Compression Methods Length: 1
            Compression Methods (1 method)
            Extensions Length: 403
            Extension: Reserved (GREASE) (len=0)
                Type: Reserved (GREASE) (64250)
                Length: 0
                Data: <MISSING>
            Extension: server_name (len=16)
                Type: server_name (0)
                Length: 16
                Server Name Indication extension
                    Server Name list length: 14
                    Server Name Type: host_name (0)
                    Server Name length: 11
                    Server Name: example.com
            Extension: extended_master_secret (len=0)
                Type: extended_master_secret (23)
                Length: 0
            Extension: renegotiation_info (len=1)
                Type: renegotiation_info (65281)
                Length: 1
                Renegotiation Info extension
                    Renegotiation info extension length: 0
            Extension: supported_groups (len=10)
                Type: supported_groups (10)
                Length: 10
                Supported Groups List Length: 8
                Supported Groups (4 groups)
                    Supported Group: Reserved (GREASE) (0xcaca)
                    Supported Group: x25519 (0x001d)
                    Supported Group: secp256r1 (0x0017)
                    Supported Group: secp384r1 (0x0018)
            Extension: ec_point_formats (len=2)
                Type: ec_point_formats (11)
                Length: 2
                EC point formats Length: 1
                Elliptic curves point formats (1)
                    EC point format: uncompressed (0)
            Extension: session_ticket (len=0)
                Type: session_ticket (35)
                Length: 0
                Data (0 bytes)
            Extension: application_layer_protocol_negotiation (len=14)
                Type: application_layer_protocol_negotiation (16)
                Length: 14
                ALPN Extension Length: 12
                ALPN Protocol
                    ALPN string length: 2
                    ALPN Next Protocol: h2
                    ALPN string length: 8
                    ALPN Next Protocol: http/1.1
            Extension: status_request (len=5)
                Type: status_request (5)
                Length: 5
                Certificate Status Type: OCSP (1)
                Responder ID list Length: 0
                Request Extensions Length: 0
            Extension: signature_algorithms (len=18)
                Type: signature_algorithms (13)
                Length: 18
                Signature Hash Algorithms Length: 16
                Signature Hash Algorithms (8 algorithms)
            Extension: signed_certificate_timestamp (len=0)
                Type: signed_certificate_timestamp (18)
                Length: 0
            Extension: key_share (len=43)
                Type: key_share (51)
                Length: 43
                Key Share extension
                    Client Key Share Length: 41
                    Key Share Entry: Group: Reserved (GREASE), Key Exchange length: 1
                        Group: Reserved (GREASE) (51914)
                        Key Exchange Length: 1
                        Key Exchange: 00
                    Key Share Entry: Group: x25519, Key Exchange length: 32
                        Group: x25519 (29)
                        Key Exchange Length: 32
                        Key Exchange: ab83faa28c812c3237c264b8d213968dadf7450bcc0c69d9f37fe6775f1fe015
            Extension: psk_key_exchange_modes (len=2)
                Type: psk_key_exchange_modes (45)
                Length: 2
                PSK Key Exchange Modes Length: 1
                PSK Key Exchange Mode: PSK with (EC)DHE key establishment (psk_dhe_ke) (1)
            Extension: supported_versions (len=7)
                Type: supported_versions (43)
                Length: 7
                Supported Versions length: 6
                Supported Version: Reserved (GREASE) (0x2a2a)
                Supported Version: TLS 1.3 (0x0304)
                Supported Version: TLS 1.2 (0x0303)
            Extension: compress_certificate (len=3)
                Type: compress_certificate (27)
                Length: 3
                Algorithms Length: 2
                Algorithm: brotli (2)
            Extension: application_settings (len=5)
                Type: application_settings (17513)
                Length: 5
                ALPS Extension Length: 3
                Supported ALPN List
                    Supported ALPN Length: 2
                    Supported ALPN: h2
            Extension: Reserved (GREASE) (len=1)
                Type: Reserved (GREASE) (39578)
                Length: 1
                Data: 00
            Extension: padding (len=204)
                Type: padding (21)
                Length: 204
                Padding Data: 000000000000000000000000000000000000000000000000000000000000000000000000…
            [JA3 Fullstring: 771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0]
            [JA3: cd08e31494f9531f560d64c695473da9]

TLS Record Layer

まず見ていくのは TLS Record Layerです。
これはたぶん rfc5246 で定まったあたりの内容です。TLSの中でなんの処理をするのか、などの指定がされていると思われます。

https://www.ietf.org/rfc/rfc5246.txt

version negotiation

TLS1.3の特徴として、下位互換のためにversionが読み取りづらいという点があります。下の画像には3つのversionがあることがわかるでしょうか。

image.png

もっとも特徴的なのは Handshake Protocol の version が TLS1.2 なところです。さらに下に行くと、 Extention: supported_versions の中で、 TLS 1.2 とともに 1.3 を候補に上げています。これでこの client(Chrome)が TLS 1.3 に対応していることをserverに要望しています。

なお、私が持つ TLS 1.3 の全知識をここで披露し終わったことと、そもそもまともにpacket見るのがこれが初めてということをここに宣言させていただきます。

さて、Handshake protocol の中には server_name という項目があり、私がリクエストした example.com が記載されています。server側はこれを見て、SNIなどのチェックを経て ServerHelloに繋げていきます。

image.png

重要なのは ここは平文 ということです。HTTPSでも、同一ネットワークにいる Mallory(悪役) にはどのドメインに通信しようとしたかがモロバレってことです。

さぁ、パケットを見ていきます。Hex dumpはこちら。最終的にはこの中が壊れていても読めるようになりたい。

0000   da 46 f8 db b2 0a 38 f9 d3 3f 65 ae 08 00 45 02
0010   02 39 00 00 40 00 40 06 04 e4 c0 a8 3d 56 5d b8
0020   d8 22 e3 fc 01 bb f8 22 c0 5b 87 e0 1e 21 80 18
0030   08 07 97 d4 00 00 01 01 08 0a 06 66 a9 f4 af 03
0040   db 5e 16 03 01 02 00 01 00 01 fc 03 03 a9 90 95
0050   9f 07 93 ba 1f f5 a0 9d 1a 5e ec 06 e8 77 06 c8
0060   8e a9 69 45 7f a5 9d 9b a9 dc 0f 0e 32 20 b1 c8
0070   e6 00 55 6b 55 61 ce da 33 e4 c9 c0 b5 92 21 e4
0080   5d 11 fb 5c c0 3d e4 c1 65 86 1b 34 f6 42 00 20
0090   6a 6a 13 01 13 02 13 03 c0 2b c0 2f c0 2c c0 30
00a0   cc a9 cc a8 c0 13 c0 14 00 9c 00 9d 00 2f 00 35
00b0   01 00 01 93 fa fa 00 00 00 00 00 10 00 0e 00 00
00c0   0b 65 78 61 6d 70 6c 65 2e 63 6f 6d 00 17 00 00
00d0   ff 01 00 01 00 00 0a 00 0a 00 08 ca ca 00 1d 00
00e0   17 00 18 00 0b 00 02 01 00 00 23 00 00 00 10 00
00f0   0e 00 0c 02 68 32 08 68 74 74 70 2f 31 2e 31 00
0100   05 00 05 01 00 00 00 00 00 0d 00 12 00 10 04 03
0110   08 04 04 01 05 03 08 05 05 01 08 06 06 01 00 12
0120   00 00 00 33 00 2b 00 29 ca ca 00 01 00 00 1d 00
0130   20 ab 83 fa a2 8c 81 2c 32 37 c2 64 b8 d2 13 96
0140   8d ad f7 45 0b cc 0c 69 d9 f3 7f e6 77 5f 1f e0
0150   15 00 2d 00 02 01 01 00 2b 00 07 06 2a 2a 03 04
0160   03 03 00 1b 00 03 02 00 02 44 69 00 05 00 03 02
0170   68 32 9a 9a 00 01 00 00 15 00 cc 00 00 00 00 00
0180   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0190   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01a0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01b0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01c0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01d0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01e0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01f0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0200   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0210   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0220   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0230   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0240   00 00 00 00 00 00 00

まず、wiresharkはデフォで hex 表示しますが、今回はこれを bitにして見ていきたいと思います。どこで切れてるか意識したいためです。 右クリックで as bits を選びます。

image.png

bitになりました。先頭の 3bytes を選んだら、 Ethernet layerのaddress周りが選択されました。こうして互いの関連がわかります。めっちゃ便利。まあ、今回問題になったのはパケット壊れてるからこの関係性がわからず、ここはなんのフィールド??でかなり詰みました。そのためにこの勉强をしています。

image.png

で、ここで wiresharkの初歩に気づきました。上のセクションと下のbitセクションは連携してて、bitセクションもethernet frameからtlsまで全部ひとつづきに書かれてます。まず TLS layerを選んでから、下のbitsを見るようにします。

image.png

Centent Type

青く光った最初の 1 bypte を選ぶと、 Content Type: Handshake (22) が光りました。

image.png

Content Typeは20, 21, 22, 23 があります。

   enum {
       change_cipher_spec(20), alert(21), handshake(22),
       application_data(23), (255)
   } ContentType;

https://www.ietf.org/rfc/rfc5246.txt

ここでは handshakeが送られてますね。ちなみにハマったパケットは 21 alert(ただし中身はこわれてる) でした。

Version

その次の 2bytes は version. これは TLS1.0の頃の表記なんだろうか。major version で1バイト、マイナーで1 byteです。TLS1.2/1.3ではここは使われないと思います。

image.png

   struct {
       uint8 major;
       uint8 minor;
   } ProtocolVersion;

Length

次の 2bytesは length. 今回は 512 (単位は bytes) です。packet全体は 583 bytes なので、そことは一致しません。これは 583 の方には Ethernet frame, tcp header などの領域が含まれているからです。
image.png

そして確認すると、Content Type 22 で送る Handshake protocol で送信するデータ内容が 512 bytes ということでした。TLS record全体のlengthではないんですね。パケットの構造は、こうして「後続する領域がどれくらいあるか」を示すためにlengthが使われます。

image.png

Handshake Protocol: Client Hello

さあ、ここから深淵に足を踏み入れます。長い Handshake protocolの始まりです。

Handshake Type

次の 1byte は どんな handshake か、です。

image.png

Handshake Typeは様々なものがあります。こちらは TLS 1.2 の例です。

   struct {
       HandshakeType msg_type;
       uint24 length;
       select (HandshakeType) {
           case hello_request:       HelloRequest;
           case client_hello:        ClientHello;
           case server_hello:        ServerHello;
           case certificate:         Certificate;
           case server_key_exchange: ServerKeyExchange;
           case certificate_request: CertificateRequest;
           case server_hello_done:   ServerHelloDone;
           case certificate_verify:  CertificateVerify;
           case client_key_exchange: ClientKeyExchange;
           case finished:            Finished;
       } body;
   } Handshake;

https://www.ietf.org/rfc/rfc5246.txt

対して、 TLS 1.3 にはさらにかなりの追加がされています。TLS 1.3 がいかに複雑になったかが、ここからもよくわかると思います。パット見で明らかに追加されたものに矢印を付けました。

B.3.  Handshake Protocol

      enum {
          hello_request_RESERVED(0),         <------- (+)
          client_hello(1),
          server_hello(2),
          hello_verify_request_RESERVED(3),         <------- (+)
          new_session_ticket(4),         <------- (+)
          end_of_early_data(5),         <------- (+)
          hello_retry_request_RESERVED(6),         <------- (+)
          encrypted_extensions(8),         <------- (+)
          certificate(11),     
          server_key_exchange_RESERVED(12),  
          certificate_request(13),
          server_hello_done_RESERVED(14),    
          certificate_verify(15),
          client_key_exchange_RESERVED(16),  
          finished(20),
          certificate_url_RESERVED(21),         <------- (+)
          certificate_status_RESERVED(22),         <------- (+)
          supplemental_data_RESERVED(23),         <------- (+)
          key_update(24),         <------- (+)
          message_hash(254),         <------- (+)
          (255)
      } HandshakeType;

https://datatracker.ietf.org/doc/rfc8446/

TLS 1.2 の Handshake typeと見比べると、結構な違いがありますね。

これこそが handshake の全貌です。恐ろしい。

Length

その次の 3 bytes は length = 508 bytes. なんのlengthかはよくわからないけどこの handshake protocol のこれから始まるdata周りの合計でしょう。

image.png

Version

次の 2bytes は version. TLS 1.2 は 0x0303 = 771 です。TLS 1.3でもここは 1.2 になります。

image.png

Random

次の 32 bytes は random. これはとても大事なんですが説明は割愛。詳しくは Professional SSL/TLS を御覧ください。末尾4 bytes はclientの時刻情報が入るはずなんですが、browser finger printとして使われる恐れがあることから今は形骸化してただのランダムらしいです。なので、値を調べるのはやめときます。

TLS 1.2 の説明ですが、randomは鍵交換で重要な役割を果たします。この乱数に脆弱性があると通信が読み取られることになります。

ServerHello~ClientKeyExchangeの通信過程で、クライアントとサーバの両方にClientHello初期乱数、ServerHello初期乱数、pre_master_secretの3つの乱数が手に入ったことになります。ここからmaster_secret(48バイト)を算出し、そこからさらにkey_blockを計算します。key_blockは理論上無限長の疑似乱数列で、必要な長さだけ計算し、そこからアプリケーションデータの暗号通信に使う共有鍵を取り出します。
https://qiita.com/n-i-e/items/41673fd16d7bd1189a29

image.png

Session ID Length

1byteで、32が入っている

image.png

Session ID

32bytesありました。TLS 1.2の説明ですが

SessionIDは、これがクライアント値とサーバ値で一致すれば、双方にキャッシュされた計算済みパラメータを利用して、ハンドシェイク手順をすっとばしてChangeCipherSpecまで進めるというものです。
https://qiita.com/n-i-e/items/41673fd16d7bd1189a29

image.png

Cipher Suites Length

2 bytes

image.png

Cipher suites

Cipher suitesはclientが使いたい暗号化の種類です。先のlength通り 32bytesあり、ひとつの suiteにつき 2bytes使われていました。つまり 32 /2 = 16 の cipher suitesをブラウザは候補としてサーバにお伺いしています。

image.png

ここで clientが提案したのは16個。後述する Hello Retry Request では TLS_AES_256_GCM_SHA384 が選ばれ、採用されていました。

Cipher Suites (16 suites)
    Cipher Suite: Reserved (GREASE) (0x6a6a)
    Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
    Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)              <---------
    Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
    Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
    Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
    Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
    Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
    Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)

clientによって対応しているcipher suitesが違うので、ここは可変領域(lengthがついている)んですね。パケットパーサーが、どこまでを可変領域か判断できるようにするために、lengthは必ずdata領域の先頭に配置されます。「Cipher suites lengthが来るはずだ」「32bytesが入ってるぞ」「じゃあ、この後の32bytesは cipher suitesだ」「その次からは、次のComporession Methods lengthが来るはずだ」と感じでパケットが読まれていくわけです。

Compression Method Length

1 byte
そのとおり、次のfieldがcipher suitesの32bytesの直後に来ました。

image.png

Compression Method

Compression Method は 1 BYTE で NULL(00000000) です。

image.png

これはTLSの圧縮には攻撃がされた過去があり(CRIME脆弱性)、現在では使われないオプションとなっています。似た文字列を圧縮しつづけることで内容を推測できることが理由です。

むちゃくちゃな例

知らない文字列 x (1 byte) があるとする。末尾に3 bytes足して xabc を送ると、4 bytes になるはず。しかし圧縮されて結果が 3 bytes になったら、abcのどれかが x に一致していると推測できる。そんなんで x がわかっちゃったりする。

現在のTLSでは圧縮できないので、データを圧縮したかったら application dataの中でする(そもそも zip ファイルを送るとか)んだと思う。

Extention Length

2bytes. ここから地獄の Extentionが始まります。403 bytesあるそうです。

image.png

Extention Padding

Extentionの詳細は飛ばして、最後のpaddingを見ます。全体では 208 bytes ありますが、len=204とあります。これはさらに細かく見れるからです

image.png

Extention Padding: Type = 2 bytes

まず 2bytes で extentionの種類が paddingだと宣言されてます。

image.png

Extention Typeは想像の通り目がくらむほどあります。paddingは RFC 7685 に書いてあるという優しさが見えます。

enum {
        server_name(0),                             /* RFC 6066 */
        max_fragment_length(1),                     /* RFC 6066 */
        status_request(5),                          /* RFC 6066 */
        supported_groups(10),                       /* RFC 8422, 7919 */
        signature_algorithms(13),                   /* RFC 8446 */
        use_srtp(14),                               /* RFC 5764 */
        heartbeat(15),                              /* RFC 6520 */
        application_layer_protocol_negotiation(16), /* RFC 7301 */
        signed_certificate_timestamp(18),           /* RFC 6962 */
        client_certificate_type(19),                /* RFC 7250 */
        server_certificate_type(20),                /* RFC 7250 */
        padding(21),                                /* RFC 7685 */
        RESERVED(40),                               /* Used but never
                                                       assigned */
        pre_shared_key(41),                         /* RFC 8446 */
        early_data(42),                             /* RFC 8446 */
        supported_versions(43),                     /* RFC 8446 */
        cookie(44),                                 /* RFC 8446 */
        psk_key_exchange_modes(45),                 /* RFC 8446 */
        RESERVED(46),                               /* Used but never
                                                       assigned */
        certificate_authorities(47),                /* RFC 8446 */
        oid_filters(48),                            /* RFC 8446 */
        post_handshake_auth(49),                    /* RFC 8446 */
        signature_algorithms_cert(50),              /* RFC 8446 */
        key_share(51),                              /* RFC 8446 */
        (65535)
    } ExtensionType;
Extention Padding: Length = 2 bytes

後続する Padding data の中身が 204 bytes と 2bytes で書かれてます。

image.png

Extention Padding: Padding Data = 最大 n bytes

paddingなので全部0です。これはblockの長さを固定化するために使われます。たぶん。

謎の JA3 文字列

extention, TLS record の末尾にある JA3 という2行は謎でした。選択してもbitsが反転しないので、Wiresharkがつけた付加情報なんでしょうか。

image.png

Extention: key_share

key_shareは鍵交換のキモらしいです。

TLS1.3では、鍵交換の方法はPSK/DHE/ECDHE/PSKのいずれかとなっており、どれを使うかをClient Helloの key_share パラメーターで選んでいます。
その際DH/ECDHEを使うなら key_share に共有値を詰めて送信します。(共有鍵は互いのkey_shareが完了後に内部で計算して生成。
https://qiita.com/developer-kikikaikai/items/055a344c847379b471f7

ClientHello(1回目) by the client
Extension: key_share (len=43)
    Type: key_share (51)
    Length: 43
    Key Share extension
        Client Key Share Length: 41
        Key Share Entry: Group: Reserved (GREASE), Key Exchange length: 1
            Group: Reserved (GREASE) (51914)
            Key Exchange Length: 1
            Key Exchange: 00
        Key Share Entry: Group: x25519, Key Exchange length: 32
            Group: x25519 (29)
            Key Exchange Length: 32
            Key Exchange: ab83faa28c812c3237c264b8d213968dadf7450bcc0c69d9f37fe6775f1fe015

恐らく下4行がclientの重要な部分ではと推測します。 Group: x25519 は ECDH用のカーブでした。
Key Exchange の乱数 32 bytes が(EC)DHEでmaster_secretを計算するためのclient側共有値。ちなみに、この後 Client Hello Requestで返ってくるのは共有値なしで、 Selected Group だけ。

Hello Retry Request by the server
            Extension: key_share (len=2)
                Type: key_share (51)
                Length: 2
                Key Share extension
                    Selected Group: secp256r1 (23)

server側から secp256r1 を使え、と言われているように思います。更にその後、clientはサーバのretry requestを受けてclient helloをもう一度送ります。そのときの key_shareは以下のように、 secp256r1 が指定されていました。

ClientHello(2回目) by the client
Extension: key_share (len=71)
    Type: key_share (51)
    Length: 71
    Key Share extension
        Client Key Share Length: 69
        Key Share Entry: Group: secp256r1, Key Exchange length: 65
            Group: secp256r1 (23)
            Key Exchange Length: 65
            Key Exchange: 042c60dacb51f9139a814981fe52c830f990fb739ba98ac993ef19b823cfb5be2ab0371f…

共有値も再生成されています。

そのさらに後、サーバは server hello でやっとサーバの共有地を返してきます。

Server Hello by the server
Extension: key_share (len=69)
    Type: key_share (51)
    Length: 69
    Key Share extension
        Key Share Entry: Group: secp256r1, Key Exchange length: 65
            Group: secp256r1 (23)
            Key Exchange Length: 65
            Key Exchange: 0457a797dc210b089cbe0b74106050b96b022f58a8c68862d10823c10cc624946eea4c59…

これで ECDHEの鍵交換ができて、お互いに共有鍵を計算できるようになったんだと思います。

Extension: psk_key_exchange_modes

もう一つ気になったのが psk_key_exchange_modes.

PSKを使う場合はpre_shared_keyに共有鍵を詰めて送信します。
https://qiita.com/developer-kikikaikai/items/055a344c847379b471f7

pre_shared_key は見当たらなかったですが、PSKを (EC)DHEで行うように要望しているように見えました。

Extension: psk_key_exchange_modes (len=2)
    Type: psk_key_exchange_modes (45)
    Length: 2
    PSK Key Exchange Modes Length: 1
    PSK Key Exchange Mode: PSK with (EC)DHE key establishment (psk_dhe_ke) (1)

Extension: signature_algorithms

ここは動的な長さ。今回は22 bytes. どうやらサーバのSSL/TLS証明書の種類(RSA/ECC)をclientからリクエストできるようです。

以下、自信ない話

知らなかったんですが、webサーバはクライアントのリクエストに応じて、同じcommon nameでも、異なる証明書を返せるそうです。

Apacheサーバでは、RSAとECCで署名した証明書を出し分ける事が出来る。confファイルに、RSAとECCで署名されたサーバ証明書と鍵をそれぞれ記述するだけです
https://asnokaze.hatenablog.com/entry/20141013/1413194597

証明書をCAから買う際、実は我々は RSA証明書を買っています。手元で openssl -genkey で秘密鍵を作る、それを使ってCSRを作る。CSRをCAに提出すると公開鍵が発行されます。このとき、秘密鍵を openssl ecparams -genkey すると、 ECCに対応した証明書を申請できます。

https://jp.globalsign.com/support/ssl/about-ecc.html

RSA証明書のメリットは計算量が少ないこと、ECC証明書のメリットはサイズ(転送量)が小さくなること。まだECC証明書はそんなに広まってないという認識です。

例えば amazon.co.jp や example.com の証明書は RSA/SHA256で、もっともpopularなものだと思います。これは今回 CLientHelloにあるsignature_algorithmsでは rsa_pkcs1_sha256 として指定されているようです。

Extension: signature_algorithms (len=18)
    Type: signature_algorithms (13)
    Length: 18
    Signature Hash Algorithms Length: 16
    Signature Hash Algorithms (8 algorithms)
        Signature Algorithm: ecdsa_secp256r1_sha256 (0x0403)
            Signature Hash Algorithm Hash: SHA256 (4)
            Signature Hash Algorithm Signature: ECDSA (3)
        Signature Algorithm: rsa_pss_rsae_sha256 (0x0804)
            Signature Hash Algorithm Hash: Unknown (8)
            Signature Hash Algorithm Signature: SM2 (4)
        Signature Algorithm: rsa_pkcs1_sha256 (0x0401)           <-------
            Signature Hash Algorithm Hash: SHA256 (4)
            Signature Hash Algorithm Signature: RSA (1)
        Signature Algorithm: ecdsa_secp384r1_sha384 (0x0503)
            Signature Hash Algorithm Hash: SHA384 (5)
            Signature Hash Algorithm Signature: ECDSA (3)
        Signature Algorithm: rsa_pss_rsae_sha384 (0x0805)
            Signature Hash Algorithm Hash: Unknown (8)
            Signature Hash Algorithm Signature: Unknown (5)
        Signature Algorithm: rsa_pkcs1_sha384 (0x0501)
            Signature Hash Algorithm Hash: SHA384 (5)
            Signature Hash Algorithm Signature: RSA (1)
        Signature Algorithm: rsa_pss_rsae_sha512 (0x0806)
            Signature Hash Algorithm Hash: Unknown (8)
            Signature Hash Algorithm Signature: Unknown (6)
        Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
            Signature Hash Algorithm Hash: SHA512 (6)
            Signature Hash Algorithm Signature: RSA (1)

実際に example.com が返してきた証明書は、RSA SHA256でした。

image.png

現状ECC証明書がほとんど使われてない気がするので、 signature_algorithms はあまり意味がない気がする。

なお、サーバ側は対応した証明書をServerHelloで返すだけなので、サーバがsignature_algorithmsを返答することはない様子でした。

Extension: application_layer_protocol_negotiation (len=14)

application_layer_protocol_negotiation は ALPN と略されます。ALPNを使うと、TLSの上でHTTP/1.1とHTTP/2の両方を使う、というようなことが可能になります。

今回は全体では 18 bytes あります。 h2, http/1.1 という文字が見えますね。

image.png

Extension: application_layer_protocol_negotiation: Type: application_layer_protocol_negotiation (16)

2 bytes で application_layer_protocol_negotiation

image.png

続いて 2 bytes で lengthがあります。この先は動的な領域です。14bytesあるそうです。

Extension: application_layer_protocol_negotiation: ALPN Extension Length: 12

さらに ALPN Extention Lengthが 2bytes来ました。lengthだけじゃだめなのか。14-2で12bytesになってます。

image.png

Extension: application_layer_protocol_negotiation: ALPN Protocol

まず ALPN string length: 2 が 1 byte あります。この2bytesは、続く文字列 h2 が2bytesという意味を表しています。

image.png

ALPN Next Protocl で h2 が指定されています。2 bytesです。
http/2 では文字が多すぎたのでしょうか。HTTP2の不思議です。
image.png

その次の ALPN string length = 8 bytes は、http/1.1 の 8bytes ですね。

これにより、この client は ALPNとして http/2 と http/1.1 の利用を求めていることがわかります。http/3はありませんね。ないのか。さすがにまだないのか。

application_settingsにも似たようなのがあって、そこでは h2 だけが指定されてました。

image.png

Extension: signed_certificate_timestamp (len=0)

CT logに関するrequestをclientからもできるらしいのですが、len=0でした。使ってないみたい。

image.png

supported_groups

手元の書籍では elliptic_curves というextentionで楕円曲線の指定ができるらしいのですが見当たりませんでした。その代わり、ここらへんがそれっぽかったです(調べてない)。ec_point_formats で楕円曲線上の点を圧縮できるらしいのですがあまり効果がないらしく、uncompressedになってました。

image.png

Extension: supported_groups (len=10)
    Type: supported_groups (10)
    Length: 10
    Supported Groups List Length: 8
    Supported Groups (4 groups)
        Supported Group: Reserved (GREASE) (0xcaca)
        Supported Group: x25519 (0x001d)
        Supported Group: secp256r1 (0x0017)
        Supported Group: secp384r1 (0x0018)

挫折

ServerHelloにすらたどり着けず数時間が溶けました。続きはいつかやりたいと想います。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?