Notification texts go here Contact Us Buy Now!

Phần 2: 80.000+ Tài Khoản – Từ Sinh Viên Đến Phó Hiệu Trưởng, Không Ai Được Bảo Vệ

BÙI MẠNH TUÂN
LOW
MEDIUM
HIGH
CRITICAL

CVSS 3.1: 9.8 (CRITICAL)

Lộ thông tin đăng nhập hàng loạt + chiếm quyền tài khoản qua API không xác thực.

Tóm tắt

Phần1 kết thúc với 896 thí sinh bị lộ dữ liệu cá nhân và ảnh chụp CCCD qua hệ thống Trung tâm Khảo thí của Trường Đại học X, toàn bộ được xây dựng trên nền tảng “Connections” của Công ty Y. Tôi khép lại báo cáo đó với một câu hỏi cứ lởn vởn trong đầu không chịu biến mất: nếu hệ thống thi cử không có bất kỳ kiểm soát truy cập nào, thì nền tảng chính của trường, chạy trên cùng một hạ tầng, sẽ ra sao?

Câu hỏi đó khiến tôi không yên. Và câu trả lời thì tệ hơn rất nhiều so với kịch bản xấu nhất mà tôi đã hình dung.

Trường Đại học X vận hành connections.universityx.vn như mạng nội bộ trung tâm của trường, cũng được xây dựng trên cùng nền tảng Connections SaaS của Công ty Y. Đây không phải cổng phụ hay hệ thống thí điểm nào đó, mà là nơi chứa mọi sinh viên, mọi cựu sinh viên, mọi cán bộ, mọi giảng viên, toàn bộ dân số kỹ thuật số của trường đại học tập trung tại một chỗ. Sử dụng cùng các kỹ thuật từ Phần 1 (gọi API không xác thực và liệt kê ID tuần tự), tôi đã trích xuất 80.053 tài khoản người dùng, mỗi tài khoản chứa tới 40 trường dữ liệu cá nhân.

Nhưng con số không phải thứ khiến tôi mất ngủ đêm đó. Mà là trường mật khẩu. API trả về thông tin đăng nhập cho cả tài khoản cán bộ lẫn sinh viên: một số ở dạng văn bản thuần (plaintext), số khác được che bằng một thuật toán đơn giản đến mức có thể dịch ngược bằng dữ liệu nằm ngay trong chính phản hồi API đó. Riêng với 554 tài khoản cán bộ có mật khẩu bị lộ, tôi thu được 208 bộ thông tin đăng nhập sử dụng được: 50 đọc trực tiếp ở dạng plaintext, 158 phục hồi offline, mà không cần thực hiện một lần đăng nhập nào.

Và để xác nhận rằng đây không phải rủi ro lý thuyết, tôi đã đăng nhập vào hai tài khoản: một Phó Hiệu trưởng và một sinh viên. Không bruteforce, không exploit, tôi chỉ đọc trường mật khẩu từ API rồi gõ vào form đăng nhập. Cả hai đều vào được ngay lần đầu.

1. Giới thiệu

1.1. Tóm tắt Phần 1

Nếu bạn chưa đọc Phần 1, đây là phiên bản ngắn gọn. Tôi đã điều tra tec.universityx.vn, hệ thống đăng ký thi của Trung tâm Khảo thí, và phát hiện:

  • 896 thí sinh bị lộ dữ liệu cá nhân qua API không xác thực
  • Số CCCD và ảnh chụp thẻ căn cước ai cũng có thể truy cập
  • Nguyên nhân gốc: Nền tảng Connections của Công ty Y không có bất kỳ cơ chế xác thực phía server nào
Vấn đề nằm ở kiến trúc nền tảng, không phải một endpoint bị cấu hình sai. Mọi bảng, mọi trường, mọi tập tin tải lên đều có thể truy cập bởi bất kỳ ai biết (hoặc đoán được) ID đối tượng đúng.

1.2. Câu hỏi tự nhiên tiếp theo

Trung tâm Khảo thí chỉ là một triển khai nhỏ: vài trăm thí sinh mỗi đợt thi. Nhưng tôi biết sự hiện diện của Trường Đại học X trên nền tảng Connections không dừng lại ở đó.

Trường còn vận hành connections.universityx.vn, mạng nội bộ trung tâm, chứa tài khoản của mọi sinh viên, cán bộ, và giảng viên trên toàn trường. Cùng nhà cung cấp, cùng framework JavaScript, cùng các script từ cdn.companyy.com, cùng kiến trúc. Và nếu hệ thống thi cử đã để lộ dữ liệu của 896 người, thì mạng lưới chính của trường đại học, nơi chứa toàn bộ dân số của trường, sẽ phơi bày những gì?

Tôi không thể không đi tiếp.

1.3. Phạm vi và Đạo đức

Các nguyên tắc đạo đức từ Phần 1 được áp dụng xuyên suốt:

  • Mọi truy cập dữ liệu đều sử dụng các endpoint công khai, không xác thực.
  • Không có xác thực nào bị vượt qua, vì không có xác thực nào tồn tại để vượt qua.
  • Không có dữ liệu nào bị sửa đổi, xóa, hoặc chia sẻ cho bên thứ ba.
  • Không thực hiện tấn công brute-force. Việc phục hồi mật khẩu được thực hiện offline bằng dữ liệu đã bị lộ từ chính API đó.
  • Chiếm quyền tài khoản chỉ thực hiện một lần duy nhất, nhằm xác nhận mức độ nghiêm trọng của lỗ hổng, và phiên đăng nhập được kết thúc ngay lập tức.

2. Mục tiêu lớn hơn: Mạng lưới Đại học

2.1. Khám phá nền tảng

Tôi mở connections.universityx.vn trong trình duyệt, bật mã nguồn lên, và cảm giác đầu tiên là déjà vu. Cùng framework JavaScript quen thuộc, tải từ cùng CDN:
<script src="https://cdn.companyy.com/js/include.core.isj"></script>
Các hàm API nội bộ y hệt vẫn có sẵn: CAN.db() để truy vấn cơ sở dữ liệu, config() để đọc phản hồi đã cache, và xửLý() để thực hiện tìm kiếm. Điểm khác biệt duy nhất là dữ liệu: thay vì thí sinh dự thi, nền tảng này quản lý toàn bộ người dùng của trường đại học.

Tôi đã biết kiến trúc này không có ổ khóa trên cửa. Giờ câu hỏi duy nhất là: có bao nhiêu thứ đằng sau cánh cửa đó?

2.2. Lập bản đồ không gian tài khoản

Tôi bắt đầu duyệt qua các ID tài khoản tuần tự qua CAN.db(), cùng kỹ thuật liệt kê như Phần . Ước tính ban đầu cho dải hoạt động là 7.787-97.744, khoảng 89.958 ID tiềm năng, con số đã đủ lớn rồi. Nhưng khi quá trình thu thập chạy, các tài khoản cứ liên tục xuất hiện vượt xa giới hạn đó, và tôi bắt đầu nhận ra quy mô thực sự lớn hơn nhiều so với tôi nghĩ:

Thông số Giá trị
ID hoạt động thấp nhất 7.787
ID hoạt động cao nhất 215.212
Tổng dải ID 207.426
Tài khoản có dữ liệu 80.053

Hơn 200.000 ID tiềm năng được dò quét, và 80.053 trong số đó trả về bản ghi người dùng đầy đủ, từng cái một, đều truy cập được mà không cần xác thực. Lúc con số vượt qua 50.000 rồi cứ tiếp tục tăng, tôi mới thực sự cảm nhận được sự khác biệt. 896 ở Phần 1 là một góc khuất nhỏ của trường đại học. 80.053 là toàn bộ trường đại học.

3. Thu thập dữ liệu: 80.053 tài khoản

3.1. Phương pháp trích xuất

Kỹ thuật hoàn toàn giống Phần 1. Với mỗi ID tài khoản trong dải, một lệnh gọi API duy nhất trả về toàn bộ bản ghi:
CAN.db("taiKhoan.{id}", function() {
    var d = config("taiKhoan.{id}");
    // d giờ chứa tất cả các trường của tài khoản này
});
Không có token, không cookie, không header xác thực, không gì cả. Nền tảng tự động tạo một phiên ẩn danh (tôi nhận được session ID kID=186xxxxx) và phục vụ dữ liệu như thể tôi là người dùng hợp lệ. Giống hệt Phần 1: cơ sở dữ liệu đơn giản trả lời bất kỳ ai hỏi, không cần biết người hỏi là ai.

3.2. Hai hướng phơi bày

80.053 tài khoản không phải một tập dữ liệu đồng nhất mà chia thành hai câu chuyện phơi bày rất khác nhau, mỗi câu chuyện mang mức độ nghiêm trọng riêng:

Loại tài khoản Số lượng Loại tài khoản (loại_tk)
Sinh viên đang học 21.393 Loại 0
Cựu sinh viên 57.588 Chủ yếu loại 0
Cán bộ & Giảng viên 562 Chủ yếu loại 2, với 6 loại 1 (admin)
Doanh nghiệp / Đối tác 166 Loại 3
Khách 344 Loại 3
Tổng 80.053

Câu chuyện thứ nhất là về 78.981 sinh viên và cựu sinh viên: khối lượng dữ liệu cá nhân bị phơi bày lớn đến mức nào. Câu chuyện thứ hai là về 562 cán bộ và giảng viên, một nhóm nhỏ hơn nhiều, nhưng với dữ liệu đăng nhập bị phơi bày chi tiết hơn. Mật khẩu bị lộ ở cả hai nhóm, nhưng tài khoản cán bộ là nơi tôi tập trung phân tích vì mức độ đặc quyền và tác động của chúng.

4. Hướng 1: Lộ dữ liệu Sinh viên và Cựu sinh viên – 78.981 tài khoản

4.1. Quy mô

Đại đa số tài khoản bị lộ, 21.393 sinh viên đang học và 57.588 cựu sinh viên, thuộc về những người đã theo học tại Trường Đại học X trong gần hai thập kỷ qua. Đây là các tài khoản chuẩn (loại 0), mỗi tài khoản chứa tới 40 trường dữ liệu cá nhân.

Hình 1: Bản ghi tài khoản sinh viên mẫu được trả về bởi API không xác thực, hiển thị các trường dữ liệu cá nhân bao gồm họ tên, ngày sinh, mã sinh viên, và thông tin liên hệ.

4.2. Những gì bị lộ cho mỗi sinh viên

Mỗi bản ghi sinh viên là một hồ sơ cá nhân hoàn chỉnh. Bảng dưới đây cho thấy mức độ đầy đủ của dữ liệu:

Trường Có dữ liệu Tỷ lệ
Họ tên (ho_ten) 80.037 100,0%
Mã sinh viên (ma_sinh_vien) 79.448 99,2%
Ngày sinh (ngay_sinh) 78.637 98,2%
Giới tính (gioi_tinh) 70.028 87,5%
Quê quán (que_quan) 50.042 62,5%
Khoa (khoa) 41.340 51,6%
Ngành (nganh) 41.226 51,5%
Khóa học (khoa_hoc) 39.768 49,7%
Chức vụ (chuc_vu) 36.390 45,5%
Email (email) 29.640 37,0%
Số điện thoại (sdt) 23.970 29,9%
Dân tộc (dan_toc) 7.845 9,8%
Ảnh đại diện (avatar_id) 6.586 8,2%
Số CCCD (cmnd_cccd) 2.750 3,4%
Tên mẹ 344 0,4%
Tên bố 333 0,4%

80.037 họ tên đầy đủ, 78.637 ngày sinh, 23.970 số điện thoại, 2.750 số căn cước công dân, và thậm chí 333 tài khoản lộ cả tên bố mẹ. Đây không phải danh sách tên đăng nhập hay bảng dữ liệu khô khan nào đó, mà là hồ sơ cá nhân hoàn chỉnh của gần như toàn bộ dân số trường đại học, từ sinh viên năm nhất đến cựu sinh viên gần hai thập kỷ trước, tất cả nằm trơ ra cho ai muốn xem thì xem.

4.3. Bức chân dung của sinh viên toàn trường

Dữ liệu vẽ nên một bức tranh chi tiết đến đáng lo ngại về Trường Đại học X. Tỷ lệ nữ-nam 4:1 (54.815 nữ, 13.522 nam) phản ánh định hướng chuyên ngành ngoại ngữ của trường. Dữ liệu khóa tuyển sinh trải dài từ K2008 đến K2025, gần hai thập kỷ sinh viên, tất cả nằm trong một cơ sở dữ liệu mở toang.

Trong 29.640 địa chỉ email, 20.793 là tài khoản Gmail cá nhân, trong khi 5.329 sử dụng tên miền Microsoft 365 của trường. 68 tài khoản có email gmai.com và 48 có gmail.con, những lỗi đánh máy xác nhận đây là dữ liệu thực do con người nhập, không phải dữ liệu test.

50.042 tài khoản có quê quán, tập trung nhiều ở miền Bắc Việt Nam, riêng Hà Nội chiếm 35,5%. Các khoa đông nhất là Quản trị Kinh doanh & Du lịch (5.579), tiếng Anh (5.510), và tiếng Trung (4.422), trải rộng trên 42 tên khoa và 56 chương trình đào tạo.

Bảng thống kê chi tiết đầy đủ (khoa, ngành, phân bố địa lý, nhân khẩu học) có trong Phụ lục.

4.4. Tại sao điều này quan trọng

Việc lộ dữ liệu sinh viên đáng lo ở cả quy mô lẫn chiều sâu. Bất kỳ ai có trình duyệt đều có thể xây dựng hồ sơ về gần 80.000 người: tên, ngày sinh, số điện thoại, quê quán, ngành học, và năm nhập học. Với 2.750 người, số căn cước công dân cũng bị lộ, một thứ không bao giờ có thể thay đổi được.

Và không chỉ dữ liệu cá nhân, mật khẩu của sinh viên cũng bị lộ qua API. Nhưng phân tích chi tiết về thông tin đăng nhập, tôi tập trung vào nhóm thứ hai, nơi mức độ đặc quyền khiến hậu quả nghiêm trọng hơn nhiều.

5. Hướng 2: Lộ dữ liệu Cán bộ và Giảng viên – 562 tài khoản (kèm mật khẩu)

5.1. Nhóm nhỏ hơn, vấn đề lớn hơn

Tài khoản cán bộ và giảng viên chỉ chiếm một phần nhỏ: 562 trên 80.053. Mật khẩu bị lộ ở cả tài khoản sinh viên lẫn cán bộ, nhưng tài khoản cán bộ đặc biệt nguy hiểm vì bốn trường dữ liệu đăng nhập rõ ràng: username, password, password_unmasked, và password_type, kết hợp với quyền quản trị mà các tài khoản này nắm giữ.

API đang trả về thông tin đăng nhập thật, không chỉ dữ liệu cá nhân, mà là credential thực sự của cán bộ trường đại học.

5.2. Trường mật khẩu

Trong lúc ánh xạ các trường được trả về cho tài khoản cán bộ, tôi nhìn thấy trường và phải dừng lại một lúc.

Trường này có dữ liệu ở cả tài khoản sinh viên lẫn cán bộ, nhưng với tài khoản cán bộ và quản trị, nó chứa thứ trông rõ ràng là thông tin đăng nhập có đặc quyền cao. Tôi ngồi nhìn chằm chằm vào màn hình, đọc đi đọc lại mấy lần vì không tin vào mắt mình. Nền tảng này, cái nền tảng mà hàng chục nghìn người đang dùng, đang trả về mật khẩu trong phản hồi API cho bất kỳ ai hỏi.

Tôi kiểm tra kỹ hơn, và dữ liệu đăng nhập bị lộ cho 561 tài khoản, chia thành ba loại:









إرسال تعليق

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.