【Write up】Lab: Broken brute-force protection, IP block @ PortSwigger Academy

`PortSwigger Web Security Academy`が提供している`Lab: Broken brute-force protection, IP block`のWrite upです。

https://portswigger.net/web-security/authentication/password-based/lab-broken-bruteforce-protection-ip-block

# Labの概要

> This lab is vulnerable due to a logic flaw in its password brute-force protection. To solve the lab, brute-force the victim's password, then log in and access their account page.
>>Your credentials: wiener:peter
>>Victim's username: carlos
>>Candidate passwords

`Candidate passwords`では下記のパスワードリストが提供されている。

```
123456
password
12345678
qwerty
123456789
12345
1234
111111
1234567
dragon
(省略)
```

`My account`のリンクからログインページへ遷移できる。
目標は`carlos`ユーザーのクレデンシャル情報を取得しログインすること。

![login form.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/0dcdefb9-a1ea-f7ca-4b00-69bc5e605c16.png)

# 解法

まずは提供されている`wiener:peter`のアカウントでログインをしてみると`302 Found`とsessionキーが返される。

![wiener peter 302.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/6a7de0dd-9ab0-6762-2af1-eae8adb09e8c.png)

`wiener`ユーザーでログインできたことが分かる。

![wienerログイン後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/c05f81d8-73b3-4298-1db6-02d5aa49b9a0.png)

一度ログアウトし、今度は誤ったパスワードでログインを試してみると`Incorrect password`という文字列が返される。
誤った情報でログインを3回試すと`You have made too many incorrect login attempts. Please try again in 1 minute(s).`という文字列と共にリクエスト制限がかけられる。
ブルートフォース攻撃をする上でこの制限は非常に厄介なので回避したい。

この認証処理ではログインが成功するとログイン試行のカウンターがリセットされる欠陥がある。
「2回ログインに失敗し、3回目に`wiener:peter`でログインを成功させる」を繰り返すと無限にログインのリクエストを送ることができ、ブルートフォース攻撃が出来そうだ。

攻撃するにあたり、2つのファイルを用意する。
1つ目はLabで提供されているパスワードリストで1つおきに`wiener`を挿入したファイル。
`pass-list.txt`として提供されているパスワードリストをファイルに保存し、`pass-list-script.sh`を実行すれば作成できる。

```pass-list-script.sh
#!/bin/bash

# 既存のテキストリストファイル名
input_file="pass-list.txt"

# 一時ファイル名
temp_file="temp.txt"

# 既存のファイルが存在しない場合はエラーメッセージを表示して終了
if [ ! -f "$input_file" ]; then
    echo "エラー: $input_file が見つかりません。"
    exit 1
fi

# 一時ファイルを作成して、`peter` を行間に挿入して書き込む
while IFS= read -r line; do
    echo "peter" >> "$temp_file"
    echo "$line" >> "$temp_file"
done < "$input_file"

# 一時ファイルを元のファイルに上書きする
mv "$temp_file" "$input_file"

echo "ファイル $input_file が更新されました。"
```

スクリプト実行前の`pass-list.txt`。

```pass-list.txt
123456
password
12345678
qwerty
123456789
(省略)
```

スクリプトを実行し、`peter`が一行ずつ挿入されているファイルが作成された。

```pass-list.txt
peter
123456
peter
password
peter
12345678
peter
qwerty
peter
123456789
```

2つ目は、`wiener`と`carlos`が交互に記述されているファイル。
同じように`user-list-script.sh`を実行すれば作成できる。

```user-list-script.sh
#!/bin/bash

# 出力するファイル名
output_file="user-list.txt"

# 行数
lines=100

# ファイルが既に存在する場合は削除して新規作成
if [ -e "$output_file" ]; then
    rm "$output_file"
fi

# 100 行のテキストを生成
for ((i=1; i<=$lines; i++)); do
    # 奇数行は wiener、偶数行は carlos を書き込む
    if (( $i % 2 == 0 )); then
        echo "carlos" >> "$output_file"
    else
        echo "wiener" >> "$output_file"
    fi
done

echo "ファイル $output_file が作成されました。"
```

ユーザー名が交互に並んだリストが作成された。

```user-list.txt
wiener
carlos
wiener
carlos
wiener
carlos
wiener
carlos
```

ファイルの作成が終了したら、ログインのリクエストを`Intruder`に設定し、`Attack type`を`Pitchfork`に、`username`と`password`のパラメータ部分を`Add§`で囲む。

![pitchfork.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/39614057-7e08-a5fa-5658-fa569d204494.png)

次に`Payloads`タブに移動、`Payload set`を`1`にし、`Payload settings`の`Load`から作成したユーザーリストのファイルを選択する。

![payload1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/4413074f-f377-c1f8-4aee-87ba1bfe49fe.png)

`Payload set`を`2`にし、`Payload settings`の`Load`から作成したパスワードリストのファイルを選択する。

![payload2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/3b86e142-c717-908c-4c00-9d94c5d1096b.png)

`Resource pool`タブに移動し、`Create new resource pool`を選択、`Maximum concurrent requests`を`1`に設定する。

![Resource pool.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/c4bcc0ca-e77b-b6fc-220b-20ab2aeea7d8.png)

上記の設定が完了したら、右上の`Start Attack`ボタンをクリックして攻撃開始。

`wiener:peter`のログインと`carlos:<パスワードリスト>`のログインが交互に試行される。

![ログイン試行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/e405ff6f-c788-1947-402f-ffd338bfd74d.png)

ログインが成功した場合ステータスコード`302`で返ってくるのでフィルタリングすると、`carlos`ユーザーのパスワードを発見できた。

![finish.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/ca7def6c-aaf1-b8b7-a188-62dfb670a504.png)

最後に特定できたユーザー情報でログインしてLabは完了です。

![login success.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/5a0ecc40-89c5-bf6a-0393-2deecc68ff5d.png)