skip to Main Content

I have a bunch of machines being monitored by adaptive application security controls that are giving warnings because the training process was not ran long enough to recognize benign executables. What’s an easy way to add exceptions for the executables in active alerts to the adaptive security groups?

2

Answers


  1. Chosen as BEST ANSWER

    This script grabs the active alerts from defender, and updates the groups. The alerts must still be dismissed manually.

    function Get-ExistingRules {
        Param(
            $subscriptionId,
            $groupName
        )
        $url = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Security/locations/centralus/applicationWhitelistings/${groupName}?api-version=2015-06-01-preview";
        return az rest `
            --method get `
            --url $url `
        | ConvertFrom-Json;
    }
    
    function Add-NewRules {
        Param(
            $subscriptionId,
            $groupName,
            $files
        )
        $url = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Security/locations/centralus/applicationWhitelistings/${groupName}?api-version=2015-06-01-preview";
        $existing = Get-ExistingRules $subscriptionId $groupName;
        $existing | ConvertTo-Json -Depth 100 > asd.json;
        $myList = $existing.properties.pathRecommendations;
        foreach ($file in $files) {
            $myList += [pscustomobject]@{
                path                = $file.path
                type                = "File"
                common              = $true
                action              = "Add"
                usernames           = @(
                    [pscustomobject]@{
                        username             = "Everyone"
                        recommendationAction = "Recommended"
                    }
                )
                userSids            = @(
                    "S-1-1-0"
                )
                fileType            = $file.type
                configurationStatus = "NotConfigured"
            };
        }
        $existing.properties.pathRecommendations = $myList;
        $existing.properties = [pscustomobject]@{
            protectionMode      = $existing.properties.protectionMode
            vmRecommendations   = $existing.properties.vmRecommendations
            pathRecommendations = $existing.properties.pathRecommendations
        }
        $existing.PSObject.properties.remove("location");
        # return $existing;
        $body = $existing | ConvertTo-Json -Depth 20 -Compress;
        $body > temp.json;
        # $body = $body -replace "`"", "`"";
        # return az rest `
        # --method PUT `
        # --url $url `
        # --body $body `
        # | ConvertFrom-Json;
    
        # avoid max command length limit by storing body in a file
        try {
        return az rest `
            --method PUT `
            --url $url `
            --body `@temp.json `
        | ConvertFrom-Json; 
        }
        catch {
            Write-Warning "Encountered error adding rule";
            Write-Warning "$_";
        }
        return $null;
    }
    
    function Format-Body {
        param(
            $obj
        )
        $body = $obj | ConvertTo-Json -Depth 100 -Compress;
        $body = $body -replace "`"", "`"";
        $body = $body -replace "`r", "";
        return $body;
    }
    
    Write-Host "Listing subscriptions";
    # you can filter to just one subscription if you want
    # $subscriptions = az account list --query "[?name=='NPRD'].id" --output tsv;
    $subscriptions = az account list --query "[].id" --output tsv;
    
    $allAlerts = New-Object System.Collections.ArrayList;
    $i = 0;
    foreach ($sub in $subscriptions) {
        Write-Progress -Id 0 -Activity "Fetching alerts" -Status $sub -PercentComplete ($i / $subscriptions.Count * 100);
        $i = $i++;
        $alerts = az security alert list `
            --subscription $sub `
        | ConvertFrom-Json `
        | Where-Object { @("VM_AdaptiveApplicationControlLinuxViolationAudited", "VM_AdaptiveApplicationControlWindowsViolationAudited") -contains $_.alertType } `
        | Where-Object { $_.status -eq "Active" };
        foreach ($x in $alerts) {
            $allAlerts.Add($x) > $null;
        }
    }
    Write-Progress -Id 0 "Done" -Completed;
    
    function Get-Files {
        Param(
            $alert
        )
        if ($alert.alertType -eq "VM_AdaptiveApplicationControlLinuxViolationAudited") {
            $fileType = "executable";
        }
        else {
            $fileType = "exe";
        }
    
        $pattern = "Path: (.*?);";
        $str = $alert.extendedProperties.file;
    
        return $str `
            | Select-String -Pattern $pattern -AllMatches `
            | ForEach-Object { $_.Matches } `
            | ForEach-Object { $_.Value } `
            | ForEach-Object { [pscustomobject]@{
                path = $_
                type = $fileType
            }};
    }
    
    
    $alertGroups = $allAlerts | Select-Object *, @{Name = "groupName"; Expression = { $_.extendedProperties.groupName } } | Group-Object groupName;
    foreach ($group in $alertGroups) {
        $groupName = $group.Name;
        $group.Group[0].id -match "/subscriptions/([^/]+)/" > $null;
        $subscriptionId = $matches[1];
        $files = $group.Group | ForEach-Object { Get-Files $_ };
        Write-Host "Adding file path rule sub=$subscriptionId group=$groupName count=$($files.Count)";
        Add-NewRules $subscriptionId $groupName $files;
    }
    

Please signup or login to give your own answer.
Back To Top
Search