iT邦幫忙

0

Day 8 BehaviorGuard:從單一連線警告到行為式 Network Detection

  • 分享至 

  • xImage
  •  

Day 7 我完成了 BehaviorGuard 第一版的 Network Monitor,可以從 Linux 系統取得目前的 TCP 連線,也能偵測像 nc 這類工具建立的可疑 Listener。

但做到這裡後,我發現一個問題:

如果只是看到 nc、看到某個 Port 就發出 Alert,那其實離真正的 EDR 還有一段距離。

因為真實環境中本來就存在大量正常網路連線,例如瀏覽器、Web Server、系統更新、API、SSH 等。

如果每一條 Connection 都產生 Alert,SOC 人員反而會被大量警告淹沒。

所以 Day 8 的目標,就是讓 Network Detection 從單純的「條件判斷」,開始往:

Context + Behavior

的方向發展。


一、加入 Process Context

原本 Network Monitor 可能只知道:

Process : nc
PID     : 1653690
Remote  : 127.0.0.1:9999

但只知道 Process Name 還不夠。

因此我加入 Process Context,透過 Linux /proc 取得:

PID
PPID
Process
Parent Process
UID
Command Line

實際取得的資訊例如:

PID     : 1653690
PPID    : 1653552
Process : nc
Parent  : zsh
Command : nc 127.0.0.1 9999
UID     : 1000

這樣 BehaviorGuard 看到的就不只是:

nc 建立了一條 Connection

而是可以理解成:

zsh
 └── nc
      └── TCP Connection

這些資訊之後都可以成為判斷行為的重要 Context。


二、判斷 Network Scope

接著我加入 Network Context,讓 BehaviorGuard 判斷 Remote IP 屬於哪一種範圍。

主要分成:

LOOPBACK
PRIVATE
EXTERNAL
MULTICAST
UNSPECIFIED
UNKNOWN

例如:

127.0.0.1
→ LOOPBACK

192.168.1.50
→ PRIVATE

10.0.0.5
→ PRIVATE

8.8.8.8
→ EXTERNAL

這裡有一個很重要的觀念:

EXTERNAL 不代表惡意。

例如 Firefox 連到 Internet:

firefox → External :443

本來就是正常行為。

所以不能寫成:

External Connection
        ↓
     HIGH Alert

而是要搭配 Process、Parent、Command、Port 等資訊一起判斷。


三、建立 Enriched Network Event

接著我升級 network_monitor.py。

現在一筆 Network Event 會包含:

Timestamp

PID
PPID
Process
Parent
UID
Command

TCP State

Local IP
Local Port

Remote IP
Remote Port

Network Scope

實際執行可以看到:

========== Network Event ==========

Process       : nc
PID           : 1653690
Parent        : zsh
UID           : 1000
Command       : nc 127.0.0.1 9999

State         : ESTAB

Local         : 127.0.0.1:46686
Remote        : 127.0.0.1:9999

Network Scope : LOOPBACK

這裡我開始理解一個 EDR 很重要的概念:

Telemetry 不等於 Alert。

系統可以收集很多 Event,但不是每個 Event 都應該變成資安警告。


四、目前的 Network Detection Rules

目前 BehaviorGuard 已經建立六條 Network Detection Rule。

BG-NET-001:Suspicious Network Listener

偵測像 nc、ncat、socat 這類工具建立 Listening Socket。

例如:

nc -l -p 9999

BehaviorGuard 發現這類工具正在監聽 Port 時,就會產生 Detection Signal。


BG-NET-002:Suspicious Network Connection

第二條則是觀察這類工具是否建立 TCP Connection。

例如:

nc → 127.0.0.1:9999

如果 Connection 進入:

ESTAB

就會產生:

BG-NET-002
Suspicious Network Connection
Severity: MEDIUM

BG-NET-003:Unexpected External Connection

第三條開始加入 Context。

例如:

python3
+
ESTAB
+
EXTERNAL

會被視為值得進一步觀察的行為。

但如果:

python3 → 127.0.0.1

Network Scope 是:

LOOPBACK

就不會因為這條 Rule 產生 Alert。


BG-NET-004:Unusual Process / Port Behavior

第四條不是直接把某個 Port 定義成惡意,而是觀察:

Process 與 Destination Port 的組合是否不尋常。

例如:

curl → External :443

這是非常常見的 HTTPS 行為,所以:

No Alert

但如果:

curl → External :4444

則產生:

BG-NET-004
Unusual Process Port Behavior
Severity: LOW

這裡故意只設定成 LOW。

因為使用 4444 並不能直接證明是攻擊,它只是一個值得注意的弱訊號。


BG-NET-005:Shell / Interpreter Network Activity

第五條針對 Shell 與 Interpreter 的網路活動。

目前觀察:

bash
sh
zsh
python
python3
perl
ruby

例如:

python3 → External

可能同時觸發:

BG-NET-003
+
BG-NET-005

目前 Detection Layer 會保留兩個不同的 Signal。

未來再透過 Correlation 與 Risk Scoring 判斷它們是否屬於同一個 Incident。


五、BG-NET-006:第一次做 Stateful Detection

今天最重要的是:

BG-NET-006
Connection Burst / Scan-like Pattern

前面的 Rule 大部分都是:

一筆 Event
   ↓
Rule
   ↓
Alert

但是有些攻擊行為不能只看一筆 Event。

例如:

nc → 9001
nc → 9002
nc → 9003
nc → 9004
nc → 9005

單獨看:

nc → 9001

可能沒有辦法判斷發生什麼事情。

但是把多筆 Event 合起來:

同一組執行來源
+
同一 Destination
+
10 秒內
+
連線到 5 個不同 Destination Ports

就開始具有 Scan-like Behavior 的特徵。

因此我建立:

detection/network_behavior.py

並使用:

from collections import defaultdict, deque

保存最近的 Network Activity。

目前設定:

WINDOW_SECONDS = 10
PORT_THRESHOLD = 5

也就是:

在 10 秒時間窗口內觀察是否出現多個不同 Destination Port。

這也是 BehaviorGuard 第一次開始具有「短期記憶」。

從:

Event → Alert

變成:

Event 1
   ↓
記住

Event 2
   ↓
記住

Event 3
   ↓
記住

Event 4
   ↓
記住

Event 5
   ↓
分析整體行為
   ↓
BG-NET-006

六、不同 PID 造成的問題

第一次設計 BG-NET-006 時,我使用:

PID + Process + Remote IP

作為事件的分組依據。

但真實測試後發現:

nc → 9001
nc → 9002
nc → 9003
nc → 9004
nc → 9005

其實會產生五個不同 PID。

例如:

PID 1675805 → :9001
PID 1675806 → :9002
PID 1675807 → :9003
PID 1675808 → :9004
PID 1675809 → :9005

如果只看 PID,BehaviorGuard 會認為:

五個完全不同的 Process

但進一步觀察後發現它們其實具有:

相同 Parent
相同 PPID

也就是:

             zsh
              │
      ┌───────┼───────┐
      ↓       ↓       ↓
     nc      nc      nc
      ↓       ↓       ↓
    :9001   :9002   :9003

所以後來把 BG-NET-006 的 Execution Context 改成利用:

PPID
+
Process
+
Remote IP

進行事件聚合。

這樣即使 Child Process 的 PID 不同,只要它們來自同一個 Parent Context,就可以一起分析。


七、第一次真實測試:成功,但出現 False Positive

接著我建立五個 Listener:

for p in 9001 9002 9003 9004 9005; do
    nc -l -p $p >/dev/null 2>&1 &
done

再建立五條 Connection:

for p in 9001 9002 9003 9004 9005; do
    nc 127.0.0.1 $p >/dev/null 2>&1 &
done

BehaviorGuard 成功產生:

BG-NET-006
Connection Burst / Scan-like Pattern
Severity: HIGH

原本以為成功了。

但仔細看 Alert 後,發現一個問題:

Listener 那一側竟然也觸發 BG-NET-006。

例如:

nc -l -p 9001

接受 Client Connection 後可能看到:

9001 ← 53944
9002 ← 59880
9003 ← 39442
9004 ← 45504
9005 ← 34342

這些:

53944
59880
39442
45504
34342

是 Client 使用的臨時 Port。

但 BG-NET-006 第一版看到:

很多不同 Remote Ports

就把它判斷成 Scan-like Pattern。

這就是今天遇到的:

False Positive(誤報)


八、Rule Tuning:降低 False Positive

因此我再次修改 BG-NET-006。

對目前 Prototype 的 nc / ncat 測試,先利用 Command Context 判斷它是不是 Listener。

核心邏輯:

if process in ["nc", "ncat"]:
    normalized_command = f" {command} "

    if (
        " -l " in normalized_command
        or " --listen " in normalized_command
    ):
        return None

也就是:

nc -l -p 9001
      ↓
Listener
      ↓
不加入 BG-NET-006 的掃描行為統計

而:

nc 127.0.0.1 9001
      ↓
Client Connection
      ↓
加入 BG-NET-006 的 Behavior History

這是目前 Prototype 的簡化處理方式,之後如果要做得更完整,還需要更可靠地判斷 Connection Direction。


九、第二次真實測試

修改完 Rule 後,我重新執行相同測試。

這次 Listener:

nc -l -p 9001
nc -l -p 9002
nc -l -p 9003
nc -l -p 9004
nc -l -p 9005

沒有再錯誤觸發 BG-NET-006。

而 Client:

nc → 127.0.0.1:9001
nc → 127.0.0.1:9002
nc → 127.0.0.1:9003
nc → 127.0.0.1:9004
nc → 127.0.0.1:9005

成功觸發:

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

Rule       : BG-NET-006
Name       : Connection Burst / Scan-like Pattern
Severity   : HIGH

Description:
nc processes from the same execution context
connected to 5 different destination ports
on 127.0.0.1 within 10 seconds.

這代表這次 Rule Tuning 成功降低了實際測試中發現的 False Positive。


十、目前 Network Detection 架構

目前 BehaviorGuard 的 Network Detection 大致變成:

Linux Network
      ↓
Network Monitor
      ↓
Raw Network Telemetry
      ↓
Process Context
+
Network Context
      ↓
Enriched Network Event
      ↓
Detection Engine
      │
      ├── BG-NET-001
      ├── BG-NET-002
      ├── BG-NET-003
      ├── BG-NET-004
      ├── BG-NET-005
      └── BG-NET-006
               ↓
        Stateful Detection
               ↓
             Alert

目前完成六條 Network Rules:

BG-NET-001
Suspicious Listener

BG-NET-002
Suspicious Network Connection

BG-NET-003
Unexpected External Connection

BG-NET-004
Unusual Process / Port Behavior

BG-NET-005
Shell / Interpreter Network Activity

BG-NET-006
Connection Burst / Scan-like Pattern

十一、今天學到的資安知識

今天最大的收穫其實不是多寫了幾條 Rule,而是開始理解 Detection Engineering 真正困難的地方。

1. 異常不代表攻擊

例如:

python3 → Internet

可能是正常 API Request,也可能是其他程式正常連線。

所以不能看到一個「看起來可疑」的東西就直接判定遭到攻擊。

需要更多 Context。


2. Telemetry 不等於 Alert

EDR 可以收集大量:

Process Event
Network Event
File Event
Command Event

但如果:

每個 Event
   ↓
全部 Alert

那最後 SOC 人員會被大量 Alert 淹沒。

所以 Detection 的目的不是「產生越多 Alert 越好」。

而是找出真正值得分析的 Behavior。


3. False Positive 是 Detection Engineering 很重要的問題

今天第一次 BG-NET-006 其實成功偵測到了:

很多不同 Remote Ports

但是後來才發現:

那些 Port 是 Listener 看到的 Client Ephemeral Ports。

也就是:

程式邏輯沒有壞

但:

資安語意判斷錯了

這讓我第一次比較明顯感受到:

Rule 能跑,不代表 Rule 就寫對了。


4. Detection Rule 需要持續 Tuning

今天完整經歷:

設計 Rule
    ↓
人工測試
    ↓
真實 Socket 測試
    ↓
產生 Alert
    ↓
分析 Alert
    ↓
發現 False Positive
    ↓
找出 Ephemeral Port 問題
    ↓
加入 Listener Filtering
    ↓
重新測試
    ↓
False Positive 降低

這比單純寫一條:

if suspicious:
    alert()

複雜很多。


5. Stateful Detection

以前的 Rule 比較像:

看到 A
↓
Alert

今天第一次做到:

看到 A
看到 B
看到 C
看到 D
看到 E
   ↓
放進時間窗口
   ↓
分析整體 Pattern
   ↓
Alert

這就是 Stateful Detection 的概念。

也讓 BehaviorGuard 開始真正往「Behavior-based Detection」發展。


Day 8 完成

目前 BehaviorGuard 進度:

Process Detection       ✅
Command Detection       ✅
Network Detection       ✅

File Detection          ⏳
Persistence Detection   ⏳

Correlation             ⏳
Risk Scoring            ⏳
Alert Deduplication     ⏳

Response                ⏳

今天最大的進步,是 BehaviorGuard 不再只是:

看到 nc
↓
Alert

而開始變成:

Telemetry
    ↓
Context Enrichment
    ↓
Detection Rule
    ↓
Behavior History
    ↓
Time Window
    ↓
Pattern Detection
    ↓
False Positive Analysis
    ↓
Rule Tuning

而且今天也真的遇到一次 False Positive,找出原因後重新調整 Detection Logic。

我覺得這也是目前做到 Day 8 為止,第一次比較明顯感受到:

資安偵測真正困難的不是「寫出 Alert」,而是讓 Alert 有意義。

下一步準備開始補 BehaviorGuard 的另一個 Telemetry Source。


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

尚未有邦友留言

立即登入留言