前幾天我們已經讓 BehaviorGuard 能夠取得 Linux 系統上的 Process 資訊,並透過 PID、PPID 找出 Process 之間的父子關係。
Day 3 我們成功偵測到:
apache2
↓
bash
並產生:
[ALERT] Suspicious process chain detected
但做到這裡後,我發現一個問題:
真實的資安環境不可能只有「apache2 → bash」這一種可疑行為。
EDR 每天會收到大量 Endpoint Event,其中可能包含 Process、Command Line、Network、File、Authentication、Privilege、Persistence 等不同類型的行為。
所以如果未來每新增一條 Detection Rule,就直接把新的 if 判斷全部塞進 process_monitor.py,程式很快就會變得難以維護。
因此 Day 4 的目標,就是把「事件蒐集」與「偵測規則」分開,建立 BehaviorGuard 第一版 Detection Engine。
今天先理解一個很重要的資安觀念:
「Event」跟「Alert」是不一樣的。
例如 Linux 系統可能出現:
systemd → apache2
bash → python3
bash → curl
apache2 → bash
python3 → sleep
這些都可以視為 Process Event。
但不能每看到一個 Event 就發出 Alert。
否則一台電腦每天可能產生大量事件,SOC 分析人員根本無法處理。
比較合理的流程應該是:
Endpoint
↓
收集 Event
↓
Detection Engine
↓
套用 Detection Rules
↓
符合可疑行為
↓
Alert
也就是:
Event = 系統發生了什麼事情
Alert = 某個 Event 符合我們定義的偵測條件
這也是 SIEM、EDR 等資安系統中很重要的概念。
前幾天我們一直在研究 PID 與 PPID。
PID 可以知道「這是哪一個 Process」。
PPID 則可以知道「是誰啟動了這個 Process」。
因此我們可以慢慢建立 Process Tree。
例如:
apache2
↓
bash
↓
curl
如果只看單一 Process:
bash
其實完全不一定有問題。
Linux 使用者本來就會使用 bash。
curl 也一樣,系統管理員平常就可能使用 curl 存取網站或 API。
但是如果加入 Parent / Child 關係:
apache2 → bash
意義就不同了。
Apache 是 Web Server,正常工作主要是處理 Web Request。
如果 Web Server 突然建立 Shell,就值得進一步調查。
因此 Detection 不應該只問:
「bash 是不是惡意程式?」
而應該開始問:
「誰啟動 bash?」
「bash 又啟動了什麼?」
「Command Line 是什麼?」
「後續有沒有 Network Connection?」
這就是 Behavior Detection 很重要的概念:
不要只看單一程式,而是看「行為與上下文」。
目前 BehaviorGuard 的專案開始變成:
behaviorguard/
├── agent/
├── data/
├── detection/
│ ├── init.py
│ ├── engine.py
│ └── process_rules.py
├── logs/
├── response/
├── test_apache.py
└── test_chain.sh
其中:
agent/
負責收集 Endpoint 資訊。
detection/
負責判斷收集到的 Event 是否具有可疑行為。
logs/
未來負責保存 Event 與 Alert。
response/
未來負責 Automated Response。
這樣可以讓不同功能分開管理。
首先建立:
detection/process_rules.py
第一條規則:
BG-PROC-001
Web Server Spawned Shell
程式如下:
def detect_web_shell(event):
web_servers = ["apache2", "nginx", "httpd"]
shells = ["bash", "sh", "zsh"]
parent = event.get("parent", "").lower()
child = event.get("child", "").lower()
if parent in web_servers and child in shells:
return {
"rule_id": "BG-PROC-001",
"rule_name": "Web Server Spawned Shell",
"severity": "HIGH",
"description": "A web server process spawned a shell."
}
return None
這條 Rule 的概念是:
Parent 是 Web Server
AND
Child 是 Shell
兩個條件同時成立時:
BG-PROC-001 MATCH
例如:
apache2 → bash
就會符合這條 Detection Rule。
但如果是:
python3 → sleep
就不符合,因此回傳:
None
這裡也學到一件很重要的事情:
「符合規則」不代表「100% 被入侵」。
Detection Rule 的作用是找出「值得調查的行為」。
實際環境還需要加入更多 Context,例如 Command Line、使用者、Network Connection、File Activity 等資訊,才能提高判斷可信度並降低 False Positive。
如果未來有 50 條 Detection Rule,不可能每次都自己手動執行:
detect_rule_1(event)
detect_rule_2(event)
detect_rule_3(event)
...
因此建立:
detection/engine.py
目前程式:
detect_web_shell,
detect_shell_network_tool
)
PROCESS_RULES = [
detect_web_shell,
detect_shell_network_tool
]
def analyze_process_event(event):
alerts = []
for rule in PROCESS_RULES:
result = rule(event)
if result is not None:
alerts.append(result)
return alerts
Detection Engine 的工作很單純:
收到一個 Event
↓
把 Event 送給所有 Detection Rule
↓
看看哪些 Rule Match
↓
把 Match 的結果加入 Alerts
所以未來我們只需要:analyze_process_event(event)
不需要自己決定應該執行哪一條 Rule。
今天也加入第二條 Process Detection Rule:
BG-PROC-002
Shell Spawned Network Tool
例如:
bash → curl
bash → wget
bash → nc
bash → ncat
程式概念
shells = ["bash", "sh", "zsh"]
network_tools = ["curl", "wget", "nc", "ncat"]
parent = event.get("parent", "").lower()
child = event.get("child", "").lower()
if parent in shells and child in network_tools:
return {
"rule_id": "BG-PROC-002",
"rule_name": "Shell Spawned Network Tool",
"severity": "MEDIUM",
"description": "A shell process launched a network-related tool."
}
return None
測試:
"parent": "bash",
"child": "curl",
"command": "curl http://example.com"
}
analyze_process_event(event)
Detection Engine 成功回傳:
BG-PROC-002
Shell Spawned Network Tool
Severity: MEDIUM
代表第二條規則也成功加入 Detection Engine。
這是今天另一個很重要的資安觀念:
False Positive(誤報)
例如:
bash → curl
可能是攻擊者下載惡意檔案。
但是也可能只是管理員正常執行:
curl https://example.com
所以如果只要看到 curl 就產生 Critical Alert,會造成大量 False Positive。
真實 Detection 通常需要更多 Context。
例如:
apache2
↓
bash
↓
curl
↓
下載檔案
↓
chmod +x
↓
執行檔案
↓
連線外部 IP
單獨看每個 Event,都不一定能直接證明是攻擊。
但如果短時間內連續出現多個異常行為:
Web Server Spawned Shell
+
Shell Spawned Network Tool
+
Downloaded File
+
File Execution
+
Outbound Connection
整體風險就會明顯提高。
這也是之後 BehaviorGuard 要做 Risk Scoring 與 Alert Correlation 的原因。
Day 1~Day 3 比較像:
「看到某個東西 → 判斷 → Alert」
Day 4 開始改成:
Endpoint Event
↓
Detection Engine
↓
┌──────────┴──────────┐
↓ ↓
BG-PROC-001 BG-PROC-002
Web Server → Shell Shell → Network Tool
↓ ↓
└──────────┬──────────┘
↓
Alerts
這個架構最大的好處是:
未來增加 Detection Rule 時,不需要重新設計整個 Monitor。
只需要:
今天除了 Python 程式以外,我主要理解了幾個 Detection Engineering 的概念:
Event ≠ Alert
Endpoint 上會產生大量 Event。
只有符合 Detection Rule 的事件,才需要進一步成為 Alert。
Process 本身不一定有問題
bash、curl、wget 都是正常 Linux 工具。
資安偵測不能只看「程式名稱」。
還需要看:
Parent Process
Child Process
Command Line
User
File Activity
Network Activity
以及前後事件之間的關係。
Process Tree 可以提供 Context
例如:
bash
單獨看沒有什麼問題。
但是:
apache2 → bash
就值得進一步調查。
如果再出現:
apache2 → bash → curl
風險又會提高。
因此「誰啟動誰」是 Endpoint Detection 很重要的資訊。
Detection Rule 不代表攻擊已經成立
Detection 的目的不是看到某個 Pattern 就直接說:
「這台電腦被駭了。」
而是:
「這個行為值得調查。」
這也是為什麼需要 Severity、Risk Score、Correlation 等機制。
False Positive 是 Detection 很大的問題
Rule 寫得太寬:
Alert 很多,但誤報也很多。
Rule 寫得太窄:
誤報降低,但可能漏掉真正的攻擊。
所以 Detection Engineering 並不是「規則越多越好」。
真正重要的是如何利用 Context,讓 Alert 更有意義。
Day 4 完成
今天 BehaviorGuard 已經從:
單一 if 判斷
正式開始轉變成:
可擴充的 Detection Engine
目前:
BG-PROC-001:Web Server → Shell
BG-PROC-002:Shell → Network Tool
下一步 Day 5,我準備開始做:
Command Line Detection
目前我們主要依靠 Parent / Child Process 關係。
Day 5 開始會進一步分析:
command
也就是:
「這個 Process 到底執行了什麼指令?」
讓 BehaviorGuard 從 Process Relationship Detection,繼續往更完整的 Endpoint Behavior Detection 前進。