Linux

known_hosts ファイル内のハッシュ化されたホスト名(IPアドレス)を自分で算出する

投稿日:

1. はじめに

Linux では /etc/ssh/ssh_config ファイルに、「HashKnownHosts yes」と記述してある場合、known_hosts ファイル内のホスト名(IPアドレス)部分がハッシュ化されます。

/etc/ssh/ssh_config ファイルの例

(省略)
Host *
  (省略)
  HashKnownHosts yes
  (省略)

known_hosts ファイル内の行の例(ハッシュされていない場合)

192.30.253.113 ssh-rsa {公開鍵を表す文字列}

この行がハッシュ化されると以下に変化します。

|1|8V1J9OVTw6LucO4ldA8vUzfBJaE=|kmv/2pGp40XQR7CCuvxqKb3IgnM= ssh-rsa {公開鍵を表す文字列}
  • IPアドレスだった部分が、別の文字列になっています。それ以降の部分に変化はありません。

本記事では、この文字列を自分で算出する方法を紹介します。

2. 実験

とある ~/.ssh/known_hosts ファイルの内容をハッシュ化してみます。

ハッシュ化する前は、以下の行が存在していました。

github.com,192.30.253.113 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==

以下のコマンドを実行することによって、known_hosts ファイル(のホスト名部分)をハッシュ化することができます。

$ ssh-keygen -H -f ~/.ssh/known_hosts

先程の行は以下のようになりました。

|1|R0yjBY6jpUzgTmJU82oSOUjIBLQ=|HCaWOPa5tIlXcNV5Ja99BEd53RA= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
  • github.com,192.30.253.113」だった部分が「|1|R0yjBY6jpUzgTmJU82oSOUjIBLQ=|HCaWOPa5tIlXcNV5Ja99BEd53RA=」に変化しています。
  • この部分は「|」で区切られており、最初の「1」はハッシュ化されていることを表します。
  • 次の「R0yjBY6jpUzgTmJU82oSOUjIBLQ=」はハッシュを算出する際に使うキーで、ソルトとして使われているようです。
  • 最後の「HCaWOPa5tIlXcNV5Ja99BEd53RA=」がハッシュ化された文字列です。

では、ホスト名(IPアドレス)である「github.com,192.30.253.113」と「R0yjBY6jpUzgTmJU82oSOUjIBLQ=」から、「HCaWOPa5tIlXcNV5Ja99BEd53RA=」を求めてみます。

いろいろ調べた結果、SSH HashKnownHosts File FormatA guide and tool for cracking ssh known_hosts files with hashcat に必要なコマンドが記載されていました。

これらの情報を元にして、以下の内容を記述したファイルを作成し、実行権限を与えて実行しました。

#!/usr/bin/sh
set -eu

hexkey=$(echo 'R0yjBY6jpUzgTmJU82oSOUjIBLQ=' | base64 --decode | xxd -p)
echo -n 'github.com' | openssl sha1 -binary -mac HMAC -macopt hexkey:$hexkey | base64
  • ハッシュのアルゴリズムとして HMAC-SHA-1 が利用されているようなので、openssl sha1 コマンドに、-mac HMAC-macopt オプションを指定して実行しています。
  • まず、ハッシュ化する際のキーである文字列を Base64 でデコードし、それを16進数表現にした文字列を変数 hexkey にセットしています。
  • 次の行では、その hexkey をキーとして HMAC-SHA-1 アルゴリズムを利用し、’github.com’ のハッシュを算出して、それを Base64 でエンコードしています。
  • 元の行には、github.com というホスト名だけでなく IPアドレスもありましたが(‘github.com,192.30.253.113’ の部分) 、ここではホスト名しか利用していません。実は IPアドレスをハッシュ化した行は別に生成されています。つまり、ssh-keygen -H コマンドによって、1行が2行になっています。上記の「echo -n ‘github.com’」の部分を「echo -n ‘192.30.253.113’」にすると、生成されるハッシュ値が元の文字列と一致しないので、その行は ‘github.com’ の行だと分かりました(キーも違います)。
  • 元の行のホスト名(IPアドレス)の部分が、「[IPアドレス]:ポート番号」となっている場合は、上記の「echo -n ‘github.com’」の部分を「echo -n ‘[IPアドレス]:ポート番号’」とします。
  • -binary, -mac, -macopt ,プションについては /docs/manmaster/man1/openssl-dgst.html で説明されています。

ここでは calc_hash.sh というファイル名にして実行してみました。

$ ./calc_hash.sh
HCaWOPa5tIlXcNV5Ja99BEd53RA=

想定通りの文字列が出力されました。

3. メモ

  • この仕様はかなり古いために、脆弱な HMAC-SHA-1 というハッシュアルゴリズムが採用されているようです。
  • 本文でもリンクを貼った chris408/known_hosts-hashcat: A guide and tool for cracking ssh known_hosts files with hashcat には、hashcat を使って known_hosts ファイルのハッシュ文字列からIPアドレスを割り出す方法が紹介されています。
  • known_hosts ファイルのホスト名(IPアドレス)がハッシュ化されていると、シェル上でホスト名の補完が効かないために HashKnownHosts を no と設定している環境もあるようです。

4. 参考

📂-Linux
-

執筆者:labo


comment

メールアドレスが公開されることはありません。

関連記事

WSL

WSL の Ubuntu 16.04 LTS を 18.04 LTS にアップグレードする

WSL の Ubuntu 16.04 LTS を 18.04 LTS にアップグレードしたときの手順を記録します。 目次1. 公式な情報2. 現状確認3. アップグレード作業(1) パッケージを最新の …

Linux

Bash: コマンド履歴のインクリメンタル検索でハイライトされないようにする

Bashにおいて、コマンド履歴のインクリメンタル検索でハイライトされないようにする方法を紹介します。

Linux

CentOS Stream 8 に OpenDKIM を導入する

CentOS Stream 8 に OpenDKIM を導入する手順について説明します。

Linux

指定した条件にマッチするファイルを検索する find コマンド

find コマンドについて説明します。 ※ 本ページで扱うのは、find (GNU findutils) 4.7.0-git です。 目次1. find コマンドの使い方式 (EXPRESSION)式 …

CentOS

CentOS 8 標準の Apache と PHP の関係について

CentOS 8 における Apache と PHP の関係について説明します。