@iamproz2911 @kidwine29
## Challenge1: Reset Password
Bạn đang kiểm thử chức năng "Reset mật khẩu qua email", gồm:
+ Nhập email để yêu cầu reset
+ Nhận link qua email (chứa token)
+ Click mở form đổi mật khẩu mới
+ Nhập password mới + xác nhận → Submit
### Luồng hệ thống:
Nhập email → nhận link (chứa token)
Token dẫn đến form đổi mật khẩu
Gửi mật khẩu mới → cập nhật thành công
### Các yếu tố nhắm vào để test bảo mật:
Input field (email, new password)
Token trong email (sensitive!)
Tốc độ gửi request (brute force)
Replay attack, token reuse
Link expire không đúng
Input chứa script (XSS)
### Thiết kế Test Case bảo mật (dạng bảng)

### Viết Python Script mô phỏng Security Test
**Mục tiêu:**
Viết script để test:
Gửi request reset
Click link reset (token)
Thử replay token
In kết quả
**API:**
POST /reset-request: gửi email
GET /reset?token=xyz: mở form
POST /reset-submit: gửi mật khẩu mới (token, new_pass, confirm)
Code mẫu như sau:
Sử dụng request:
```
import requests
BASE_URL = "http://example.com"
# Step 1: Gửi yêu cầu reset
def request_reset(email):
r = requests.post(f"{BASE_URL}/reset-request", data={"email": email})
print("[*] Reset request sent.")
return r.text # giả định nhận được token trong response (demo)
# Step 2: Gửi mật khẩu mới với token (có thể lặp để test replay)
def submit_new_password(token, new_pass="12345678"):
r = requests.post(f"{BASE_URL}/reset-submit", data={
"token": token,
"new_pass": new_pass,
"confirm": new_pass
})
print(f"[+] Submit token {token} → status: {r.status_code}")
print(r.text)
# Ví dụ sử dụng
if __name__ == "__main__":
token = "abc123" # Demo: token giả định đã lấy từ email
submit_new_password(token) # Lần 1 → OK
submit_new_password(token) # Lần 2 → Fail (nếu bảo mật tốt)
```
Hoặc có thể code tools bruteforce, XSS, Sai confirm để test validation.
### Report
Giả sử mắc lỗi tại Replay Attack
Bản báo cáo như sau:
```
**Title:** Replayable Reset Token allows attacker to reuse link
**Severity:** High
**Component:** /reset-submit
**Steps to Reproduce:**
1. Submit reset password request for user A → receive token1
2. Use token1 to reset password → success
3. Reuse token1 to submit new password again
**Expected Result:**
- Token should be invalid after first use
**Actual Result:**
- Token can be reused multiple times → attacker can hijack session if intercepted.
**Suggested Fix:**
- Invalidate token after use
- Use short-lived tokens, link expiration, rate limiting
```
## Challenge2: Upload file
Ứng dụng có chức năng upload file đại diện (avatar)
### Luồng hệ thống:
Người dùng đăng nhập → vào trang Profile
Có form upload file: chọn ảnh đại diện → Submit
Server chấp nhận file .jpg, .png, .jpeg
Sau khi upload, avatar sẽ hiển thị trên trang profile
**API:**
POST /server.com/upload
### Thiết kế Test Case bảo mật (dạng bảng)

### Viết script test
Test chức năng upload file không check dung lượng
```
#include <iostream>
#include <curl/curl.h>
#include <string>
int main() {
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
const char* file_path = "big_test_file.dat";
const char* upload_url = "http://your-server.com/upload";
struct curl_httppost* form = NULL;
struct curl_httppost* last = NULL;
curl_formadd(&form, &last,
CURLFORM_COPYNAME, "file",
CURLFORM_FILE, file_path,
CURLFORM_END);
curl_easy_setopt(curl, CURLOPT_URL, upload_url);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, form);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, [](char* ptr, size_t size, size_t nmemb, void* userdata) -> size_t {
size_t total = size * nmemb;
std::cout << std::string(ptr, total);
return total;
});
std::cout << "Uploading file: " << file_path << "...\n";
res = curl_easy_perform(curl);
if(res != CURLE_OK)
std::cerr << "Upload failed: " << curl_easy_strerror(res) << "\n";
else
std::cout << "Upload succeeded.\n";
curl_formfree(form);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
```
### Report
**Title:** Upload file without checking file size
**Severity:** High
**Component:** /uploads
**Steps to Reproduce:**
1. Prepare a file about 5gb and get the file path
2. Upload directly to the server in .jpg format that the server allows
3. The server successfully downloaded the file without returning any messages or errors.
**Expected Result:**
- Disallow upload and send notification ("uploaded file exceeds allowed capacity")
**Actual Result:**
- Allow downloading files up to 5gb -> attack can cause DoS attack
**Suggested Fix:**
- Upload size limit, around 2 or 3 mb depending on system.
### Tối ưu testcase
| STT | Test Case | Vulnerability | Expected Result |
| --- | ------------------------------------------ | ------------------------------------------- | --------------------------------------------------- |
| 1 | Upload large file (1–5GB) | **DoS (Unrestricted Upload)** | Server rejects upload > X MB, returns clear message |
| 2 | Bypass extension filter (`shell.php.jpg`) | **Content-Type Bypass / RCE** | File rejected despite .jpg extension |
| 3 | Test file name tampering (`../avatar.jpg`) | **Path Traversal** | Server sanitizes filename, stores safely |
| 4 | Upload valid file, access URL directly | **Insecure Direct Object Reference (IDOR)** | URL is protected / randomized |
| 5 | Upload image with embedded JS in metadata | **Stored XSS / Script Injection** | Script is not executed on profile view |
| 6 | Reuse upload URL for other user | **Broken Access Control** | Server denies cross-user access |
### Case khó và hiểm hơn
1. Bypass Content-Type bằng Content-Type: image/png nhưng nội dung là shell (file.php nhưng content_type: img/images)
2. Upload file có Polyglot payload – vừa là ảnh vừa là mã thực thi
3. Tấn công Stored XSS qua tên file / metadata ảnh(exiftool -Comment='<script>alert(1)</script>' x.jpg)
4. Tạo ZIP Bomb hoặc evasion file (zip nhỏ nhưng bung ra khoảng 5gb)
5. Test race condition – cùng lúc 2 người upload trùng tên
## Challenge 3: OTP send Email
Ứng dụng có chức năng "Xác thực OTP" khi người dùng thực hiện hành động quan trọng (ví dụ đổi mật khẩu, xác minh tài khoản...).
### Luồng hoạt động như sau:
Người dùng nhập email hoặc số điện thoại.
Hệ thống gửi mã OTP gồm 6 số (VD: 932751).
Người dùng nhập mã OTP → hệ thống xác thực.
**API:** /api/send-otp
### Thiết kế Test Case bảo mật (dạng bảng)

### Viết script test
Dùng python test gửi nhiều yêu cầu gửi mã OTP
```
import requests
import time
def test_otp_rate_limit():
url = "https://server.com/api/send-otp"
hearders = {'Content-Type': 'application/json'}
data = {'phone-number': '0123'}
for i in range(10):
response = requests.post(url, json=data, headers=hearders)
print(f"Yêu cầu {i+1}: {response.status_code}")
time.sleep(1)
test_otp_rate_limit()
```
### Report
**Title:** Send multiple OTP code requests
**Severity:** High
**Component:** /send-otp
**Steps to Reproduce:**
1. Enter email to receive OTP
2. Continue sending other OTP code requests
**Expected Result:**
- Do not allow sending another OTP code if the current code has not expired
**Actual Result:**
- Multiple OTP codes are sent back for each request, causing damage to the company's resources and budget.
**Suggested Fix:**
- Limit the waiting time between OTP requests.
- Warning if continue will have to wait longer.
### Tối ưu Test case
| STT | Test Case | Mục tiêu bảo mật | Expected Result |
| --- | -------------------------------------------------------------- | ----------------------- | ---------------------------------------------- |
| 7 | Gửi OTP sau khi login session hết hạn | Session Handling | Server không gửi OTP nếu session không hợp lệ |
| 8 | Thay đổi số điện thoại/email giữa quá trình gửi & xác minh OTP | Insecure State Handling | OTP không hợp lệ nếu input đầu vào bị thay đổi |
| 9 | Xem log/debug để tìm OTP bị ghi log | Information Disclosure | OTP không nên ghi vào log/debug file |
| 10 | Phân tích entropy OTP (kiểm tra độ ngẫu nhiên) | Predictable OTP | OTP phải đủ random (không lặp/tiên đoán được) |
## Challenge 4: PRIVILEGE ESCALATION
Tình huống:
Trong ứng dụng web, người dùng có thể:
Truy cập trang /account/edit sau khi login
Form có các trường: tên, email, số điện thoại, địa chỉ, avatar...
Khi nhấn Submit, dữ liệu được gửi qua PUT /api/user/{id}
### Thiết kế Test Case bảo mật (dạng bảng)

### Viết script test
```
import requests
url = "https://server.com/api/user/1"
session = requests.Session()
response = session.get(url)
csrf_token = session.cookies.get('XSRF-TOKEN')
if csrf_token:
print(f"CSRF Token get: {csrf_token}")
else:
print(f"Không tìm thấy")
exit()
headers = {
'X-CSRF-TOKEN': csrf_token,
'Content-Type': 'application/json'
}
data = {
'name': 'newname',
'phone': 'newphone'
}
put_response = session.put(url, headers=headers, json=data)
if put_response.status_code==200:
print("updated")
else:
print("Lỗi: {put_response.text}")
new_csrf_token = session.cookies.get('XSRF-TOKEN')
if new_csrf_token != csrf_token:
print("đã thay đổi: {new_csrf_token}")
else:
print("chưa thay đổi")
```
### Report
**Title:** Change CSRF In PUT request
**Severity:** High
**Component:** /api/user/{user_id}
**Steps to Reproduce:**
1. GET Request to endpoint /api/user/{id} or /user/profile to get CSRF token.
2. After obtaining the CSRF token from the response, a PUT request needs to be sent to update the profile, ensuring that the CSRF token is passed as requested.
3. In the Headers tab, add the CSRF token to the request header.In the Body tab, submit the data you want to update.
4. Check Response: After sending PUT request, check the response.
**Expected Result:**
- The new token is returned in cookies or in the request response.
**Actual Result:**
- CSRF token remains unchanged. Can send put request with old CSRF to update profile of user.
**Suggested Fix:**
- Update CSRF token after each data change action
- Block request when CSRF token is invalid
### Tối ưu testcase
| STT | Test Case | OWASP Risk | Expected Result |
| --- | ----------------------------------------------------- | --------------------------- | ------------------------------------------ |
| 1 | Inject `<script>` vào input | **XSS** | Script không thực thi, dữ liệu được escape |
| 2 | Inject `' OR 1=1--` vào email | **SQLi** | Không ảnh hưởng DB, dữ liệu được sanitize |
| 3 | Đổi `user_id` → chỉnh thông tin người khác | **IDOR** | Trả về 403 hoặc block |
| 4 | Gửi request khi chưa login | **Broken Auth** | Trả về 401/403, yêu cầu login |
| 5 | Upload file `.php` / polyglot `.jpg` | **Insecure Upload** | Chỉ cho phép MIME hợp lệ |
| 6 | CSRF token không thay đổi → submit PUT | **CSRF** | Token phải đổi sau mỗi hành động |
| 7 | Nhập input dài + ký tự đặc biệt | **Improper Input Handling** | Dữ liệu được giới hạn và làm sạch |
| 8 | Truyền data nhạy cảm qua HTTP | **Unencrypted Transport** | Dữ liệu phải đi qua HTTPS |
| 9 | Truy xuất các field không cần thiết (e.g. `is_admin`) | **Excessive Data Exposure** | Chỉ trả dữ liệu cần thiết |
| 10 | Gửi nhiều lần PUT → đo phản hồi | **Rate Limit** | Sau X lần phải bị block/tạm ngưng |
### Case khó và hiểm hơn
| TC# | Mô tả | Dữ liệu gửi | Kết quả mong đợi |
| ---- | ---------------------------------------------------- | -------------------------------- | ---------------------------------------------------------------- |
| TC01 | Thử inject `is_admin: 1` vào JSON khi update profile | `{ "name": "A", "is_admin": 1 }` | Server từ chối hoặc bỏ qua `is_admin`, không thay đổi quyền user |
## Challenge 5: User Authorization
### Tình huống
Ứng dụng có 3 loại người dùng:
User bình thường (ROLE: user)
Quản trị viên nhóm (ROLE: manager)
Admin toàn hệ thống (ROLE: admin)
**API endpoint:**
GET /users → xem danh sách người dùng (admin mới được)
PUT /user/{id}/role → thay đổi role của user
DELETE /user/{id} → xóa user
GET /report → xem báo cáo toàn hệ thống (manager, admin được phép)
### Thiết kế Test Case bảo mật (dạng bảng)

### Viết script test
```
import threading
import requests
import time
BASE_URL = "https://server.com"
USER_ID = 123
TOKEN = "23243"
headers = {
"Authorization": f"Bearer {TOKEN}",
"Content_Type": f"application/json"
}
def update_role_to_admin():
url = f"{BASE_URL}/user/{USER_ID}/role"
data = {
"role": "admin"
}
response = requests.put(url, headers= headers)
print("[PUT /user/{id}/role]", response.status_code, response.text)
def access_report():
url = f"{BASE_URL}/report"
response = requests.get(url, headers= headers)
print("[GET /report]", response.status_code, response.text)
thread1 = threading.Thread(target=update_role_to_admin)
thread2 = threading.Thread(target= access_report)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
```
### Report
**Title:** Race condition API Change Role and Get Report(Admin only)
**Severity:** High
**Component:** GET /report and PUT /user/{id}/role
**Steps to Reproduce:**
1. Use the role change API to change to the admin role
2. Next, access the Get / Report API to check if the role has changed and the data can be read.
3. If the server performs the role check function before viewing the report, the time between the two may not be optimal.
4. Use thread to send 2 processes in parallel to test
**Expected Result:**
- Sends back status 403 forbidden and system says no access
**Actual Result:**
- Returns status code 200 OK and lists system reports under admin rights
**Suggested Fix:**
- Do not use old tokens after changing rights
- After the role is changed → the system must force a new user to log in
- Make sure PUT /user/{id}/role only returns after: The role has actually changed and the old token has been revoked
- Temporarily lock access to high-level resources while roles are changing
- Security: Check permissions directly from DB
### Tối ưu testcase
| TC | Gây ấn tượng mạnh vì |
| ------ | ------------------------------------------------------------- |
| ✅ TC2 | Gửi `"role": "admin"` → classic **insecure role change** |
| ✅ TC5 | Thử đổi endpoint `/user → /admin` để **API discovery** |
| ✅ TC8 | Inject query param `?type=admin` → ít ai test, nhưng có thật |
| ✅ TC10 | Race condition giữa PUT & GET → **bug bounty mindset** |
| ✅ TC9 | Path traversal trong REST API → kiểm tra dev có lọc đường dẫn |
### Case khó và hiểm hơn
## Challenge 6: Token Handling & Authentication Check
### Tình huống:
Một hệ thống web sử dụng JWT (JSON Web Token) để xác thực người dùng. Cơ chế như sau:
Khi đăng nhập, server trả về access_token và refresh_token.
access_token dùng trong 15 phút, truyền qua Authorization: Bearer ...
Khi hết hạn, người dùng dùng refresh_token để gọi API /auth/refresh để lấy token mới.
Có 2 endpoint quan trọng:
GET /user/profile → cần access_token
POST /auth/refresh → cần refresh_token
### Thiết kế Test Case bảo mật (dạng bảng)

### Viết script test
CURL test LogInjection
```
curl -X POST http://example.com/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token": "abc123\n[ERROR] Admin logged in\n"}'
```
```
abc\n[INFO] User admin logged in
" OR ""="
\r\n[ERROR] LOGIN FAILED
"; DROP LOGS --
```
### Report
**Title:** Loginjection in Refresh Token Function
**Severity:** Mid
**Component:** POST /auth/refresh
**Steps to Reproduce:**
1. Check the post API to see what it carries
2. Try payload {
"refresh_token": "abc123\n[ERROR] Admin hacked"}
3. Check status code and viewlog
4. Use Payload Loginjection insert in username or refresh_token and viewlog
**Expected Result:**
- Sends back status 403 forbidden and system says no access
**Actual Result:**
- Returns statuscode 401 Unauthorized, the system reports that the token is invalid.
**Impact:**
- Disrupt or disrupt log-based automated monitoring systems
- Hide traces of malicious behavior
- Maybe Stored XSS (less common).
**Suggested Fix:**
- Escape or remove dangerous characters in input
- Do not log unverified data directly
- Limit the length of data logged
### Tối ưu testcase
| STT | Nhận xét chi tiết |
| ----- | ------------------------------------------------------------------------------------------------------------------------------------- |
| ✅ TC1 | **Replay refresh token** là ý tưởng rất thực tế, thường bị khai thác để spam access token hoặc chiếm quyền. |
| ✅ TC2 | Test **reusing expired access token** sau khi refresh là đúng logic JWT lifecycle |
| ✅ TC3 | **JWT tampering bằng sửa payload "role": "admin"** kiến trúc token-based auth. |
| ✅ TC4 | **SQLi trong token** test được case **nội suy token vào query**. |
| ✅ TC5 | Test mã hóa lại JWT → khá sáng tạo, nên ghi rõ hơn: “dùng token decode, sửa payload, encode lại nhưng không sign → replay”. |
| ✅ TC6 | **IDOR thông qua token bypass + param user\_id** → classic test nhưng hiệu quả. |
| ✅ TC7 | **Log injection** → một trong những kỹ thuật (đặc biệt trong SOC alert pipeline). |
| ✅ TC8 | **SQLi trong Authorization header** → đây là một case **rất ít người đụng tới**, header-level injection. |
## Challange 7: CAN + Setting via API
Các kiến thức cần có Automotive & Firmware, STRIDE Threat Mod
| OWASP Principle | Ứng dụng trong Automotive |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **Input Validation** | Dùng để kiểm tra dữ liệu gửi vào ECU (qua CAN, Bluetooth, app...) – tránh buffer overflow, command injection. |
| **Authentication & Authorization** | Kiểm tra xem firmware hoặc ứng dụng có phân quyền đúng khi truy cập chức năng (ví dụ: khởi động động cơ, phanh từ xa). |
| **Secure Communication** | Đảm bảo các giao tiếp OTA, Bluetooth, Wi-Fi, LTE được mã hóa (TLS, VPN), tránh MITM. |
| **Logging & Monitoring** | Hệ thống xe nên có tính năng phát hiện hành vi bất thường trong CAN (ví dụ: ECU gửi quá nhiều message – flood attack). |
| **Fail Securely** | Khi có lỗi, xe cần về trạng thái an toàn (ví dụ: mất tín hiệu cảm biến thì không tự động phanh khẩn cấp nhầm). |
| **Least Privilege** | Mỗi ECU nên chỉ được phép làm đúng chức năng, tránh privilege escalation (ví dụ: hệ thống giải trí không được điều khiển tay lái). |
| Ký hiệu | Mối đe dọa | Ví dụ trong ứng dụng ô tô thực tế |
| ------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **S** | **Spoofing (Giả mạo danh tính)** | Hacker giả mạo tài khoản của chủ xe, đăng nhập vào app điều khiển từ xa và **mở khóa xe trái phép**. |
| **T** | **Tampering (Sửa đổi dữ liệu)** | Kẻ tấn công can thiệp vào giao tiếp giữa app và server, **sửa thông số trạng thái xe** (như mức pin, vị trí). |
| **R** | **Repudiation (Phủ nhận hành vi)** | Người dùng điều khiển xe từ xa (mở máy, chạy xe), nhưng sau đó **phủ nhận rằng mình đã làm điều đó**, nếu hệ thống **không có log xác thực** (như timestamp, IP, token xác minh). |
| **I** | **Information Disclosure (Rò rỉ thông tin)** | Ứng dụng bị lỗi hoặc cấu hình sai khiến thông tin như **vị trí xe, số điện thoại, biển số** bị lộ ra qua API hoặc URL. |
| **D** | **Denial of Service (Từ chối dịch vụ)** | Hacker gửi **hàng loạt request giả** tới server của app, làm tê liệt hệ thống, người dùng thật **không thể mở khóa xe hay định vị xe**. |
| **E** | **Elevation of Privilege (Leo thang đặc quyền)** | Một lỗi trong app cho phép người dùng bình thường **truy cập chức năng quản trị** như xóa log, xem xe của người khác. |
Các testcase chủ yếu:
| ID | Mục tiêu kiểm tra | Mô tả test case | Các bước thực hiện chi tiết | Kết quả dự kiến | Mức độ rủi ro | Ghi chú |
| ------------ | ------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ---------------- | ------------------------------------- |
| TC\_OTA\_001 | Kiểm tra xác thực gói cập nhật | Gửi gói firmware có chữ ký số hợp lệ | 1. Chuẩn bị gói firmware với chữ ký số hợp lệ<br>2. Thực hiện cập nhật | Firmware được chấp nhận và cập nhật thành công | Rất cao | Cốt lõi đảm bảo an toàn OTA |
| TC\_OTA\_002 | Kiểm tra từ chối gói firmware giả mạo | Gửi gói firmware bị chỉnh sửa hoặc không có chữ ký hợp lệ | 1. Chuẩn bị gói firmware bị thay đổi nội dung hoặc không có chữ ký<br>2. Thực hiện cập nhật | Hệ thống từ chối cập nhật, log lỗi, giữ nguyên firmware cũ | Rất cao | Ngăn chặn giả mạo hoặc tấn công |
| TC\_OTA\_003 | Kiểm tra replay attack | Gửi lại gói firmware cũ đã được cập nhật thành công trước đó | 1. Gửi lại gói firmware OTA đã dùng thành công trong quá khứ | Hệ thống phát hiện replay và từ chối cập nhật | Cao | Ngăn replay tấn công OTA |
| TC\_OTA\_004 | Kiểm tra tấn công từ chối dịch vụ (DoS) OTA | Gửi nhiều gói firmware sai hoặc tấn công flood trong thời gian ngắn | 1. Gửi nhiều yêu cầu cập nhật firmware không hợp lệ liên tục | Hệ thống giới hạn số lần cập nhật, ngắt kết nối hoặc cảnh báo | Trung bình - cao | Bảo vệ tài nguyên hệ thống |
| TC\_OTA\_005 | Kiểm tra bảo vệ channel truyền tải | Kiểm tra truyền tải OTA qua kênh mã hóa (TLS, VPN) | 1. Quan sát quá trình truyền OTA<br>2. Kiểm tra dữ liệu OTA truyền dưới dạng mã hóa | Dữ liệu OTA được mã hóa, không bị nghe lén hoặc sửa đổi | Rất cao | Giữ tính bảo mật dữ liệu OTA |
| TC\_OTA\_006 | Kiểm tra rollback attack | Gửi gói firmware cũ hơn để hạ cấp firmware | 1. Gửi gói firmware phiên bản cũ hơn hiện tại để cập nhật | Hệ thống phát hiện và từ chối cập nhật phiên bản firmware cũ | Cao | Ngăn rollback gây lỗi, mất bảo mật |
| TC\_OTA\_007 | Kiểm tra bảo vệ bootloader | Đảm bảo bootloader chỉ chấp nhận firmware đã ký số hợp lệ | 1. Thử chạy firmware không hợp lệ hoặc chưa được ký số từ bootloader | Bootloader từ chối khởi chạy firmware | Rất cao | Giữ hệ thống an toàn từ lúc khởi động |
| TC\_OTA\_008 | Kiểm tra logging và alerting | Kiểm tra hệ thống ghi log và cảnh báo các hành vi bất thường | 1. Thực hiện các hành vi tấn công giả mạo, replay, DoS<br>2. Kiểm tra log và cảnh báo | Các hành vi được ghi lại chi tiết và hệ thống phát cảnh báo | Trung bình | Hỗ trợ phát hiện và xử lý sự cố |
Authentication & Integrity: TC_OTA_001, TC_OTA_002, TC_OTA_007 tập trung kiểm tra chữ ký số, đảm bảo firmware không bị chỉnh sửa và bootloader xác thực trước khi chạy.
Replay protection: TC_OTA_003 đảm bảo kẻ tấn công không thể dùng lại gói firmware cũ.
DoS Protection: TC_OTA_004 giúp bảo vệ hệ thống không bị quá tải do tấn công từ chối dịch vụ.
Confidentiality: TC_OTA_005 bảo vệ dữ liệu truyền OTA không bị nghe lén.
Rollback protection: TC_OTA_006 ngăn chặn việc cập nhật firmware cũ gây lỗi.
Monitoring: TC_OTA_008 giúp đảm bảo giám sát và cảnh báo sự cố bảo mật.
### Mô tả chức năng:
“Đặt nhiệt độ điều hòa từ ứng dụng smartphone qua CAN”
Code:
```
#include <iostream>
#include <string>
class ClimateControl {
private:
int temperature;
public:
ClimateControl() : temperature(22) {}
void setTemperature(int temp) {
if (temp >= 16 && temp <= 30) {
temperature = temp;
std::cout << "[CAN] Set AC temperature to " << temperature << "°C\n";
} else {
std::cout << "[WARN] Temperature out of range: " << temp << "\n";
}
}
int getTemperature() {
return temperature;
}
};
int main() {
ClimateControl cc;
// Giả lập nhận dữ liệu từ ứng dụng di động
std::string input;
std::cout << "Enter temperature: ";
std::getline(std::cin, input);
int temp = std::stoi(input); // ⚠️ điểm cần lưu ý bảo mật
cc.setTemperature(temp);
}
```
### Thiết kế Test Case bảo mật (dạng bảng)
### Viết script test
### Report
### Tối ưu testcase
### Case khó và hiểm hơn
## Challange 8: Memory Seat Position)
### Tình huống chức năng:
Trong xe ô tô, người dùng có thể điều chỉnh vị trí ghế lái (ngả lưng, khoảng cách, chiều cao...) từ ứng dụng di động.
Dữ liệu vị trí được gửi xuống ECU qua giao tiếp nội bộ (giả lập).
C++ xử lý API đầu vào rồi ghi xuống bộ nhớ hệ thống.
Code:
```
#include <iostream>
#include <string>
#include <sstream>
class SeatControl {
private:
int distance;
int height;
int angle;
public:
bool updateSeatPosition(const std::string& input) {
std::istringstream iss(input);
int d, h, a;
char sep;
if (!(iss >> d >> sep >> h >> sep >> a) || sep != ',') {
std::cout << "[ERROR] Invalid input format.\n";
return false;
}
if (d < 0 || d > 100 || h < 0 || h > 50 || a < 0 || a > 90) {
std::cout << "[WARN] Out of range value.\n";
return false;
}
distance = d;
height = h;
angle = a;
std::cout << "[INFO] Seat position updated: "
<< "D=" << distance << ", H=" << height << ", A=" << angle << "\n";
return true;
}
};
int main() {
SeatControl control;
std::string user_input;
std::cout << "Enter seat position (D,H,A): ";
std::getline(std::cin, user_input);
control.updateSeatPosition(user_input);
}
```
### Thiết kế Test Case bảo mật (dạng bảng)

### Viết script test
```
#include <iostream>
#include <vector>
#include <string>
class PayloadInjector {
private:
std::vector<std::string> sqlPayloads = {
"' OR '1'='1",
"'; DROP TABLE users; --",
"' UNION SELECT * FROM users --",
"' OR 1=1--",
"\" OR \"\"=\"",
"'; EXEC xp_cmdshell('dir'); --"
};
std::vector<std::string> cmdPayloads = {
"&& ls",
"&& whoami",
"&& shutdown -h now",
"| cat /etc/passwd",
"; rm -rf /",
"`reboot`"
};
std::vector<std::string> targets = {
"50,25,45", // vali input
};
public:
void run() {
std::cout << "== SQL Injection Payloads ==\n";
for (const auto& input : targets) {
for (const auto& payload : sqlPayloads) {
inject(input, payload);
}
}
std::cout << "\n== Command Injection Payloads ==\n";
for (const auto& input : targets) {
for (const auto& payload : cmdPayloads) {
inject(input, payload);
}
}
}
void inject(const std::string& baseInput, const std::string& payload) {
std::string d = payload + ",25,45";
std::string h = "50," + payload + ",45";
std::string a = "50,25," + payload;
std::cout << "[Test D] " << d << "\n";
std::cout << "[Test H] " << h << "\n";
std::cout << "[Test A] " << a << "\n";
std::cout << "------------------------------\n";
}
};
int main() {
PayloadInjector injector;
injector.run();
return 0;
}
```
### Report
**Title:** SQL injection
**Severity:** High
**Component:** updateSeatPosition
**Steps to Reproduce:**
1. Create SQLi payload, simple CMD injection and insert after inputs
2. Try alternating between 3 positions.
3. Check status code and viewlog
4. Input is not sanitized and uses string concatenation
**Expected Result:**
- Still saved to db with clean data and not considered as SQL query
**Actual Result:**
- Payload executes with SQLi, payload skips just enter input first cell
- Payload execution with CMD injection, shell execution
**Impact:**
- Change sqli payload and possibly delete database
- Leaking customer information
- RCE system via CMD injection vulnerability
**Suggested Fix:**
- Clean input data, use prepared statement
- Do not use system commands to execute saving data to file
### Tối ưu testcase
| STT | Nhận xét |
| ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ✅ TC1 | Tư duy DoS rõ ràng: **gửi nhiều lệnh liên tục** → chiếm tài nguyên CAN/ECU. Có thể bổ sung `sleep(0.1)` để tạo nhịp spam hợp lý. |
| ✅ TC2 | Dùng **CodeQL để tìm hardcoded** là cách làm rất chuyên nghiệp. " quét thử default key/API endpoint hardcoded"` |
| ✅ TC3 | Dù trong C++ không có SQL nặng, nhưng với CMD injection thì thực tế. |
| ✅ TC4 | **Buffer overflow bằng chuỗi cực dài** → dù là std::string, nhưng đây là tư duy đúng của kiểm thử memory safety. |
| ✅ TC5 | Test input đặc biệt: tab, newline, empty string → kiểm thử robust và sát thực tế. |
| ✅ TC6 | **Broken Auth khi gọi API điều khiển ghế** từ app giả → mô phỏng đúng attack vector thực tế từ mobile app |
| ✅ TC7 | Test phân tách sai ký tự (tưởng `-` là phân tách) → rất sâu, liên quan **parser logic** + **memory handling** |
## Testcase cho PWN automotive firmware
| TestCase ID | Vulnerability Type | Mô tả | Payload đầu vào | Kết quả mong đợi |
| ------------ | ------------------- | --------------------------------- | ---------------------------------------- | ----------------------------------------- |
| PWN\_TC\_001 | Buffer Overflow | Tràn stack cơ bản | `A * 80` | Dẫn đến crash, kiểm tra lỗi segmentation |
| PWN\_TC\_002 | Stack Canary Bypass | Bypass stack canary (nếu tắt) | `A * 72 + ROP` | Ghi đè return address, shellcode thực thi |
| PWN\_TC\_003 | Format String Bug | Format string khi dùng `printf` | `%x%x%x%x%x` | In rò rỉ địa chỉ stack |
| PWN\_TC\_004 | Use After Free | Truy cập vùng nhớ sau khi free | Giả lập với object bị delete rồi gọi lại | Crash hoặc undefined behavior |
| PWN\_TC\_005 | Heap Overflow | Ghi đè con trỏ hàm ảo (vtable) | Ghi đè vtable với shellcode | Thực thi mã tùy ý |
| PWN\_TC\_006 | Integer Overflow | Tính toán kích thước không hợp lệ | Nhập length = -1 | Cấp phát nhỏ nhưng ghi vượt |
| PWN\_TC\_007 | Race Condition | Hai luồng ghi/đọc chung dữ liệu | Thực thi song song | Gây ra hành vi không xác định hoặc crash |
| PWN\_TC\_008 | TOCTOU | Time of check vs use | Sửa file sau khi kiểm tra quyền | Bypass quyền truy cập |
| PWN\_TC\_009 | Stack Pivot + ROP | Ghi đè esp và gọi chuỗi ROP | ROP chain trong input | Gọi system("/bin/sh") hoặc execve |
```
// vulnerable.cpp
#include <iostream>
#include <cstring>
using namespace std;
void vulnerableFunction(char *input) {
char buffer[64];
strcpy(buffer, input); // không kiểm tra độ dài => buffer overflow
cout << "Input was: " << buffer << endl;
}
int main(int argc, char *argv[]) {
if (argc < 2) {
cout << "Usage: " << argv[0] << " <input>" << endl;
return 1;
}
vulnerableFunction(argv[1]);
return 0;
}
```
### Tổng quan về PWN trong C++
Trong lĩnh vực bảo mật và exploitation (pwn), test case cho C++ thường tập trung vào:
Memory corruption: buffer overflow, heap overflow, use-after-free.
Dangling pointers: các lỗi truy cập vùng nhớ đã bị giải phóng.
Format string vulnerabilities
Integer overflow / underflow
Race conditions / TOCTOU
Dangling function pointers / vtable hijacking
Stack smashing / ROP chains (nếu có không bật canary)