SIEM for Azure Activity Monitor
===
# Problem

# Current Status
- 同類型攻擊已被抑制
- 雲端環境公用帳號皆無高級權限
- 設置create vm policy,暫時讓vm無法再被建置
- Azure Activity, AAD Sing-in Log已藉由connector導入至SIEM供後續監控使用
- 依據上述問題之攻擊型態,分析出可行監測點如下:

1. 惡意登入意圖監測點:
- 入侵通常透過短時間**透過不同地理區域登入地點嘗試目標帳號**
- 登入時由於多重次數嘗試,**登入失敗的次數相比之下會偏高**
2. Azure Portal監測點
- 攻擊者通常會嘗試登入不同微軟服務,如outlook, sharepoint等。此次攻擊手法透過**存取Azure Portal後取得resource使用**
3. Azure大量使用資源監測點
- 攻擊者可能意圖破壞雲端資源部署,進行**大量刪除資源動作**
- 攻擊者可能**大量建立資源**作為跳板,對其他目標進行攻擊
- 為能有效建立更多資源,攻擊者可能**藉由特定帳號升級其它帳號權限或提升自己權限**
# Goal
<!-- - 阻擋
- 透過Azure Policy設置特定規則阻絕侵入 -->
- 根據上述問題分析偵測點,偵測:
- 惡意登入意圖
- Azure大量使用資源
- 通知機制建立
# Scenarios

- Azure Sentinel本身提供許多內建的Hunting Queries
- Data Source Filter可以挑選出專屬於AzureActivity, SigninLogs之腳本供參考
- 後續再調整/客製相關Query,設定告警機制
### 異常登入活動偵測
#### Azure Active Directory Sign-in Burst from Multiple Locations
- Highlights accounts associated with multiple authentications from different geographical locations in a short period of time.
- 偵測多重地點登入意圖,識別高風險被入侵帳號清單
- 若未有啟用MFA帳號於此清單中更需注意入侵風險
#### Failed Attempt to Access Azure Portal
- Access attempts to Azure Portal from an unauthorized user. Either invalid password or the user account does not exist.
- 偵測嘗試登入失敗Azure Portal使用者
- 可再嘗試結合Azure角色資料,識別風險高低
### Azure 異常活動偵測
#### Granting Permissions to Account 帳號提升權限告警
- Shows the most prevalent users who grant access to others on azure resources and for each account their common source ip address. If an operation is not from this IP address it may be worthy of investigation.
- 監測特權帳號權限提升行為
- 若是該清單常用ip與新的提升特權帳號活動比較之ip有落差,或許是可疑異常
#### Mass Cloud Resource Deletions Time Series Anomaly
- 偵測駭客惡意破壞行為,透過特定帳號大量刪除雲端資源
- 偵測特定帳號不當操作大量刪除資源
#### Mass Cloud Resource Creation Time Series Anomaly
- 偵測駭客竊取雲端資源,透過特定帳號大量建置雲端資源
- 偵測特定帳號不當操作大量建置資源
# Issue TBD
- 偵測異常之後續工作預期難以定義工作/職責
- 2個Log Table各找2個有價值可run的腳本提報
# Ref
- https://github.com/Azure/Azure-Sentinel/tree/master/Hunting%20Queries/SigninLogs
- https://github.com/Azure/Azure-Sentinel/tree/master/Hunting%20Queries/AzureActivity
:::spoiler
# Backup
#### Common deployed resources
- This query looks for common deployed resources (resource name and resource groups) and can be used in combination with other signals that show suspicious deployment to evaluate if the resource is one that is commonly being deployed/created or unique.
- 監測異常資源部署
- 後續可以以此查詢微調,內建有使用Apriori algorith方式
- https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/basketplugin?WT.mc_id=Portal-fx
- 簡易點可能可以利用過去頻率基礎亦可

```
AzureActivity
| where OperationNameValue has_any ("DEPLOYMENTS/WRITE", "virtualMachines/write")
| where ActivityStatusValue == "Success"
| summarize by bin(TimeGenerated, 1h), Resource, ResourceGroup, OperationNameValue, Caller
| evaluate basket()
| where isnotempty(Caller) and isnotempty(Resource) and isnotempty(TimeGenerated)
| order by Percent desc, TimeGenerated desc
| extend timestamp = TimeGenerated
// remove comments below on filters if the goal is to see more common or more rare Resource, Resource Group and Caller combinations
| where Percent <= 40 // <-- more rare
// | where Percent >= 60 // <-- more common
```
#### Creation of an anomalous number of resources
- Looks for anomalous number of resources creation or deployment activities in azure activity log. It is best to run this query on a look back period which is at least 7 days.
- 監測不規則/詭異的異常資源建立
- 以time series方式呈現,觀察是否有異常pattern
```
AzureActivity
| where OperationNameValue in~ ("microsoft.compute/virtualMachines/write", "microsoft.resources/deployments/write")
| where ActivityStatusValue == "Success"
| where SubscriptionId == "643ce542-f23a-4c64-b43d-4010277d25f8" //DIaaS
| make-series dcount(ResourceId) default=0 on EventSubmissionTimestamp in range(ago(7d), now(), 1d) by Caller
| extend AccountCustomEntity = Caller
| extend timestamp = todatetime(EventSubmissionTimestamp[7])
```
```
let starttime = 14d;
let endtime = 1d;
let timeframe = 1h;
let TotalEventsThreshold = 25;
let TimeSeriesData =
AzureActivity
| where TimeGenerated between (startofday(ago(starttime))..startofday(ago(endtime)))
| where OperationNameValue endswith "delete"
| project TimeGenerated, Caller
| make-series Total = count() on TimeGenerated from startofday(ago(starttime)) to startofday(ago(endtime)) step timeframe by Caller;
let TimeSeriesAlerts = materialize(TimeSeriesData
| extend (anomalies, score, baseline) = series_decompose_anomalies(Total, 3, -1, 'linefit')
| mv-expand Total to typeof(double), TimeGenerated to typeof(datetime), anomalies to typeof(double), score to typeof(double), baseline to typeof(long)
| where anomalies > 0
| project Caller, TimeGenerated, Total, baseline, anomalies, score
| where Total > TotalEventsThreshold and baseline > 0 );
TimeSeriesAlerts
| where TimeGenerated > (ago(endtime))
| project TimeGenerated, Caller
| join (AzureActivity
| where TimeGenerated > (ago(endtime))
| where OperationNameValue endswith "delete"
| summarize count(), make_set(OperationNameValue), make_set(Resource) by bin(TimeGenerated, 1h), Caller) on TimeGenerated, Caller
| extend timestamp = TimeGenerated, AccountCustomEntity = Caller
```
#### Login spike with increase failure rate
- This query over SiginLogs will summarise the total number of login attempts for each hour of the day on week days, this can be edited. The query then uses Kusto anomaly detection to find login spikes for each hour across all days. The query will then calculate the percentage change between the anomalous period and the average logins for that period. Finally the query will determine the success and failure rate for logins for the given 1 hour period, if a specified % change in logins is detected alongside a specified failure rate a result is presented.
- 使用kql中異常偵測的內建功能,偵測登入行為fail rate異常狀況
:::