---
# System prepended metadata

title: AI-SOC Final Project
tags: [log 分析]

---

# AI-SOC Final Project 
###### tags: `Security` `AI` `SOC` `監控` `log 分析` 
[TOC]



https://hackmd.io/@ncnu-opensource/book/%2FF40AXYr2QMOrUD8HO12zTg

---


## 系統功能
1. 即時 log 收集與分析
2. LLM 輔助威脅評估
3. 自動化響應機制
5. 可視化監控界面
### Repo
- <a href='https://github.com/Anna0131/AI-SOC'>GitHub</a>
## 專案用到的工具介紹

在這次專案中，我們主要使用了 **Vector** 和 **Prometheus** 兩個工具來協助分析與監控系統資料。

**Vector 負責從各種來源收集和處理日誌與指標，並轉換成可用格式。
Prometheus 負責儲存、監控這些資料，提供查詢與告警，協助維護系統健康。**

### Vector
Vector 是一個高效能的**資料收集與處理工具**，專門用來處理大量的日誌（log）和指標（metrics）資料。它可以從不同來源收集資料，並進行處理、格式轉換後，將資料輸出到其他系統（例如監控系統或儲存系統）。

- 特色
    - 多來源輸入：可收集來自檔案、網路、Syslog 等的資料。
    - 即時處理：可快速處理大量資料。
    - 轉換與過濾：可對收集到的資料進行過濾、轉換格式（例如 JSON、文本）以符合後續系統需求。
    - 輸出多樣化：可將處理後的資料輸出到 Prometheus、Elasticsearch、Kafka 等系統。

- ref：https://ithelp.ithome.com.tw/articles/10332767
### Prometheus

#### 介紹

Prometheus 是一個開源的監控和告警系統，用來收集和儲存時間序列資料（例如 CPU 使用率、記憶體用量、請求數量等），並且支援強大的查詢功能和可視化。

Prometheus 和其他時序資料庫相比有個**典型特性**：
**它是主動從各TARGET（client 端）上拉取（pull）數據，而非等待監控端的推送（push）。**


#### 特色
- 時間序列資料庫：專門設計來儲存隨時間變化的資料（metrics），例如系統性能、request number等。
- 靈活的查詢語言（PromQL）：提供查詢語言，可以查詢和分析資料。
- 自動發現：可自動找到要監控的目標（ex: Kubernetes 中的服務)
- 告警功能：可設定規則，當數據超過設定閾值時，會自動發出通知。
- 與 Grafana 整合：常與 Grafana 搭配使用，將資料視覺化展示。

ref
- https://ithelp.ithome.com.tw/articles/10299053
- https://hackmd.io/@cheese-owner/BkF8Kmlc5


### 3 Red Team Tools

- SQLMaps（滲透測試工具，可檢測 SQL injection 漏洞）
    - `git clone https://github.com/sqlmapproject/sqlmap.git`
    - `cd sqlmap`
    - `python3 sqlmap.py -u "http://163.22.17.116" --data="username=admin&password=secret" -p "username,password" --dbs`
    ![image](https://hackmd.io/_uploads/rklL5bXbgl.png)
    ![image](https://hackmd.io/_uploads/r1czSb4fgl.png)


- Dalfox（XSS 參數分析和掃描工具）
    - Mac OS：`brew install dalfox`
    - `dalfox url http://163.22.17.116`
    ![image](https://hackmd.io/_uploads/B1W8vbXbxl.png)
    ![image](https://hackmd.io/_uploads/HkOmSWEMge.png)


- Gobuster （try 字典檔，網站目錄爆破工具）
    - ` gobuster dir -u "http://163.22.17.116" -w /usr/share/wordlists/dirb/big.txt -b 301,401,403,404,500 -t 20`
    ![image](https://hackmd.io/_uploads/B1DGkWVGgl.png)
    ![image](https://hackmd.io/_uploads/H1slr-Nzgx.png)



## 流程圖
![image](https://hackmd.io/_uploads/HkyoF3Ezex.png)

### Step
1. 用三個工具（SQLMaps,dalfox,gobuster）送攻擊 request 去打特定主機A，獲得 web access log。
    -  查看攻擊的 log：`sudo vim /var/log/nginx/access.log`
        >  我們設定好的 Nginx 除了 GET 以外，還可以在 log 看到 POST 的 request body
2. 用 Vector 蒐集 raw log，再 Parse 這些 log
    > 用 [Regex](https://tw.alphacamp.co/blog/regex)（正規表達式）把字串中的欄位切分出來，ex:IP、status code

5. 用寫好的靜態分析規則（白名單＋黑名單）判斷 log 是否為攻擊，若為攻擊則把該 parse 過的 log 標記起來，放到 Prometheus。
7. 也會把一般的未標記的 raw log 放到 Prometheus，讓後端去拿資料並判斷行為模式
    > Prometheus 可用 Promql 查詢 metrics
9. **把靜態分析後判定為攻擊的log** 和 **後端分析 raw log 後判定行為模式異常的 log** ，都**給 LLM 判斷是否為為真正的攻擊行為（想避免 False positive）**。
    > False positive（假陽性）可以想像成實際未患病，但模型預測為患病。
    > 在某些應用領域也被稱為誤報（False Alarm）。
    > False positive 情況
![image](https://hackmd.io/_uploads/r1ENt3NGxx.png)


12. 於 Dashboard 顯示 LLM 的判斷結果

### 靜態分析
核心的邏輯是採用白名單（whitelist）+ 黑名單（blacklist）來過濾，因為：
- 在正常情境下，正常 request 數量遠大於惡意攻擊 request
- 過多 False Positive 會讓系統管理員忽略掉真正有用的異常資訊
- LLM（大語言模型）的任務無法完全平行執行，且計算資源有限，因此需要先做初步過濾以減少處理量

#### 過濾規則設計
- **白名單**
    - 設定安全的 IP 位址
    - 不同時間點對應不同安全範圍（可隨時更新）

- **黑名單**
    - HTTP status code 屬於 4xx（Client Error）或 5xx（Server Error）
    - 使用未授權的 Query String（例如不應存在於 URL 的參數）
    - 基於行為模式：
        - 在過去一段時間內，單一 IP 或 User-Agent 存取次數異常過多（例如暴力破解行為）
    - 可根據客戶環境動態調整策略，例如某些時間段封包量異常本為正常現象，需設置例外處理


#### 總結
- 靜態分析能提供初步過濾，將大量無關或重複的 log 節省下來，減輕後續 LLM 分析負擔
- 仍需結合動態分析（例如資源使用量、即時行為監控）才能完整反映系統現況
- 最終目標是結合 LLM 判斷與專業判讀，建立兼顧效率與準確性的入侵偵測系統（IDS）

:::info
### 常見 Detection 說明

當我們進行 **靜態分析** (例如查看系統或網路的 log 記錄) 時，可以藉由分析 HTTP 請求內容來判斷是否有 **SQL Injection** 攻擊的跡象。

具體來說，若在 log 中看到以下關鍵字或特殊符號，這可能代表 SQL Injection 攻擊：
- 關鍵字：`OR`, `AND`, `FROM`, `OR 1=1`, `SELECT`
- 特殊符號：`:`、`()`、`'` (單引號)、`-` (減號)

> 舉例來說，如果在 HTTP request 中觀察到：`GET /index.php?id=1 OR 1=1`，這裡的 `OR 1=1` 明顯是一種試圖繞過條件限制的 SQL Injection 攻擊特徵。
> 
這些關鍵字與符號常用於構造惡意 SQL 查詢，試圖繞過資料庫驗證或執行未授權的查詢。

串）

### 總結
- **靜態分析** 能幫助我們從 HTTP log 中，透過已知的特徵模式（例如特定關鍵字和符號），快速判斷是否可能存在 SQL Injection 攻擊。
- 但需要注意，靜態分析只能針對已知特徵進行偵測，對於變異型態或隱藏得很深的攻擊（例如混淆、編碼過後的 payload），可能會漏判。


ref：https://medium.com/@u.emmanuel53/detecting-web-attacks-in-server-logs-as-a-soc-analyst-945e36dac01e
:::
### 工具說明
1. **Vector**
在我們的專案中，我們用 Vector 來收集 server 的 web access log，並對這些 log 進行即時轉換與處理(ex:parsing)，使它們符合 Prometheus 的格式。也會提供 API 讓 Prometheus 查詢指標資料（metrics），讓後續的監控系統能正確理解和呈現資料。


2. **Prometheus**
將 Vector 收集和處理後的指標資料（metrics）輸出到 Prometheus，由它負責**儲存和監控這些指標**。
當系統中發生異常（例如：request 異常增加），Prometheus 可以及時發出警告，讓我們及早應對，保護系統的穩定性與安全。
    > 目前專案用到的指標有：`nginx_nginx_requests_total` 和 `nginx_nginx_requests_total_no_filter`

3. **Backend Server**
   - Express.js 框架
   - RESTful API 設計


4. **LLM 分析**
   - 基於 OpenAI API 做 log 分析
   - 威脅評估

5. **資料庫**
   - MySQL 儲存
   - 歷史數據查詢


### 後端技術（backend/server.js）
1. **Node.js & Express.js**
   ```javascript
   import express from 'express';
   import cors from 'cors';
   const app = express();
   ```


2. **資料庫操作**
   ```javascript
   const pool = mysql.createPool({
       host: '198.19.249.55',
       user: 'aiioc',
       password: 'aiioc',
       database: 'aiioc',
       waitForConnections: true,
       connectionLimit: 10,
       queueLimit: 0
   });
   ```


3. **LLM 整合**
   ```javascript
   const openai = new OpenAI({
       baseURL: "https://openrouter.ai/api/v1",
       apiKey: "YOUR_API_KEY"
   });
   ```

3. 行為模式分析：request 限流功能 
    ```javascript
    async function checkRequestFrequency(ip) {
        const query = `sum(sum_over_time(nginx_nginx_requests_total_no_filter{ip="${ip}"}[40s]))`;
        const response = await fetchWithTimeout(`${PROMETHEUS_URL}/api/v1/query?query=${encodeURIComponent(query)}`);
        const data = await response.json();
        // 分析請求頻率
    }
    ```

### 監控技術
1. **Vector.yml 配置**
   ```yaml
   sources:
     nginx_logs:
       type: "file"
       include: ["/var/log/nginx/access.log"]
   
   transforms:
     parse_nginx:
       type: "remap"
       inputs: ["nginx_logs"]
   
   sinks:
     prometheus:
       type: "prometheus"
       inputs: ["parse_nginx"]
   ```
   - log 作靜態分析
   - 數據轉換（parse）
   - 指標輸出
   - sink部分添加了 prometheus_exporter sink
    配置了兩種指標：
    http_response_time_seconds：HTTP 響應時間的分布
    http_requests_total：HTTP 請求總數，按方法、狀態碼和端點分類

2. **Prometheus.yml 查詢**
   ```javascript
   const query = `sum(sum_over_time(nginx_nginx_requests_total_no_filter{ip="${ip}"}[40s]))`;
   ```
   - PromQL Query 查詢
   - 可依設定好的時間定期抓取 Vector 的指標。
    ```yaml=
    global:
      scrape_interval: 15s
      evaluation_interval: 15s

    scrape_configs:
      - job_name: 'vector'
        static_configs:
          - targets: ['vector:9090']
    ```    
### 儲存持久性資料技術
#### docker-compose.yml

1. Vector 添加 9090 對映
- Vector 是用來收集和轉換日誌（log）的工具。
- 我們在 Vector 容器裡開放 9090 這個 port，因為這是 Vector 的 Prometheus exporter（將內部指標數據輸出給 Prometheus 抓取）所使用的 port。這樣 Prometheus 就能從這個 port 上來收集 Vector 提供的指標數據。

2. Prometheus 服務（用 9091 port）
- Prometheus 是一個監控系統和時序數據庫，會定期從 Vector 收集指標數據。

3. 設置 volumes 持久化 Prometheus 數據
- Prometheus 收集到的數據需要長期儲存，不能只存在記憶體中。
- 我們透過 docker-compose 中的 volumes 把 Prometheus 的數據儲存在主機上，這樣就算容器重啟，數據也不會消失。
    ```yaml=
    version: "3.8"
    services:
      vector:
        image: timberio/vector:0.46.1-debian
        container_name: vector
        restart: always
        volumes:
          - ./vector.yaml:/etc/vector/vector.yaml:ro
          - /var/log/nginx:/var/log/nginx:ro
        ports:
          - "8686:8686"
          - "9090:9090"
        command: ["vector", "--config", "/etc/vector/vector.yaml"]

      prometheus:
        image: prom/prometheus:latest
        container_name: prometheus
        restart: always
        volumes:
          - ./prometheus.yml:/etc/prometheus/prometheus.yml
          - prometheus_data:/prometheus
        ports:
          - "9091:9090"
        command:
          - '--config.file=/etc/prometheus/prometheus.yml'
          - '--storage.tsdb.path=/prometheus'
          - '--web.console.libraries=/usr/share/prometheus/console_libraries'
          - '--web.console.templates=/usr/share/prometheus/consoles'

    volumes:
      prometheus_data: {}
    ```


## 詳細流程

### 1. Log 收集流程
1. Nginx 產生 log
2. Vector 監控 log 文件變化
3. 解析 log 內容為結構化數據
4. 轉換為 Prometheus 指標
5. 推送到 Prometheus service

### 2. 分析流程
1. 定期檢查請求頻率
   ```javascript
   setInterval(async () => {
       console.log('Checking request frequencies...');
       const activeIPs = await getActiveIPs();
       // 檢查每個 IP 的請求頻率
   }, 20000);
   ```

2. AI 分析可疑行為
   ```javascript
   const analysis = await sendToOpenAI(requestData);
   ```

3. 結果儲存＆通知
   ```javascript
   await saveAnalysisResult(analysisResult, request.logEntry);
   ```


### 部署
#### 要求
- Node.js >= 14
- MySQL >= 8.0
- Vector 配置
- Prometheus 設置
- 告警規則定義


:::success
### Nginx 記錄 POST Request Body 設定教學
在這個專案中，我們需要收集包含 HTTP POST request body 的 log，以便後續透過 Vector 收集與分析資料。以下是步驟與設定。

1. 編輯 /etc/nginx/nginx.conf，新增 postdata 格式來記錄請求的資料，包含 request body。(新增自定義的 log_format)
- `vi /etc/nginx/nginx.conf`
    > log collector（Vector） 要把 log 的欄位切分出來
    ```=
    log_format postdata '$remote_addr - $remote_user [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" "$gzip_ratio" '
                           '"$request_body"';
    ```
    - $request_body：用來記錄 HTTP POST 請求的 body 資料。
    - $gzip_ratio：表示 gzip 壓縮比（可選，可刪掉）。
    - 其他欄位（IP、時間、user agent 等）也是常見 log 內容。

2. 在對應的 site 設定檔加入 location 並啟用 request body 記錄
- 編輯 /etc/nginx/sites-available/default 或你的 site 設定檔，加入以下內容：
    ```=
    location /log {
        log_format postdata $request_body;
        access_log /mnt/logs/nginx/my_tracking.access.log postdata;
        echo_read_request_body;  # 需要 echo 模組，確認 Nginx 已安裝 nginx-full 或加載 echo 模組
    }
    ```
    - access_log：指定 log 檔案路徑與格式。
    - echo_read_request_body：這是第三方 echo 模組功能，用來讀取 request body。安裝完整 nginx (nginx-full) 後會支援。

3. 安裝完整的 Nginx 支援（如果缺少 module）    
- `apt-get install nginx-full`
    > nginx-full 版本包含更多模組（例如 echo module），這樣才能讓 $request_body 在 log 裡記錄下來。

4. 搭配 Vector (log collector) 切分欄位
在 Vector 中，我們會設定 remap 或 parse_grok，對 log line 進行切分，把 $request_body 對應成獨立欄位，方便後續查詢和分析。


5. 為什麼要記錄 POST Request Body？
- 靜態 log 分析：光看 URL 和 headers 不夠，POST request body 可能藏有惡意 payload（例如 SQL Injection, XSS）。
- 攻擊取證：當系統發生異常，我們能從 log 中還原完整請求內容（包含 body），提高鑑識與取證能力。
- 搭配 LLM 分析：讓後端 AI 模型可以讀取更完整的資料，做更準確的判斷。

ref：https://stackoverflow.com/a/14034744/21023840

:::
#### 配置步驟
1. 把專案 clone 下來：`git clone https://github.com/Anna0131/AI-SOC.git`
2. 安裝需要的套件：`npm intstall`
4. 初始化資料庫（建 DB 、建使用者帳號並給權限）
    > 記得 **sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf**， 把bind-address 改成0.0.0.0，資料庫才能給外面連

6. 啟動服務`npm start`
![image](https://hackmd.io/_uploads/ByAxcIrfge.png)






<!--
## 舊流程圖
![image](https://hackmd.io/_uploads/BJdvBIvWle.png)
-->


## Demo
可打一些 request 測試
`curl "http://163.22.17.116/admin?page=3"`

`curl "http://163.22.17.116/admin?pages=3"`

`for ((i=1; I<=30; i++)); do   curl "http://163.22.17.116/admin?page=3"; done`
![image](https://hackmd.io/_uploads/SyQbSWPzxl.png)
![image](https://hackmd.io/_uploads/BkCWHZwMxl.png)
![image](https://hackmd.io/_uploads/Bk3MH-vGex.png)
