世の中には数多くのハッキング方法が存在します。
今回はその一つであるタイミング攻撃を紹介したいと思います。
タイミング攻撃とは
何らかのアプリへの入力に対する応答時間を利用した攻撃手法です。
なぜ応答時間がハッキングに利用されるのか
プログラムの多くは基本的に正誤の判定を最適化して応答してしまうからです。
例えば、文字列Aと文字列Bが一致するかを判定する場合、プログラムは
1文字目が同じかどうか、2文字目が同じかどうか…n文字目が同じかどうかといった感じで判定していき、違う文字が出現した段階で違う文字列として「違う文字列だよ」と応答します。
つまり、一致する文字が多いほど応答に時間がかかることになります。
よって、応答時間が長い文字がパスワードに使用されているとハッカーに推測されてしまうわけです。
実際にハッキングしてみる
最悪のパスワードチェックプログラム
まずは最も愚かなパスワードチェックプログラムの一例を以下に示します。
def check_password(input_password):
password = get_password()
if len(input_password) != len(password):
return False
for i in range(len(password)):
if input_password[i] != password[i]:
return False
return True
このプログラムの愚かなところは、上記した「1文字ずつ比較」しているところに加え、パスワードの長さに関する判定まで組み込んでいるところです。
これにより、タイミング攻撃がさらに容易になってしまいます。
攻撃
上記のパスワードチェックプログラムに対してタイミング攻撃を仕掛けてみます。
方法は単純で、
- 1文字ずつ文字数を増やした適当なパスワードを与えて最も時間がかかった文字数を得る
- 最も時間がかかった文字数分の文字列を1文字ずつ入れ替え、より時間のかかる文字列を調べる
これだけです。Pythonにはtimeitという時間計測用の標準モジュールがあるので、
alt_time = timeit.repeat(
stmt="check_password(input_password)",
setup=f"input_password={alt!r}",
globals=globals(),
number=trials,
repeat=10
)
input_password_time = timeit.repeat(
stmt="check_password(input_password)",
setup=f"input_password={input_password!r}",
globals=globals(),
number=trials,
repeat=10
)
こんな感じで時間を計測していきます。
では実行してみましょう。
大小英数字という一般的なパスワードを想定して攻撃してみましたが、たったの22秒でハッキングが完了しました。
タイミング攻撃を防ぐには
字面通り、タイミングをずらしてやれば解決です。
Python3.6以降にはsecretsというセキュリティ系ライブラリをユーザーフレンドリーにした標準モジュールがあるのでこれを使うと良いでしょう。
def check_password_corrected(input_password):
password = get_password()
return secrets.compare_digest(input_password, password)
まとめ
ChatGPTなどの台頭により、誰でもプログラムを簡単に作成できるようになりましたが、AIは倫理やセキュリティなんてものは明確に指示しないと意識しません。
誰でも簡単にプログラムを作成できる世の中だからこそ、個々人のセキュリティ意識はより高くしていく必要があると思います。
コメント