調查可疑的 IoT 裝置
適用於 IoT 的 Defender 服務警示可明確指出疑似涉入可疑活動的的 IoT 裝置,或有跡象顯示已遭到入侵的裝置。
在本指南中,使用所提供的調查建議,來協助判斷組織的潛在風險、決定如何修復,以及探索可在日後防止類似攻擊的最佳方法。
- 尋找您的裝置資料
- 使用 KQL 查詢進行調查
我如何存取資料?
根據預設,適用於 IoT 的 Defender 會在 Log Analytics 工作區中儲存您的安全性警示和建議。 您也可以選擇儲存未經處理的安全性資料。
若要找出用來儲存資料的 Log Analytics 工作區:
- 開啟 IoT 中樞,
- 在 [安全性] 底下,選取 [設定],然後選取 [資料收集]。
- 變更 Log Analytics 工作區的組態詳細資料。
- 選取 [儲存]。
下列組態,執行下列步驟來存取儲存在 Log Analytics 工作區中的資料:
- 選取並在 IoT 中樞中選取適用於 IoT 的 Defender 警示。
- 選取 [進一步調查]。
- 選取 [若要查看哪些裝置有此警示,請按一下這裡並檢視 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 解決方案安全性態勢。 如果您還沒有裝置代理程式,請考慮部署安全性代理程式或變更現有裝置代理程式的組態,以改善您的結果。