iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
Modern Web

AI 驅動的 Web 資安新時代系列 第 19

Day19 - AI Agent 幫我排程弱點掃描與回報

  • 分享至 

  • xImage
  •  

為什麼要做自動弱點掃描?

在網站維護中,如果沒有持續檢查,往往漏洞被攻擊者發現的速度比防守方更快。

傳統做法是 人工定期測試,但這樣效率低,也容易遺漏。

利用 AI Agent,我們可以:

  • 自動產生攻擊 payload 測試 API
  • 即時分析伺服器回應
  • 每天定時執行,並輸出掃描報告

AI Agent 工作流程

  1. 排程觸發
    • 使用 node-cron 或系統 crontab,每天固定時間啟動掃描程式。
  2. 模擬攻擊
    • AI Agent 發送常見攻擊 payload:
      • SQL Injection (' OR 1=1 --)
      • XSS (<script>alert(1)</script>)
  3. AI 分析
    • 把伺服器回應丟給 Gemini,請模型判斷是否有漏洞。
  4. 報告生成
    • 結果存成 JSON 檔,並顯示在終端機。

server – 模擬不安全伺服器

1、建立伺服器與解析 JSON

  • express 建立 API 伺服器
  • body-parser 處理 POST JSON
import express from "express";
import bodyParser from "body-parser";
import sqlite3 from "sqlite3";

const app = express();
const port = 3000;

app.use(bodyParser.json());

2、初始化 SQLite 資料庫

使用 SQLite 記憶體資料庫,預先建立兩個測試用帳號

const db = new sqlite3.Database(":memory:");

db.serialize(() => {
  db.run("CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT, password TEXT)");
  db.run("INSERT INTO users (username, password) VALUES ('admin', 'admin123')");
  db.run("INSERT INTO users (username, password) VALUES ('test', 'test123')");
});

3、不安全登入 API(SQL Injection 模擬)

這裡故意使用字串拼接,方便測試 SQL Injection

app.post("/api/login", (req, res) => {
  const { username, password } = req.body;

  // 漏洞:直接拼接 SQL,容易被注入攻擊
  const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`;

  db.all(query, (err, rows) => {
    if (err) return res.status(500).send("伺服器錯誤: " + err.message);

    if (rows.length > 0) {
      res.send(`歡迎 ${rows[0].username}!登入成功。`);
    } else {
      res.status(401).send("登入失敗,帳號或密碼錯誤。");
    }
  });
});

4、不安全留言 API(XSS 模擬)

沒有做任何過濾,會讓 <script> 被直接執行

app.get("/api/comment", (req, res) => {
  const { msg } = req.query;
  res.send(`<h1>你的留言:</h1><p>${msg}</p>`); // 直接輸出用戶輸入
});

5、啟動伺服器

app.listen(port, () => {
  console.log(`伺服器啟動中 → http://localhost:${port}`);
});

AI Agent 弱點掃描

1、初始化 Gemini

  • 使用 .env 中的 GEMINI_API_KEY
  • 呼叫 Gemini 來分析 API 回應
const API_KEY = process.env.GEMINI_API_KEY;
const genAI = new GoogleGenerativeAI(API_KEY);
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });

2、取得目前檔案的目錄

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

3、模擬弱點測試目標

  • 第一筆模擬 SQL Injection
  • 第二筆模擬 XSS
const targets = [
   {
      url: "http://localhost:3000/api/login",
      payload: { username: "admin", password: "' OR 1=1 --" },
   },
   {
      url: "http://localhost:3000/api/login",
      payload: { username: "<script>alert(1)</script>", password: "123" },
   },
];

4、執行掃描並呼叫 Gemini

  • 每個目標 API 都會送出請求
  • 伺服器回應交給 Gemini 分析漏洞
export async function runScan() {
   let results = [];

   for (let t of targets) {
      const res = await fetch(t.url, {
         method: "POST",
         headers: { "Content-Type": "application/json" },
         body: JSON.stringify(t.payload),
      });

      const text = await res.text();

      // 丟給 Gemini 分析
      const ai = await model.generateContent({
         contents: [
         { role: "user", parts: [{ text: `分析以下回應是否有漏洞:\n\n${text}` }] },
         ],
      });

      results.push({
         target: t.url,
         payload: t.payload,
         status: res.status,
         analysis: ai.response.text(),
      });
   }

   // 確保 report 資料夾存在 (Day19/report)
   const reportDir = path.join(__dirname, "report");
   if (!fs.existsSync(reportDir)) {
      fs.mkdirSync(reportDir);
   }

   // 存成報告檔
   const file = path.join(reportDir, `report-${Date.now()}.json`);
   fs.writeFileSync(file, JSON.stringify(results, null, 2));
   return { file, results };
}

5、輸出報告

  • 確保 report/ 資料夾存在
  • 輸出 JSON 報告檔
runScan()
   .then((report) => {
      console.log("掃描完成,報告存檔:", report.file);
      console.log("掃描結果:");
      report.results.forEach((r, i) => {
         console.log(`第 ${i + 1} 筆`);
         console.log("Target:", r.target);
         console.log("Status:", r.status);
         console.log("Payload:", JSON.stringify(r.payload));
         console.log("Analysis:", r.analysis, "\n");
      });
   })
   .catch((err) => {
      console.error("掃描失敗:", err);
   });

6、執行掃描

runScan()
   .then((report) => {
      console.log("掃描完成,報告存檔:", report.file);
      console.log("掃描結果:");
      report.results.forEach((r, i) => {
         console.log(`第 ${i + 1} 筆`);
         console.log("Target:", r.target);
         console.log("Status:", r.status);
         console.log("Payload:", JSON.stringify(r.payload));
         console.log("Analysis:", r.analysis, "\n");
      });
   })
   .catch((err) => {
      console.error("掃描失敗:", err);
   });

自動排程執行

1、匯入套件

  • node-cron : 負責排程
  • 呼叫 agent.js 內的 runScan()
import cron from "node-cron";
import { runScan } from "./agent.js"

2、設定排程

0 3 * * * 代表每天 03:00 觸發,會自動產生報告。

console.log("排程器啟動中...");

// 每天凌晨 3 點自動掃描
cron.schedule("0 3 * * *", async () => {
  console.log("開始弱點掃描...");
  const report = await runScan();
  console.log("掃描完成,報告存檔:", report.file);
});

上一篇
Day18 - 藍隊 Agent:自動修補與防禦建議
下一篇
Day20 - Agent × RAG:即時查詢最新 CVE 與 Exploit POC
系列文
AI 驅動的 Web 資安新時代22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言