調查可疑的 IoT 裝置

適用於 IoT 的 Defender 服務警示可明確指出疑似涉入可疑活動的的 IoT 裝置,或有跡象顯示已遭到入侵的裝置。

在本指南中,使用所提供的調查建議,來協助判斷組織的潛在風險、決定如何修復,以及探索可在日後防止類似攻擊的最佳方法。

  • 尋找您的裝置資料
  • 使用 KQL 查詢進行調查

我如何存取資料?

根據預設,適用於 IoT 的 Defender 會在 Log Analytics 工作區中儲存您的安全性警示和建議。 您也可以選擇儲存未經處理的安全性資料。

若要找出用來儲存資料的 Log Analytics 工作區:

  1. 開啟 IoT 中樞,
  2. 在 [安全性] 底下,選取 [設定],然後選取 [資料收集]
  3. 變更 Log Analytics 工作區的組態詳細資料。
  4. 選取 [儲存]。

下列組態,執行下列步驟來存取儲存在 Log Analytics 工作區中的資料:

  1. 選取並在 IoT 中樞中選取適用於 IoT 的 Defender 警示。
  2. 選取 [進一步調查]
  3. 選取 [若要查看哪些裝置有此警示,請按一下這裡並檢視 DeviceId 資料行]

可疑 IoT 裝置的調查步驟

若要檢視關於您 IoT 裝置的深入解析和未經處理的資料,請移至 Log Analytics 工作區以存取您的資料

請參閱下面的範例 KQL 查詢,以開始調查裝置上的警示和活動。

您可以透過使用下列 KQL 查詢,找出同一時間前後是否觸發了其他警示:

let device = "YOUR_DEVICE_ID";
let hub = "YOUR_HUB_NAME";
SecurityAlert
| where ExtendedProperties contains device and ResourceId contains tolower(hub)
| project TimeGenerated, AlertName, AlertSeverity, Description, ExtendedProperties

具有存取權的使用者

若要了解哪些使用者可以存取此裝置,請使用下列 KQL 查詢:

 let device = "YOUR_DEVICE_ID";
 let hub = "YOUR_HUB_NAME";
 SecurityIoTRawEvent
 | where
    DeviceId == device and AssociatedResourceId contains tolower(hub)
    and RawEventName == "LocalUsers"
 | project
    TimestampLocal=extractjson("$.TimestampLocal", EventDetails, typeof(datetime)),
    GroupNames=extractjson("$.GroupNames", EventDetails, typeof(string)),
    UserName=extractjson("$.UserName", EventDetails, typeof(string))
 | summarize FirstObserved=min(TimestampLocal) by GroupNames, UserName

請使用這項資料來了解︰

  • 哪些使用者可以存取此裝置?
  • 具有存取權的使用者是否擁有預期的權限等級?

開啟連接埠

若要找出裝置中正在使用或已使用的連接埠,請使用下列 KQL 查詢:

 let device = "YOUR_DEVICE_ID";
 let hub = "YOUR_HUB_NAME";
 SecurityIoTRawEvent
 | where
    DeviceId == device and AssociatedResourceId contains tolower(hub)
    and RawEventName == "ListeningPorts"
    and extractjson("$.LocalPort", EventDetails, typeof(int)) <= 1024 // avoid short-lived TCP ports (Ephemeral)
 | project
    TimestampLocal=extractjson("$.TimestampLocal", EventDetails, typeof(datetime)),
    Protocol=extractjson("$.Protocol", EventDetails, typeof(string)),
    LocalAddress=extractjson("$.LocalAddress", EventDetails, typeof(string)),
    LocalPort=extractjson("$.LocalPort", EventDetails, typeof(int)),
    RemoteAddress=extractjson("$.RemoteAddress", EventDetails, typeof(string)),
    RemotePort=extractjson("$.RemotePort", EventDetails, typeof(string))
 | summarize MinObservedTime=min(TimestampLocal), MaxObservedTime=max(TimestampLocal), AllowedRemoteIPAddress=makeset(RemoteAddress), AllowedRemotePort=makeset(RemotePort) by Protocol, LocalPort

請使用這項資料來了解︰

  • 裝置上目前作用中的接聽通訊端有哪些?
  • 目前作用中的這些接聽通訊端是否應允許使用?
  • 是否有任何可疑的遠端位址連線至裝置?

使用者登入

若要找出登入過此裝置的使用者,請使用下列 KQL 查詢:

 let device = "YOUR_DEVICE_ID";
 let hub = "YOUR_HUB_NAME";
 SecurityIoTRawEvent
 | where
    DeviceId == device and AssociatedResourceId contains tolower(hub)
    and RawEventName == "Login"
    // filter out local, invalid and failed logins
    and EventDetails contains "RemoteAddress"
    and EventDetails !contains '"RemoteAddress":"127.0.0.1"'
    and EventDetails !contains '"UserName":"(invalid user)"'
    and EventDetails !contains '"UserName":"(unknown user)"'
    //and EventDetails !contains '"Result":"Fail"'
 | project
    TimestampLocal=extractjson("$.TimestampLocal", EventDetails, typeof(datetime)),
    UserName=extractjson("$.UserName", EventDetails, typeof(string)),
    LoginHandler=extractjson("$.Executable", EventDetails, typeof(string)),
    RemoteAddress=extractjson("$.RemoteAddress", EventDetails, typeof(string)),
    Result=extractjson("$.Result", EventDetails, typeof(string))
 | summarize CntLoginAttempts=count(), MinObservedTime=min(TimestampLocal), MaxObservedTime=max(TimestampLocal), CntIPAddress=dcount(RemoteAddress), IPAddress=makeset(RemoteAddress) by UserName, Result, LoginHandler

請使用查詢結果來了解︰

  • 有哪些使用者登入過此裝置?
  • 這些登入過的使用者是否應該登入?
  • 登入的使用者是從預期還是非預期的 IP 位址進行連線?

處理清單

若要了解處理清單是否符合預期,請使用下列 KQL 查詢:

 let device = "YOUR_DEVICE_ID";
 let hub = "YOUR_HUB_NAME";
 SecurityIoTRawEvent
 | where
    DeviceId == device and AssociatedResourceId contains tolower(hub)
    and RawEventName == "ProcessCreate"
 | project
    TimestampLocal=extractjson("$.TimestampLocal", EventDetails, typeof(datetime)),
    Executable=extractjson("$.Executable", EventDetails, typeof(string)),
    UserId=extractjson("$.UserId", EventDetails, typeof(string)),
    CommandLine=extractjson("$.CommandLine", EventDetails, typeof(string))
 | join kind=leftouter (
    // user UserId details
    SecurityIoTRawEvent
    | where
       DeviceId == device and AssociatedResourceId contains tolower(hub)
       and RawEventName == "LocalUsers"
    | project
       UserId=extractjson("$.UserId", EventDetails, typeof(string)),
       UserName=extractjson("$.UserName", EventDetails, typeof(string))
    | distinct UserId, UserName
 ) on UserId
 | extend UserIdName = strcat("Id:", UserId, ", Name:", UserName)
 | summarize CntExecutions=count(), MinObservedTime=min(TimestampLocal), MaxObservedTime=max(TimestampLocal), ExecutingUsers=makeset(UserIdName), ExecutionCommandLines=makeset(CommandLine) by Executable

請使用查詢結果來了解︰

  • 裝置上是否執行了任何可疑的處理序?
  • 這些處理序是不是由適當的使用者來執行?
  • 是否有任何命令列執行包含正確且預期中的引數?

下一步

在調查裝置並更加了解您的風險之後,請考慮設定自訂警示來改善您的 IoT 解決方案安全性態勢。 如果您還沒有裝置代理程式,請考慮部署安全性代理程式變更現有裝置代理程式的組態,以改善您的結果。