Add exceptions for file paths from azure defender to adaptive application security controls

277 views Asked by At

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

There are 2 answers

0
TeamDman On 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;
}