web-dev-qa-db-ja.com

SSH:公開鍵と既知の中間者を使用

通常、人々はどこでも単一の秘密鍵と公開鍵のペアを使用することをお勧めします(私たちが秘密鍵を危険にさらす可能性について話していない場合):

  1. ベストプラクティス:「ユーザーごとに1つのSSHキー」または「ホストごとに複数のSSHキー」
  2. 秘密鍵/公開鍵の再利用
  3. https://serverfault.com/questions/80478/ssh-do-you-use-one-private-public-key-pair-for-each-remote-machine-or-a-single/80483# 8048

    SSHを介したクライアント証明書認証を使用する場合、これにより脆弱性が生じるようです。提案するのはとても人気があるので、以下の「アルゴリズム」は機能しないと思います。しかし、私はそれが正確に何が悪いのか分かりません。

説明をできるだけ詳細にして、可能な限り矛盾を最小限に抑えようとしました。そのため、長さをお許しください...

前提条件

  • PC1には、(S1_id_rsa.pubS2_id_rsa.pub)の両方のフィンガープリントがあります彼の既知のホスト。
  • Server1PC1のアカウントがServer2に存在することをどういうわけか知っています。
  • キー:
    • PC1:hasP1_id_rsaS1_id_rsa.pubS2_id_rsa.pub
    • Server1、攻撃者:hasS1_id_rsaP1_id_rsa.pubS2_id_rsa.pub
    • Server2:hasS2_id_rsaP1_id_rsa.pub

アルゴリズム

これはよく知られた 中間者攻撃 に似ていますが、少し異なります。

  1. PC1は(Hi /)をServer1に送信します
  2. Server1は(Hi /)をServer2に送信します
  3. サーバーは公開鍵を共有しています

    1. Server2Server1を送信しますS2_id_rsa.pub
    2. Server1PC1S1_id_rsa.pubを送信します(S2_id_rsa.pub
    3. PC1S1_id_rsa.pubのフィンガープリントを受け入れます(既知のとおり)
  4. Diffie-Hellman を使用して、2つの個別の共有秘密トンネルが生成されます。

    1. 「サーバー1-サーバー2」

      1. Server2はDH1.aを生成し、S2_id_rsaで署名されたDH1.AをServer1
      2. Server1はDH1.bを生成し、DH1.BをServer2に送信します
      3. トンネルが確立されました
    2. "PC1--Server1"
      1. Server1はDH2.aを生成し、S1_id_rsaで署名されたDH1.AをPC1
      2. PC1はDH2.bを生成し、DH2.BをServer1に送信します
      3. トンネルが確立されました。
  5. クライアント認証(Server2は、彼がPC1)と通信していることを確認したい

    1. PC1P1_id_rsa.pubServer1に送信します
    2. Server1P1_id_rsa.pubServer2に送信します
    3. Server2はチャレンジを生成します。チャレンジはP1_id_rsaでのみ解決でき、Server1
    4. Server1PC1へのチャレンジのみをトンネルします
    5. PC1がチャレンジを解決し、回答をServer1に送信します
    6. Server1トンネルはServer2に応答します
    7. できました。
  6. できた

追伸私はウィキペディアで 公開鍵暗号中間者攻撃 を調べました、そして この非常に詳細な答え (私の見解プロセス全体の大部分はそれに基づいています)が、答えはわかりません。

読みやすい「ダミーのssh認証と暗号化プロセス」を見つけることができませんでした...

Server Faultについてはすでに同じ質問をしましたが、ここに再投稿するには 推奨されました です。

6
Igor

最後に、私はそれを得たと思います。

まず第一に-私の説明ではssh v1とssh v2プロトコルを混同しています。チャレンジ/レスポンス認証はssh v1からのものです。

Ssh v2では、クライアントは自分の秘密鍵で特定のパッケージに署名するだけで、サーバーは格納された公開鍵を使用してそれをチェックします。このパッケージはrfcで説明されています here

To perform actual authentication, the client MAY then send a
signature generated using the private key.  The client MAY send the
signature directly without first verifying whether the key is
acceptable.  The signature is sent using the following packet:

  byte      SSH_MSG_USERAUTH_REQUEST
  string    user name
  string    service name
  string    "publickey"
  boolean   TRUE
  string    public key algorithm name
  string    public key to be used for authentication
  string    signature

The value of 'signature' is a signature by the corresponding private
key over the following data, in the following order:

  string    session identifier
  byte      SSH_MSG_USERAUTH_REQUEST
  string    user name
  string    service name
  string    "publickey"
  boolean   TRUE
  string    public key algorithm name
  string    public key to be used for authentication

したがって、署名されたパッケージには、計算された「セッション識別子」が含まれています 次のように

  H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K)
  <…..>
  mpint     K, the shared secret  

つまり、署名は共有秘密に依存し、共有秘密はP1<->S1およびS1<->S2トンネル。

3
Igor

通常、人々はどこでも単一の秘密公開鍵ペアを使用することを推奨します(私たちが秘密鍵を危険にさらす可能性について話していない場合)

SSH接続には2つのキーペアが含まれることに注意してください。

  • 1つはサーバーのホストを識別します(サーバーには秘密鍵があります)。
  • 公開鍵認証を使用している場合、1つはユーザーを識別するためです(クライアントは秘密鍵を持っています)。

引用する推奨事項は、ユーザーキーに関するものです。ユーザーごとに1つの秘密キーを使用することは実行可能なモデルですが、特にお勧めしません(ホストまたはサイトごとに個別のキーペアを使用するコストはそれほど高くありません)。一方、サーバーキーは複製されません。これらは、SSHサーバーのインストール時に新たに生成されます。

このトピックについては、質問で引用した投稿の他に、次も参照してください SSHのauthorized_keysファイルとknown_hostsファイルの違いは何ですか?

あなたが説明する攻撃では、鍵の役割を混同しています。これらはホストキーssh_Host_rsaであり、ユーザーキーではありません。これは、説明する攻撃の動作には直接関係ありませんが、混乱の一部である可能性があります。

スティッキーポイントはステップ3.3にあります。

PC1はS1_id_rsa.pubのフィンガープリント(既知)を受け入れます

2つのケースがあります。

  • PC1が以前にS2に接続したことがある場合、PC1(より正確にはPC1のユーザーのアカウント)はS2のホスト公開鍵をknown_hostsファイルに記憶しています。そのため、S1がS2のホストキーを送信した場合、PC1のSSHクライアントは、ホストキーが記録されたホストキーと一致しないことを検出し、怖いメッセージで接続を中止します。

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @    WARNING: REMOTE Host IDENTIFICATION HAS CHANGED!     @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
    Someone could be eavesdropping on you right now (man-in-the-middle attack)!
    It is also possible that the RSA Host key has just been changed.
    

    したがって、このシナリオでは攻撃は不可能です(ユーザーがチェックを回避するために邪魔をしない限り、OpenSSHは意図的にこれを困難にします)。

  • PC1がS2に接続したことがない場合、PC1はS1がS2のキーであると伝えているものを何でも受け入れます。 PC1は、名前S2と暗号化IDとの関連付けについて事前の知識がなく、そのような関連付けを知っている信頼できる第三者(つまり、公開鍵インフラストラクチャ)に連絡する方法もないため、この操作を防ぐ方法はありません。中間攻撃。

問題は、サーバー1の証明書を使用しているため、クライアントがサーバー1と通信していることをクライアントが知っていることです。 server1にserver2であることを示す有効な証明書がある場合、クライアントが以前にserver2に接続したことがない場合、クライアントはそれを認識しません。ただし、ほとんどのSSHクライアントは、特定のサーバー用に接続する証明書のフィンガープリントを追跡します。クライアントが接続に行き、サーバー1に接続すると、証明書が署名されていても、指紋が変更されたという警告がユーザーに表示される可能性があります。

S2であると主張するS1への既知の接続について、s2がp1の秘密鍵を正確に知っている場合、01がs1を介してs2と通信したい場合、s2を暗号化し、s2がp1を暗号化します。 p1がs2から鍵交換を受け取らない場合、s1はs2としてp1との交換に署名できないため、問題があることがわかります。

1
AJ Henderson

実際、これは信頼できるリストにあるクラックされた証明書の既知の脆弱性であり、失効リストが必要な理由です。

この攻撃が機能するには、2つの穴が必要です。

  1. PC1は実際にserver1と通信している間、server2と通信していると考える必要があります。
  2. PC1にはS1_id_rsa.pubを信頼できる証明書として使用し、server2のアドレスを指します(そうしないと、PC1はステップ#4.3でserver2ではなくserver1と通信していることを認識します)。

#1は信頼できないネットワークで発生する可能性がありますが、#2は、server1が自身を信頼できるパーティとして挿入することを許可した以前の違反が発生した場合にのみ発生します。

0
ratchet freak