Guidant AI 資安檢視總報告 · 連線清單
代理程式拿著客戶給的維運帳密,登進客戶自己的伺服器跑檢查的那條線。CINC Auditor/GCB/OpenSCAP 三種主機型工具都走它;Nmap 也走它(登進「執行主機」去跑)。這是整套產品裡權限最高的一條線——帳密通常是能 sudo 的。這一頁回答:這條線怎麼連、哪些功能走它、它帶來什麼威脅、駭客怎麼打、我們要怎麼防、目前做到哪。
這一頁怎麼來的:DFD Level 0 把產品運作時的連線編成 C01~C25;STRIDE 六頁每一條問題都標了發生在哪幾條線。這裡以連線為單位整理。命中只有 1 條,另兩種手法是依這條線的特性補的(表內標明)。個別問題修了沒不在這頁講。
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB'}}}%%
flowchart LR
API["guidant-api<br/>派工時解密帳密"]
subgraph AGENTBOX["🏢 客戶機房"]
direction LR
subgraph AG["evidence-agent"]
direction TB
CRED["帳密 → /dev/shm 暫存檔<br/>0600・用完即刪<br/>不進命令列"]
TOOLS["cinc-auditor(InSpec/GCB)<br/>oscap(OpenSCAP,paramiko)<br/>nmap(登進執行主機跑)"]
CRED --> TOOLS
end
LNX(["🖥 Linux 主機<br/>sshd :22"])
WIN(["🖥 Windows 主機<br/>WinRM :5985 明文<br/>/:5986 TLS"])
MITM(["🕵 同網段的人<br/>搶答 SSH/攔 WinRM"])
TOOLS == "SSH :22 · 密碼或私鑰<br/>不驗主機指紋" ==> LNX
TOOLS == "WinRM · 帳密<br/>預設 http :5985" ==> WIN
MITM -. "回應 SSH 握手<br/>或攔明文 WinRM" .-> TOOLS
end
API -- "C20 · 心跳回應帶明文帳密" --> AG
classDef ext fill:#FBFCFC,stroke:#9AA8AA,stroke-dasharray:3 2
classDef open fill:#FDECEC,stroke:#C0392B
class LNX,WIN,MITM ext
class MITM open
| 項目 | 現況 |
|---|---|
| 誰 → 誰 | 客戶機房的 evidence-agent → 客戶自己的受檢主機(Linux 或 Windows)。兩端都在客戶內網,我們的雲端連不到也不碰這條線 |
| 協定/埠 | Linux:SSH :22(CINC Auditor/GCB 由 cinc-auditor 的 ssh transport 連;OpenSCAP 與 Nmap 用 paramiko 直連)。Windows:WinRM(cinc-auditor 的 winrm transport),winrm_ssl 開關決定走 :5985 明文 http 或 :5986 TLS,預設關、走明文;開 TLS 時另有 winrm_self_signed 可接受自簽憑證 |
| 傳什麼 | 登入後在主機上執行檢查命令(讀設定檔、查服務狀態、跑 oscap/nmap 二進位),把結果拉回 agent。OpenSCAP/Nmap 在遠端家目錄建暫存檔、跑完 SFTP 拉回、finally 清掉 |
| 怎麼驗身分 | 代理程式對主機:客戶填在「檢測工具設定」頁的維運帳密——SSH 走密碼或私鑰(ssh_password/ssh_private_key),WinRM 走帳密;多數檢查需要 root,所以帳號通常能 sudo(Nmap 的 SYN 掃描明文要求 use_sudo,對齊受測機的 sudoers 白名單)。主機對代理程式:SSH 不驗主機指紋——paramiko 設 AutoAddPolicy,誰回應握手就信誰(程式註解寫明「無預先分發的 known_hosts 基礎設施,第一版接受首次連線風險」);WinRM 預設明文沒有身分可驗 |
| 帳密怎麼到 agent 手上 | 雲端加密存 tenant_detection_tool_configs,派工時解密、經 C20 心跳回應下發。agent 收到後不進命令列(cinc-auditor --password 會出現在 ps),改寫進 /dev/shm(記憶體型檔案系統)的設定檔/私鑰檔,權限 0600,try/finally 用完即刪(含例外與取消路徑) |
| 何時存在 | 派主機型掃描時。目標清單由任務參數指定,單次上限 DETECTION_SCAN_TARGET_MAX_HOSTS(預設 256) |
依據:agent repo core/task_executor_connectors/inspec.py(transport 選擇、/dev/shm 設定檔、winrm_ssl 預設 False、埠 5985/5986)、openscap.py:194-214(AutoAddPolicy、look_for_keys=False)、nmap.py(SSH 型、use_sudo、shlex.quote);主專案 config/config.py:219;DFD Level 0 §2.6 工具表。
| 群 | 功能 | 對威脅的意義 |
|---|---|---|
| ① 組態合規檢查 | CINC Auditor(InSpec 相容規則包)、GCB(政府組態基準,同引擎換內容)、OpenSCAP(CIS/STIG,Linux 限定) | 登進去讀設定、跑檢查命令。權限高但動作是讀;風險在「拿著能 sudo 的帳號登進去的是誰、跑的規則包是誰寫的」(規則包來源見 C24) |
| ② 網路探測 | Nmap——agent 登進客戶指定的「執行主機」,在上面跑 [sudo] nmap 掃目標網段(這一跳是 C23,掃出去的流量是 C25) |
執行主機要裝 nmap 並放 sudoers 白名單;targets 與埠範圍是使用者輸入、直接進命令列(有 shlex.quote) |
| ③ 測試連線 | 「測試連線」按鈕經 C21 叫 agent 對目標主機實連一次 | 目標由按的人填——這就是本頁唯一命中的那條 |
掃描在這條線上抓到 1 條問題(M03-6)。依這條線的特性再補兩種手法(T2、T3 無掃描實例,風險欄標明)。
| # | 風險 | 威脅 | 駭客怎麼打 | 得手什麼 | STRIDE | 實例 |
|---|---|---|---|---|---|---|
| T1 | 🟡 中 | 連到哪由呼叫者填——代理程式替人敲遍內網 | ① 有權按「測試連線」的人;② 目標清單放一整段內網位址;③ agent 逐台用維運帳密去連;④ 從「連得上/被拒/逾時/帳密錯」的差異畫出內網哪些機器活著、開了 SSH 或 WinRM、帳密對不對 | 客戶內網主機存活圖;帳密被送到非預期的主機(若那台是攻擊者的,帳密就外流) | I 資料外洩 | M03-6 「測試連線」要連到哪台主機由呼叫者自己指定 🟡 |
| T2 | —(無掃描實例) | 假冒受檢主機,接走帳密(SSH 不驗指紋/WinRM 明文) | ① 站在 agent 與受檢主機之間(同網段 ARP 欺騙、改 DNS、或控制了目標 IP 曾屬於的機器);② agent 派掃描時發起 SSH——paramiko AutoAddPolicy 不比對主機指紋,攻擊者的 sshd 回應握手就被接受;③ agent 送出密碼(或用私鑰簽挑戰)——密碼直接到手;④ Windows 那頭更簡單:WinRM 預設 :5985 明文,帳密與整段對話在線上就能讀 |
客戶能 sudo 的維運帳密;之後用它登進真正的主機 | S 冒充身分、I 資料外洩 | — |
| T3 | —(無掃描實例) | 受檢主機被入侵後,反過來打代理程式 | ① 某台受檢主機已被攻擊者控制;② agent 用 sudo 帳號登進去跑 oscap/nmap,在遠端家目錄建暫存檔、SFTP 拉回結果;③ 攻擊者替換 oscap/nmap 二進位或動遠端暫存檔,回一份「全部合規」的假報告;④ 或在結果檔裡塞特製內容(超長字串、惡意 XML),讓 agent 解析時卡住或出錯 | 偽造該台主機的稽核結果;讓 agent 的解析卡死 | T 竄改資料、D 讓服務停擺 | — |
三種手法的共同點:這條線上流的是客戶最高權限的鑰匙,而兩端(agent 主機、受檢主機)都是客戶自己的機器、都可能被入侵。T1 是「鑰匙被送到不該去的門」;T2 是「門是假的,鑰匙被接走」;T3 是「門後面的人是假的,報告被換掉」。產品能管的是 agent 這一端怎麼拿鑰匙、怎麼認門、怎麼信門後面回來的東西——不是客戶內網乾不乾淨。
對應三種威脅,防線分六條。D1 直接對應掃描抓到的手法;標 ◇ 的是依這條線的特性補的標準防線,沒有實例。「目前」欄寫程式裡實際有的機制;⚠️ 表示只靠慣例或沒有機制。
| # | 防線 | 擋哪種威脅 | 目前做到哪 |
|---|---|---|---|
| D1 | 目標由呼叫者填,就要限量、收斂回應、記下誰按的 | T1 | ✅ 測試連線限 32 台、回應只回成功/失敗、稽核日誌記目標清單與逐台結果(詳 C21 D3)。裁定不設目標白名單——哪台算合法目標由客戶管 |
| D2 ◇ | 帳密不落實體磁碟、不進命令列、不進日誌 | T2、T3 的前提(帳密在 agent 主機上的暴露面) | ✅ /dev/shm 暫存檔 0600、try/finally 刪;✅ cinc-auditor 走 --config 檔不走 --password;✅ log 只記主機與工具;✅ paramiko look_for_keys=False, allow_agent=False(不撿本機其他身分)。⚠️ /dev/shm 不可用時 fallback 到系統暫存目錄(仍 0600),會落實體磁碟 |
| D3 ◇ | SSH 要驗主機指紋:首次連線記下指紋、之後不符就拒(同 SSH 用戶端的 known_hosts);或由客戶在工具設定頁預填指紋 | T2 | ⚠️ 沒有。AutoAddPolicy=每次都接受(連「首次信任、之後釘住」都沒做——paramiko 的 AutoAdd 在新 client 物件上每次都是「首次」)。程式註解明寫是第一版的取捨。這是這條線最大的缺口:帳密能 sudo,而對方是誰完全不驗 |
| D4 ◇ | WinRM 預設走 TLS(:5986),明文要客戶明示才開;接受自簽憑證也要明示 | T2 | ⚠️ winrm_ssl 預設 False、走 :5985 明文。有 TLS 選項(winrm_ssl+winrm_self_signed),但預設是不安全的那一邊。Windows 主機預設只開 5985,開 5986 要客戶自己配憑證——所以預設明文有實務理由,但至少畫面要警告 |
| D5 ◇ | 從受檢主機拉回的東西都是外部輸入:結果檔大小上限、解析逾時、XML 不解析外部實體 | T3 | ✅ Nmap:XML 上限 60MB(_XML_MAX_BYTES)、解析顯式 resolve_entities=False, no_network=True、XSLT 轉 HTML 走 subprocess 可 kill;✅ 遠端暫存檔 finally 清理含失敗路徑。⚠️ OpenSCAP 沒有對應的結果檔大小上限與解析器設定(openscap.py grep `MAX_BYTES |
| D6 ◇ | 最小權限帳號:文件指引客戶給 agent 專用帳號、sudoers 只白名單必要的二進位,而不是給一般維運帳號 | T1~T3 的後果縮小 | ✅ Nmap 的設定指引明寫 sudoers NOPASSWD: /usr/bin/nmap 白名單、二進位路徑寫死對齊白名單(_NMAP_BIN/_OSCAP_BIN)。⚠️ CINC Auditor/GCB 的檢查需要讀各種系統檔,實務上多半要 root 等效權限,沒有「專用帳號最小權限清單」 |
最該補的一步:D3。SSH 不驗主機指紋,等於拿著客戶的 root 密碼去敲門、誰應門就給誰。做法不難:agent 本機維護一份 known_hosts(首次記、之後比,不符就拒並在掃描結果標紅),或讓客戶在工具設定頁預填主機指紋。這一刀讓 T2 從「同網段就能做」變成「要先攻下那台主機才行」。
AutoAddPolicy 寫在兩支 connector 裡(openscap、nmap),cinc-auditor 的 ssh transport 怎麼處理 host key 沒查(它用 Ruby 的 train-ssh,預設行為另查)。依據:STRIDE 六頁信任邊界連線標記(CM-2403/2404 驗收後版本)、agent repo core/task_executor_connectors/inspec.py/openscap.py/nmap.py、主專案 config/config.py、DFD Level 0 §2.4/§2.6。