paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

SSHのセッション確立フローをもう一回勉強する キャプチャで見てみる編

前回SSHのフローを整理したということで実際の動きを見てみようと思います。
ssh -vとかで見てもいいんですがNWエンジニアらしくWire sharkを使います。

環境

  • クライアント
    • サブ機Windows10
    • IP: 192.168.0.12
  • サーバ
    • Ubuntu 18.04LTS
    • IP: 192.168.0.10

セッション確立のおさらい

  1. TCPコネクション確立
  2. サーバ使用できるバージョンを応答
  3. サーバの公開ホストキーの提供
    • 公開鍵認証でサーバのFinger printを確認して認証
  4. アルゴリズムネゴシエーション
  5. Diffie Hellman関数で鍵交換
    • ここで暗号化、複合化用の共通鍵が交換される
  6. 共通鍵を使って以後の通信をやりとり
    • 以降のコネクションで使われる共通鍵暗号はバイナリパケットプロトコルと呼ばれる
    • パケットにMACを使ってデータの整合性を保っている

SSH接続して暗号化パケットが開始されるまでの流れを見ようと思います。

SSHのセッションサマリ

キャプチャを出力してみます。
テキストでログを出せるようtsharkを使います。
TCPも入れると見づらいのでsshに絞ります。

PS C:\Users\masashi\Documents> & 'C:\Program Files\Wireshark\tshark.exe'  -r .\sshcapture.pcapng -Y "ssh"
    4   0.010420 192.168.0.10192.168.0.12 SSH 95 Server: Protocol (SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3)
    5   0.045942 192.168.0.12192.168.0.10 SSH 87 Client: Protocol (SSH-2.0-OpenSSH_for_Windows_7.7)
    7   0.051690 192.168.0.10192.168.0.12 SSHv2 1134 Server: Key Exchange Init
    8   0.074208 192.168.0.12192.168.0.10 SSHv2 1374 Client: Key Exchange Init
   10   0.136611 192.168.0.12192.168.0.10 SSHv2 102 Client: Diffie-Hellman Key Exchange Init
   12   0.149371 192.168.0.10192.168.0.12 SSHv2 506 Server: Diffie-Hellman Key Exchange Reply, New Keys, Encrypted packet (len=172)
   13   0.179002 192.168.0.12192.168.0.10 SSHv2 70 Client: New Keys
   15   0.221135 192.168.0.12192.168.0.10 SSHv2 98 Client: Encrypted packet (len=44)
   17   0.223068 192.168.0.10192.168.0.12 SSHv2 98 Server: Encrypted packet (len=44)

   以後暗号化フェーズなので割愛

鍵が作られるまではシンプルなフローですね。

キャプチャの詳細

さっきのコマンドに-Vでパケットの中身を出力できます。

& 'C:\Program Files\Wireshark\tshark.exe'  -r .\sshcapture.pcapng -Y "ssh" -V

全てのヘッダが出力されるのでSSHのみ抽出します。

  • Frame 4

server -> client

SSH Protocol
    Protocol: SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
    [Direction: server-to-client]

サーバが使用できるバージョンを応答

  • Frame 5

client -> server

SSH Protocol
    Protocol: SSH-2.0-OpenSSH_for_Windows_7.7
    [Direction: client-to-server]

クライアントが使用できるバージョンを応答

  • Frame 7

server -> client

SSH Protocol
    SSH Version 2
        Packet Length: 1076
        Padding Length: 6
        Key Exchange
            Message Code: Key Exchange Init (20)
            Algorithms
                Cookie: 59ce5ed2756dcfa9fbdd28f4c53ae1ac
                kex_algorithms length: 258
                kex_algorithms string [truncated]: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,di
                server_host_key_algorithms length: 65
                server_host_key_algorithms string: ssh-rsa,rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519
                encryption_algorithms_client_to_server length: 108
                encryption_algorithms_client_to_server string: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
                encryption_algorithms_server_to_client length: 108
                encryption_algorithms_server_to_client string: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
                mac_algorithms_client_to_server length: 213
                mac_algorithms_client_to_server string [truncated]: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-
                mac_algorithms_server_to_client length: 213
                mac_algorithms_server_to_client string [truncated]: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-
                compression_algorithms_client_to_server length: 21
                compression_algorithms_client_to_server string: none,zlib@openssh.com
                compression_algorithms_server_to_client length: 21
                compression_algorithms_server_to_client string: none,zlib@openssh.com
                languages_client_to_server length: 0
                languages_client_to_server string: [Empty]
                languages_server_to_client length: 0
                languages_server_to_client string: [Empty]
                First KEX Packet Follows: 0
                Reserved: 00000000
        Padding String: 000000000000
    [Direction: server-to-client]

アルゴリズムネゴシエーション

  • Frame 8

client -> server

SSH Protocol
    SSH Version 2
        Packet Length: 1316
        Padding Length: 9
        Key Exchange
            Message Code: Key Exchange Init (20)
            Algorithms
                Cookie: 0cf07f579036cbc7231de08c60d1d70c
                kex_algorithms length: 304
                kex_algorithms string [truncated]: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,di
                server_host_key_algorithms length: 290
                server_host_key_algorithms string [truncated]: ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25
                encryption_algorithms_client_to_server length: 108
                encryption_algorithms_client_to_server string: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
                encryption_algorithms_server_to_client length: 108
                encryption_algorithms_server_to_client string: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
                mac_algorithms_client_to_server length: 213
                mac_algorithms_client_to_server string [truncated]: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-
                mac_algorithms_server_to_client length: 213
                mac_algorithms_server_to_client string [truncated]: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-
                compression_algorithms_client_to_server length: 4
                compression_algorithms_client_to_server string: none
                compression_algorithms_server_to_client length: 4
                compression_algorithms_server_to_client string: none
                languages_client_to_server length: 0
                languages_client_to_server string: [Empty]
                languages_server_to_client length: 0
                languages_server_to_client string: [Empty]
                First KEX Packet Follows: 0
                Reserved: 00000000
        Padding String: 000000000000000000
    [Direction: client-to-server]

アルゴリズムネゴシエーション

  • Frame 10

client -> server

SSH Protocol
    SSH Version 2
        Packet Length: 44
        Padding Length: 6
        Key Exchange
            Message Code: Diffie-Hellman Key Exchange Init (30)
            Multi Precision Integer Length: 32
            DH client e: 6f8e847cc717af634fc2a4a2f40f3e9c3da5589b96e6256e…
        Padding String: 000000000000
    [Direction: client-to-server]

Diffie Hellman関数で鍵交換

  • Frame 12

server -> client

SSH Protocol
    SSH Version 2
        Packet Length: 260
        Padding Length: 10
        Key Exchange
            Message Code: Diffie-Hellman Key Exchange Reply (31)
            KEX host key (type: ecdsa-sha2-nistp256)
                Host key length: 104
                Host key type length: 19
                Host key type: ecdsa-sha2-nistp256
                ECDSA elliptic curve identifier length: 8
                ECDSA elliptic curve identifier: nistp256
                ECDSA public key length: 65
                ECDSA public key (Q): 04862785baafcc04b427fc94afb8c218bc7cf3304bf46a8f…
            Multi Precision Integer Length: 32
            DH server f: b69a114f714a437eea10af55c24ffa3a6c1d7f82bde26e0c…
            KEX H signature length: 100
            KEX H signature: 0000001365636473612d736861322d6e6973747032353600…
        Padding String: 00000000000000000000
    SSH Version 2
        Packet Length: 12
        Padding Length: 10
        Key Exchange
            Message Code: New Keys (21)
        Padding String: 00000000000000000000
    SSH Version 2 (encryption:chacha20-poly1305@openssh.com mac:<implicit> compression:none)
        Packet Length (encrypted): b0a86384
        Encrypted Packet: a39e1c313eae920f96f8c3f899d1a6a8fbec57d03066ad42…
        MAC: c079d73892d1035d8c093ebee8d2d360
    [Direction: server-to-client]

Diffie Hellman関数で鍵交換

  • Frame 13

client -> server

SSH Protocol
    SSH Version 2
        Packet Length: 12
        Padding Length: 10
        Key Exchange
            Message Code: New Keys (21)
        Padding String: 00000000000000000000
    [Direction: client-to-server]

Diffie Hellman関数で鍵交換 ここで暗号化の共通キーが作られてたようです

  • Frame 15

client -> server

SSH Protocol
    SSH Version 2 (encryption:chacha20-poly1305@openssh.com mac:<implicit> compression:none)
        Packet Length (encrypted): 34c31ecb
        Encrypted Packet: 3dd12d6bdb56ae5ed5a1e2e0582e010605e48952efb30374
        MAC: fae09f0688fcc0786a1fd2f974c2b657
    [Direction: client-to-server]

共通鍵を使って以後の通信をやりとり
ログインユーザ認証もここから

  • Frame 17

server -> client

SSH Protocol
    SSH Version 2 (encryption:chacha20-poly1305@openssh.com mac:<implicit> compression:none)
        Packet Length (encrypted): 15917057
        Encrypted Packet: c2d8d1fd1bbcd26183d94e91fd7b56ec98ca32f0e06c06e2
        MAC: 95b94d9b6d38d9d4daaeb1669b18baa1
    [Direction: server-to-client]

共通鍵を使って以後の通信をやりとり

まとめ

共通鍵の作成までは意外とシンプルなフローでしたね。
RFCネゴシエーションは2~3ターンで完了します、とありましたが本当にその通りでした。

やはりといっては何ですが、暗号化用のプロトコルなのでキャプチャしても大した情報は得られませんでした。
公開ホストキーの情報も確認できると思いましたがキャプチャには載ってきませんでした。
本当はどこかに隠されているんでしょうか。こういうの見つけられたらハッカーぽくてかっこいいんですけどね。

鍵交換の部分も詳しく確認していきたいところですが、前回と今回でSSHセッションの大まかな流れが整理できたのでいったん完了にします。

しかしパケットの中身を見るのは楽しいですね。