/// <summary> /// Create web hook subscriptions in order to receive the notifications /// </summary> /// <param name="filters"></param> /// <returns>The subscription object</returns> public async Task <Tuple <Subscription, string> > Subscribe(AlertFilterModel filters) { var changeType = "updated"; var expirationDate = DateTime.UtcNow.AddHours(3); var randno = new Random().Next(1, 100).ToString(); var clientState = "IsgSdkSubscription" + randno; var filteredQuery = GraphQueryProvider.GetQueryByAlertFilter(filters); var resource = filters.ContainsKey("AlertId") && filters.HasPropertyFilter("AlertId") ? $"/security/alerts/{filters.GetFirstPropertyFilter("AlertId").Value}" : $"/security/alerts{(!String.IsNullOrWhiteSpace(filteredQuery) ? $"?$filter={filteredQuery}" : string.Empty)}"; Subscription subscription = new Subscription() { ChangeType = changeType, NotificationUrl = ConfigurationManager.AppSettings["ida:NotificationUrl"], Resource = resource, ExpirationDateTime = expirationDate, ClientState = clientState }; var result = await this.graphClient.Subscriptions.Request().AddAsync(subscription); return(new Tuple <Subscription, string>(result, filteredQuery)); }
/// <summary> /// Get alerts based on the alert filters /// </summary> /// <param name="filters"></param> /// <returns>alerts matching the filtering criteria</returns> public async Task <Tuple <IEnumerable <Alert>, string> > GetAlerts(AlertFilterModel filters, Dictionary <string, string> odredByParams = null) { if (filters == null) { var result = await this.graphClient.Security.Alerts.Request().Top(filters.Top).GetAsync(); return(new Tuple <IEnumerable <Alert>, string>(result, string.Empty)); } else { try { // Create filter query var filterQuery = GraphQueryProvider.GetQueryByAlertFilter(filters); var customOrderByParams = new Dictionary <string, string>(); //// If there are no filters and there are no custom odredByParams (if specified only top X) if ((odredByParams == null || odredByParams.Count() < 1) && filters.Count < 1) { customOrderByParams.Add("createdDateTime", "desc"); } else if (filters.Count >= 1 && filters.ContainsKey("createdDateTime")) { customOrderByParams.Add("createdDateTime", "desc"); } // Create request with filter and top X ISecurityAlertsCollectionRequest request = null; if (string.IsNullOrEmpty(filterQuery)) { request = this.graphClient.Security.Alerts.Request().Top(filters.Top); } else { request = this.graphClient.Security.Alerts.Request().Filter(filterQuery).Top(filters.Top); } // Add order py params if (customOrderByParams.Count > 0) { request = request.OrderBy(string.Join(", ", customOrderByParams.Select(param => $"{param.Key} {param.Value}"))); } else if (odredByParams != null && odredByParams.Count() > 0) { request = request.OrderBy(string.Join(", ", odredByParams.Select(param => $"{param.Key} {param.Value}"))); } // Get alerts var result = await request.GetAsync(); return(new Tuple <IEnumerable <Alert>, string>(result, filterQuery)); } catch (Exception ex) { } return(null); } }
/// <summary> /// Get information about alert statistics /// </summary> /// <returns>Statistics Data</returns> public async Task <AlertStatisticModel> GetStatisticAsync(int topAlertAmount) { // Select all unresolved alerts var filter = new AlertFilterModel { Top = topAlertAmount }; filter.Add( "Status", new List <AlertFilterProperty>() { { new AlertFilterProperty(new AlertFilterPropertyDescription("Status", AlertFilterOperator.NotEquals), "resolved") } }); var unresolvedAlerts = await this.GetAlerts(filter); //// Select all secure scores string accessToken = await SampleAuthProvider.Instance.GetUserAccessTokenAsync(); var secureScores = await this.GetSecureScore(accessToken, "?$top=100"); var latestSecureScore = secureScores.OrderByDescending(rec => rec.CreatedDateTime).FirstOrDefault(); var secureScoreModel = latestSecureScore != null ? new SecureScoreStatisticModel { Current = latestSecureScore.CurrentScore ?? 0, Max = latestSecureScore.MaxScore ?? 0 } : null; var activeAlerts = new Dictionary <string, int>(); var usersAlerts = new StatisticCollectionModel <SeveritySortOrder>(); var hostsAlerts = new StatisticCollectionModel <SeveritySortOrder>(); var providersAlerts = new StatisticCollectionModel <SeveritySortOrder>(); var ipAlerts = new StatisticCollectionModel <SeveritySortOrder>(); if (unresolvedAlerts != null && unresolvedAlerts.Item1 != null) { foreach (var alert in unresolvedAlerts.Item1) { // Calculate active alerts if (!activeAlerts.ContainsKey(alert.Severity.ToString())) { activeAlerts.Add(alert.Severity.ToString(), 1); } else { ++activeAlerts[alert.Severity.ToString()]; } // Calculate users with the most alerts var userPrincipalName = alert.UserStates?.FirstOrDefault()?.UserPrincipalName; if (!string.IsNullOrWhiteSpace(userPrincipalName)) { usersAlerts.Add(userPrincipalName, alert.Severity.ToString()); } // Calculate destination ip address with the most alerts var ipAddress = alert.NetworkConnections?.FirstOrDefault()?.DestinationAddress; if (!string.IsNullOrWhiteSpace(ipAddress)) { ipAlerts.Add(ipAddress, alert.Severity.ToString()); } // Calculate hosts with the most alerts var hostName = alert.HostStates?.FirstOrDefault()?.Fqdn; if (!string.IsNullOrWhiteSpace(hostName)) { hostsAlerts.Add(hostName, alert.Severity.ToString()); } // Calculate providers with the most alerts var provider = alert.VendorInformation.Provider; if (!string.IsNullOrWhiteSpace(provider)) { providersAlerts.Add(provider, alert.Severity.ToString()); } } } // Get top of the sorted users with the most alerts var sortedTopUserAlertsWithPrincipalNames = usersAlerts.GetSortedTopValues(4); var sortedTopUserAlert = new Dictionary <KeyValuePair <string, string>, Dictionary <SeveritySortOrder, int> >(); // Get additional information about each user from top list var users = await this.GetUserDisplayNames(sortedTopUserAlertsWithPrincipalNames.Select(rec => rec.Key)); //// Replaced UserPrincipalName to DisplayName if it is possible if (users != null) { foreach (var rec in sortedTopUserAlertsWithPrincipalNames) { var newKey = users.ContainsKey(rec.Key) && !users[rec.Key].Equals(rec.Key, StringComparison.CurrentCultureIgnoreCase) ? users[rec.Key] : rec.Key; sortedTopUserAlert.Add(new KeyValuePair <string, string>(newKey, rec.Key), rec.Value); } } return(new AlertStatisticModel { ActiveAlerts = activeAlerts, SecureScore = secureScoreModel, UsersWithTheMostAlerts = sortedTopUserAlert, HostsWithTheMostAlerts = hostsAlerts.GetSortedTopValues(4) .Select(rec => new KeyValuePair <KeyValuePair <string, string>, Dictionary <SeveritySortOrder, int> >( new KeyValuePair <string, string>( rec.Key.Split('.').FirstOrDefault() ?? rec.Key, rec.Key), rec.Value)).ToDictionary(rec => rec.Key, rec => rec.Value), ProvidersWithTheMostAlerts = providersAlerts.GetSortedTopValues(4).Select(rec => new KeyValuePair <KeyValuePair <string, string>, Dictionary <SeveritySortOrder, int> >( new KeyValuePair <string, string>( rec.Key, rec.Key), rec.Value)).ToDictionary(rec => rec.Key, rec => rec.Value), IPWithTheMostAlerts = ipAlerts.GetSortedTopValues(4) .Select(rec => new KeyValuePair <KeyValuePair <string, string>, Dictionary <SeveritySortOrder, int> >( new KeyValuePair <string, string>( rec.Key.Split('.').FirstOrDefault() ?? rec.Key, rec.Key), rec.Value)).ToDictionary(rec => rec.Key, rec => rec.Value), }); }