iT邦幫忙

0

Day26 BehaviorGuard:從 Detection 到 Auto Response,讓 Linux 真正執行自動防禦

  • 分享至 

  • xImage
  •  

在 Day25,我們成功將 Process Monitor、Network Monitor、Correlation Engine 和 Response Dispatcher 整合成一套 Unified Event Pipeline。

當 Linux 出現可疑行為時,BehaviorGuard 已經可以自動偵測、建立 Event ID、記錄 Alert,並根據風險等級產生 Response 決策。

不過,當時還有一個很重要的問題:

我們的系統雖然能夠偵測可疑行為,卻還不能由正式監控事件直接觸發真正的防禦動作。

例如偵測到 HIGH Alert 時,系統只會顯示:

Decision   : REVIEW_REQUIRED
Execution  : DRY RUN
Executed   : False

這代表系統認為事件值得處理,但實際上還沒有終止程序或阻斷連線。

因此,Day26 的目標是讓 BehaviorGuard 從 Detection(偵測)進一步走向 Auto Response(自動回應)。

今天主要完成:

  1. 建立 Auto Response Policy。
  2. 將 Policy 整合進 Response Dispatcher。
  3. 讓真正的 Process Alert 自動觸發受控 SIGTERM。
  4. 利用 nftables 實作 30 秒限時 IP 封鎖。
  5. 讓真正的 Network Alert 自動觸發限時阻斷。
  6. 驗證 Response 結果,並記錄 Audit Log。

本次所有實際處置都限制在 Kali Linux 的受控測試環境,沒有開放對任意程序或外部 IP 自動執行防禦。


一、什麼是 Auto Response?

在資安領域中,Detection 和 Response 是兩個不同的階段。

Detection 的工作是發現可疑行為。

例如:

Rule     : BG-NET-001
Name     : Suspicious Network Listener
Severity : HIGH
Process  : socat

這只能代表系統發現某個網路程序符合可疑行為規則。

但發現問題後,還要決定該如何處理。

這就是 Response 的工作。

常見的端點回應方式包括:

  • 終止可疑程序。
  • 隔離受感染主機。
  • 阻斷特定網路連線。
  • 停用帳號或限制權限。
  • 通知資安分析人員進一步調查。

如果 Response 需要分析人員手動執行,就屬於人工處置。

如果系統能在符合安全策略後自動執行,就屬於 Auto Response。

我們今天主要實作其中兩項:

SIGTERM:終止受控測試程序。

nftables:暫時阻斷指定測試 IP。

但 Auto Response 也有風險。

如果正常程序被誤判成惡意程序,系統又直接將它終止,可能造成正常服務中斷。

因此,真正的 Auto Response 不應該只是:

HIGH Alert
    ↓
直接終止程序

而應該是:

Detection Alert
       ↓
Response Policy
       ↓
檢查授權與目標
       ↓
ALLOW / DENY / DRY RUN
       ↓
執行符合條件的處置
       ↓
Response Verification
       ↓
Audit Log

這也是今天最重要的設計概念。


二、建立 Auto Response Policy

今天首先新增:

response/auto_policy.py

這個模組的工作不是直接執行防禦,而是決定某項處置是否被允許。

我們建立三種主要決策:

Decision 意義
ALLOW 通過目前這一層策略檢查
DENY 不符合授權或目標限制,拒絕處置
DRY_RUN 只模擬決策,不執行實際處置

其中 DRY_RUN 特別重要。

例如一筆真正的 HIGH Network Alert:

alert = {
    "rule": "BG-NET-001",
    "source": "NETWORK",
    "severity": "HIGH",
    "dst_ip": "8.8.8.8"
}

即使它的 Severity 是 HIGH,也不能代表 8.8.8.8 就是惡意 IP。

因此我們的 Policy 會判斷:

if source != "CONTROLLED_LAB":
    result["decision"] = "DRY_RUN"
    result["reason"] = (
        "Live detection requires additional approval"
    )
    return result

也就是說,一般真實監控事件不會只因為 Severity 很高就直接執行破壞性操作。

另外,我們將 Network Blocking 的實驗目標限制為:

TEST_IP = "127.0.0.2"

如果要求封鎖其他 IP,Policy 就會拒絕。

第一階段測試

執行:

PYTHONPATH=. python3 test_day26_policy.py

得到:

Test     : Real HIGH Process Alert
Decision : DRY_RUN
[PASS]

Test     : Real HIGH Network Alert
Decision : DRY_RUN
[PASS]

Test     : Unauthorized Lab Process
Decision : DENY
[PASS]

Test     : Authorized Lab Process
Decision : ALLOW
[PASS]

Test     : Authorized Lab Network
Decision : ALLOW
[PASS]

Test     : Unapproved IP
Decision : DENY
[PASS]

Total: 6/6 PASS

這次驗證了六種情況,包含正常監控告警、未授權處置、受控實驗及未核准 IP。

不過,要特別注意:

Policy 回傳 ALLOW,不代表可以直接終止任意 PID。

它只代表通過第一層策略,後面仍然需要確認程序身分、命令內容,以及它是否真的是預先註冊的測試程序。


三、將 Auto Response Policy 整合進 Dispatcher

接下來我們修改:

response/dispatcher.py

在原本的 Response Dispatcher 前面增加 Policy 檢查。

原本的 Dispatcher 可以根據 Severity 決定:

MEDIUM → INVESTIGATE
HIGH   → REVIEW_REQUIRED

今天則增加:

policy = evaluate_auto_response(
    alert,
    action,
    lab_authorized=False
)

這裡刻意將一般監控事件的 lab_authorized 設為 False。

這樣即使有人在 Alert 裡提供看似允許的資料,也不會單靠 Alert 內容就取得實際處置授權。

我們同時新增一筆 Policy Audit:

log_response(
    rule=rule,
    action="AUTO_POLICY",
    target=policy["target"],
    status=policy["decision"],
    reason=policy["reason"],
    event_id=alert.get("event_id"),
    source=source
)

這裡的 Event ID 是 Day25 加入的功能。

有了 Event ID,我們就能知道某筆 Policy 決策是由哪一筆 Detection Alert 觸發。

第二階段測試

實際輸出:

========== Day26 Auto Response Policy ==========

Rule       : BG-NET-001
Source     : NETWORK
Severity   : HIGH
Action     : BLOCK
Decision   : DRY_RUN
Reason     : Live detection requires additional approval
Executed   : False

原本的 Dispatcher 也正常:

Decision   : REVIEW_REQUIRED
Execution  : DRY RUN

最後成功記錄:

[AUDIT] RESPONSE_DECISION -> REVIEW_REQUIRED
[AUDIT] AUTO_POLICY -> DRY_RUN

這代表新的 Policy 沒有破壞 Day25 的 Response 功能。


四、真正的 Process Auto Response

完成 Policy 後,我們開始實作今天最重要的功能之一:

讓真正的 Process Monitor 偵測到 Alert 後,自動終止符合嚴格條件的測試程序。

之前 Day22~24 雖然已經測試過 SIGTERM,但主要是測試程式直接呼叫終止函式。

這次的不同之處,是必須從真正的 Detection Alert 開始。

我們選擇使用 Day5 建立的:

BG-CMD-002
Python Inline Code Execution

這條規則可以偵測類似:

python3 -c 'import time; time.sleep(30)'

的 Python Inline Execution。

不過,python3 -c 並不一定是惡意行為。

正常開發、系統管理及自動化測試都可能使用。

所以我們不會把所有 BG-CMD-002 Alert 都設定成自動終止。

1. 建立受控程序登記表

我們新增:

response/lab_process_registry.py

只有由測試程式使用 subprocess.Popen() 建立,且符合指定命令的程序,才可以註冊。

例如:

proc = subprocess.Popen([
    sys.executable,
    "-c",
    "import time; time.sleep(30)"
])

我們會記錄該程序的 PID 與建立時的身分資訊。

在真正終止前,再重新確認程序仍是原本註冊的目標。

這麼做是因為 Linux PID 可能被重複利用。

假設 PID 5000 的程序已經結束,Linux 未來可能將 PID 5000 分配給其他程序。

如果只檢查 PID,就可能終止錯誤對象。

因此我們還會檢查程序名稱、執行檔、命令及建立時間等資訊。

這降低了錯誤處置風險,但仍不是完整消除 PID 競爭條件的正式產品級方案。

2. 第一次測試失敗

第一次執行:

PYTHONPATH=. python3 -u test_day26_live_terminate.py

結果顯示:

[TEST] Registered process PID: 2849139
[PASS] Test process registered

Detection Engine 也成功觸發:

[ALERT] BG-CMD-002
Rule      : Python Inline Code Execution
Severity  : MEDIUM

但是最後出現:

RuntimeError:
Monitor did not terminate the test process

為什麼 Detection 成功,程序卻沒有終止?

3. 找到真正的原因

檢查後發現 process_monitor.py 仍然使用舊的 Response 流程。

所以雖然能觸發 Detection,也可以記錄 Response 決策,但沒有經過 Day26 新增的 Live Auto Response Hook。

我們將 Process Monitor 改為統一呼叫:

ingest_alert(
    normalized_alert,
    "PROCESS"
)

讓 Alert 進入 Unified Event Pipeline,再由 Pipeline 呼叫 Live Response。

4. 修正後成功執行 SIGTERM

重新測試後:

========== BehaviorGuard Pipeline ==========

Event ID : bd4aa6b8-bd33-4ce4-97f6-57bec739e9ab
Source   : PROCESS
Rule     : BG-CMD-002

接著一般 Policy 仍然顯示:

Decision   : DRY_RUN
Executed   : False

但系統另外確認這筆 Alert 的 PID 確實屬於事先註冊的測試程序,於是執行受控自動終止:

[AUDIT] AUTO_TERMINATE_LAB -> SUCCESS
[AUTO RESPONSE] Registered process: SUCCESS

最後測試成功:

[PASS] Real Monitor triggered termination
[PASS] Process exited
[PASS] Response Audit recorded

Event ID:
bd4aa6b8-bd33-4ce4-97f6-57bec739e9ab

這次最重要的成果,是完成真正的:

Linux Process
      ↓
Process Monitor
      ↓
BG-CMD-002
      ↓
Unified Pipeline
      ↓
受控程序身分驗證
      ↓
SIGTERM
      ↓
Response Audit

也就是讓真正的監控事件觸發實際程序終止,而不是只有人工呼叫測試函式。


五、使用 nftables 實作 Temporary IP Blocking

完成 Process Auto Response 後,我們開始進行 Network Auto Response。

在 Day24,我們已經使用 nftables 成功阻斷指定 IP。

當時使用的是一般 Drop Rule:

ip daddr 127.0.0.2 counter drop

但這樣有一個問題:

只要規則沒有被手動刪除,就可能持續存在。

如果 Response 程式異常停止,或沒有執行解除函式,可能導致封鎖狀態持續。

因此今天我們改用 nftables 的 Timeout Set。

1. nftables Set 是什麼?

Set 可以理解成 nftables 管理的一組資料。

例如我們建立:

blocked_ips

用來保存目前需要封鎖的 IP。

再讓防火牆規則比對這個 Set。

封包目的 IP
      ↓
是否存在 blocked_ips?
      ↓
YES → DROP
NO  → 不由此規則阻斷

我們還可以為 Set 元素指定 Timeout。

例如:

127.0.0.2 timeout 30s

表示這個 IP 的封鎖元素會在 30 秒後到期。

2. 建立限時封鎖規則

今天測試使用:

table ip bg_day26

其中包含:

table ip bg_day26 {
    set blocked_ips {
        type ipv4_addr
        flags timeout
        timeout 30s
    }

    chain output {
        type filter hook output priority 0; policy accept;
        ip daddr @blocked_ips counter drop
    }
}

幾個重要名詞:

名詞 說明
table nftables 規則的管理容器
chain 定義封包要經過的規則鏈
output 處理由本機送出的封包
set 儲存要比對的 IP 集合
timeout 指定元素有效期限
drop 丟棄符合條件的封包

這裡的 output 代表我們阻斷的是 Kali Linux 本機對指定目的 IP 發出的流量。

它不是將整台電腦從網路中隔離。

3. 驗證 30 秒自動解除

我們新增:

response/timed_network_blocker.py

並先進行獨立測試。

結果:

[PASS] Temporary firewall table created
[PASS] Temporary block installed

查看 nftables Set:

elements = {
    127.0.0.2 expires 29s988ms
}

這表示 nftables 正在倒數封鎖期限。

接著使用 Ping 測試:

[PASS] Ping blocked during active rule

等待封鎖到期後:

[PASS] Block element automatically expired
[PASS] Connectivity restored
[PASS] Test table removed

這次證明:

封鎖元素會由 Linux 核心管理到期,不需要依靠 Python 在指定時間手動刪除元素。

需要注意,到期的是 Set 裡面的 IP 元素,並不是整個 nftables Table。

所以我們也加入測試完成後的 Table 清理程序。


六、真正的 Network Auto Response 整合

完成限時封鎖後,我們接著將它整合進:

response/live_auto_response.py

這次使用 Day7 建立的規則:

BG-NET-001
Suspicious Network Listener

這條規則會偵測 nc、ncat、socat 等工具建立 TCP Listener 的行為。

為了避免誤判造成不必要的封鎖,我們新增:

response/lab_network_registry.py

只有符合預先登記的實驗程序,才能進入真正的封鎖流程。

本次使用:

socat TCP-LISTEN:19999,bind=127.0.0.1,reuseaddr -

也就是讓 socat 在本機:

127.0.0.1:19999

建立 TCP Listener。

為什麼不直接封鎖 Alert 的 Remote IP?

因為 BG-NET-001 偵測的是監聽 Socket。

一個正在 LISTEN 的 Socket,並不一定已經有遠端連線。

例如今天的事件:

State  : LISTEN
Remote : 0.0.0.0:*:0

這並不是可直接當作惡意來源的 IP。

因此,我們沒有從 Alert 中猜測封鎖目標,而是另外指定受控實驗 IP:

127.0.0.2

真正的 Network Alert 只負責觸發受控實驗流程,封鎖目標則由事先設定的 Policy 限制。

這是本次測試的重要安全設計。


七、最終實測:Network Alert 自動觸發 nftables

最後執行:

PYTHONPATH=. python3 -u test_day26_live_network.py

1. 註冊真正的 socat 程序

[PASS] Controlled socat registered
[TEST] PID: 2854656

Network Monitor 成功收集:

Process : socat
PID     : 2854656
State   : LISTEN
Local   : 127.0.0.1:19999

2. Detection Engine 成功產生 HIGH Alert

========== BehaviorGuard Network Alert ==========

Rule       : BG-NET-001
Name       : Suspicious Network Listener
Severity   : HIGH

Process    : socat
PID        : 2854656

這是真正的 Linux 網路行為,不是手動建立的假 Alert。

3. Alert 進入 Unified Pipeline

========== BehaviorGuard Pipeline ==========

Event ID : 96750ac5-292b-49e3-846c-3b8ba2bdf397
Source   : NETWORK
Rule     : BG-NET-001

[INFO] Alert saved to logs/alerts.jsonl

這代表 Network Detection 已經接進 Day25 建立的 Pipeline。

4. Response Policy 執行判斷

一般 Response Policy 顯示:

Decision   : DRY_RUN
Executed   : False

Dispatcher 則顯示:

Decision   : REVIEW_REQUIRED
Execution  : DRY RUN

但系統也會另外檢查:

  • Alert 是否為 BG-NET-001。
  • Process 是否為 socat。
  • Socket 是否處於 LISTEN。
  • 是否監聽預期的本機位址與 Port。
  • PID 是否屬於事先註冊的測試程序。
  • 程序身分是否仍然一致。

全部通過,才允許這個受控實驗進行真正的 IP Blocking。

5. 自動阻斷成功

最重要的輸出:

[AUDIT] AUTO_BLOCK_LAB -> SUCCESS
[AUTO NETWORK] Temporary block: SUCCESS

[PASS] Real Network Alert triggered BLOCK
[PASS] Response Audit linked

這代表真正的 Network Alert 已經自動觸發 nftables 封鎖。

而且封鎖成功後,系統也確認限時元素確實存在:

[PASS] nftables timed element active

6. 封鎖到期並恢復

等待 30 秒後:

[AUDIT] AUTO_UNBLOCK_LAB -> SUCCESS

[PASS] Timed block expired
[PASS] Connectivity restored
[PASS] Unblock Audit linked
[PASS] Test table cleaned

這代表系統不只會執行封鎖,也會驗證封鎖是否到期,以及網路連線是否恢復。

最後清除本次測試建立的 nftables Table,避免影響後續實驗。


八、為什麼 Response Audit 很重要?

今天的 Process 和 Network Response 都有一個共同設計:

每筆 Detection Event 都有 Event ID。

例如這次 Network Alert:

96750ac5-292b-49e3-846c-3b8ba2bdf397

這個 ID 可以對應到不同階段的處置紀錄。

Detection Alert
      ↓
Event ID
      ↓
AUTO_POLICY
      ↓
AUTO_BLOCK_LAB
      ↓
AUTO_UNBLOCK_LAB

本次實際紀錄包含:

[AUDIT] AUTO_POLICY -> DRY_RUN
[AUDIT] AUTO_BLOCK_LAB -> SUCCESS
[AUDIT] AUTO_UNBLOCK_LAB -> SUCCESS

其中 DRY_RUN 與 SUCCESS 並不矛盾。

DRY_RUN 表示一般正式監控事件沒有獲得任意執行防禦的權限。

SUCCESS 則代表額外的受控實驗檢查通過後,對事先限定的測試目標成功執行了處置。

透過這些紀錄,我們可以追蹤:

  1. 哪一筆 Detection Alert 觸發 Response。
  2. 系統原本決定採取什麼處置。
  3. 是否允許執行受控 Auto Response。
  4. 實際處置是否成功。
  5. 封鎖到期後是否恢復正常。

對 SOC 分析人員來說,Response 不應該只留下「成功」兩個字,而是應該能追溯處置原因與結果。


九、Day26 最終成果

今天我們完成了以下功能:

功能 測試結果
Auto Response Policy 6/6 PASS
Policy 整合 Dispatcher PASS
真實 Process Alert 觸發 SIGTERM PASS
受控程序身分驗證 PASS
SIGTERM 結果驗證 PASS
Process Response Audit PASS
nftables Temporary Blocking PASS
真實 Network Alert 觸發 BLOCK PASS
30 秒限時封鎖 PASS
封鎖期間連線阻斷驗證 PASS
封鎖到期自動解除 PASS
解除後連線恢復 PASS
Network Response Audit PASS
測試防火牆表格清理 PASS

不過目前還有一些限制。

首先,自動 SIGTERM 和 IP Blocking 只對預先註冊的受控測試目標開放,並不是任意真實威脅都能自動處置。

其次,目前的程序身分驗證仍有改進空間,例如進一步降低 PID 重複利用與檢查、終止之間的競爭條件。

最後,雖然限時阻斷元素可以自行到期,但異常狀況下的資源清理、權限隔離、重複封鎖及系統重啟復原,仍需要後續完善。

因此,BehaviorGuard 現階段仍然是研究與實驗用途的 Linux EDR 原型,而不是可直接部署到正式企業環境的防護產品。


十、今日心得

今天是目前 BehaviorGuard 開發過程中,我認為非常重要的一天。

前面幾天,我們花了不少時間寫 Detection Rules,讓 Linux 能夠偵測可疑程序、Shell 指令、網路連線、檔案異動,以及 Persistence 行為。

但我最初規劃這個專題時,就不希望它最後只是顯示很多 Alert。

因為在真實的資安環境中,發現可疑行為只是第一步,後面還有判斷、處置與驗證的工作。

今天最大的進步,就是讓 BehaviorGuard 真正執行了兩種 Response:

第一種是透過真實 Process Alert,自動終止事先註冊的測試程序。

第二種是透過真實 Network Alert,自動執行 nftables 限時 IP Blocking。

而且這次不只驗證防禦是否執行,還確認程序是否真的退出、網路是否真的被阻斷,以及到期後能否恢復。

開發過程中也遇到不少問題。

例如第一次進行 Process Auto Response 時,雖然 BG-CMD-002 成功觸發,程序卻沒有被終止。

後來才發現 Process Monitor 還沒有接到正確的 Unified Pipeline。

這讓我更清楚理解,程式裡面即使已經寫好 Response 函式,也不代表實際的 Detection Alert 一定能走到那個函式。

另外,我也學到 nftables 不只能建立一般的 Drop Rule,還可以利用 Set Timeout 讓封鎖元素自動到期。

這對自動防禦來說很重要,因為如果只考慮如何封鎖,卻沒有考慮如何恢復,一旦發生誤判,防禦機制本身也可能造成服務中斷。

今天最大的心得是:好的資安自動防禦,不只是知道什麼時候要執行 Response,更重要的是知道什麼情況下不能執行,以及執行後如何安全恢復。

經過 Day26,BehaviorGuard 已經從原本以 Detection 為主的工具,逐步發展成具有真實受控 Auto Response 能力的 Linux Endpoint Security 原型。

接下來 Day27,我們將回頭檢查所有已建立的 Detection Rules,確認 Process、Network、File 和 Persistence Alert 是否都能進入 Unified Pipeline,並進一步完成 Multi-Source Correlation。

讓 BehaviorGuard 不只是看見單一可疑行為,也能分析多個行為之間是否形成一條完整的攻擊鏈。

Day26 完成。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言