Lab 03 で攻撃者は store_admin のメール・パスワードを取得した。しかしうつろい EC は2要素認証(TOTP)を導入済み。ログイン後、6桁の認証コード入力画面が表示される。
ところが、TOTP 検証エンドポイント /login/2fa にはレート制限が無い。6桁の数字なので候補は最大100万通り。30秒の有効期間内であれば、毎秒数千リクエストで総当たりすれば 100万 / 数千 = 数百秒で破れる。
Lab 03 で攻撃者は store_admin のメール・パスワードを取得した。しかしうつろい EC は2要素認証(TOTP)を導入済み。ログイン後、6桁の認証コード入力画面が表示される。
ところが、TOTP 検証エンドポイント /login/2fa にはレート制限が無い。6桁の数字なので候補は最大100万通り。30秒の有効期間内であれば、毎秒数千リクエストで総当たりすれば 100万 / 数千 = 数百秒で破れる。
TOTP 検証エンドポイントを総当たりして、被害者の現在の TOTP コードを破ってください。
// /login/2fa エンドポイント
$expected = totp_current_code($user->totp_secret);
if ($_POST['code'] === $expected) {
$_SESSION['fully_authenticated'] = true;
return ['status' => 'success'];
}
return ['status' => 'error', 'message' => 'コードが正しくありません'];
// ↑ 試行回数のチェックなし — 100万回の試行を許してしまう
6 桁の TOTP = 10^6 = 1,000,000 通り 有効期間 = 30 秒 (TOTP 仕様) 攻撃速度 = 1,000 req/s 程度(普通のサーバ) → 平均 500,000 / 1,000 = 500 秒で破れる 高速並列なら 10,000 req/s 程度 → 平均 50 秒 = 1 TOTP 周期内で完了
「TOTP 総当たりを開始」を押すと、000000〜999999 を高速試行(画面では加速演出)。被害者の現在のコード(ランダム)で当たります。
これは「攻撃を実装せずとも、レート制限不在を見逃すと致命的」であることの実例。Lab 03 で破ったパスワード + Lab 04 の TOTP 突破を組み合わせれば、被害者アカウントは完全に攻撃者の手に落ちます。