FalconForce unknown stable kql

AWS Resource Shared with Unknown External Account

This query searches for resources being shared with an external AWS account that is not on a list of known trusted accounts.

View Source

Detection Logic

let timeframe = 2*1h;
let RuleId = "0236";
let DedupFields = dynamic(["TimeGenerated", "UserAccount"]);
let TrustedAccounts= dynamic([]);
let SharingEvents=(
    AWSCloudTrail
| where ingestion_time() >= ago(timeframe)
| where EventName in ("ModifyImageAttribute","ModifySnapshotAttribute","ModifyDBSnapshotAttribute","PutBucketPolicy")
        or (EventSource == "lambda.amazonaws.com" and EventName startswith "AddPermission")
);
let ImageSharing=(
    SharingEvents
| where EventName == "ModifyImageAttribute"
| mv-expand LaunchPermission=parse_json(RequestParameters).launchPermission
| mv-expand AddItem=LaunchPermission.add.items
| extend AddedAccount = AddItem.userId
| extend SharedGroup = AddItem.group
| extend SharedResourceId = parse_json(RequestParameters).imageId
);
let SnapshotSharing=(
    SharingEvents
| where EventName == "ModifySnapshotAttribute"
| mv-expand CreateVolumePermission=parse_json(RequestParameters).createVolumePermission
| mv-expand AddItem=CreateVolumePermission.add.items
| extend AddedAccount=AddItem.userId
| extend SharedResourceId = parse_json(RequestParameters).snapshotId
);
 let DBSnapshotSharing=(
    SharingEvents
| where EventName == "ModifyDBSnapshotAttribute"
| where parse_json(RequestParameters).attributeName =~ "restore"
| mv-expand AddedAccount=parse_json(RequestParameters).valuesToAdd
| extend SharedResourceId = parse_json(RequestParameters).dBSnapshotIdentifier
);
let BucketSharing=(
    SharingEvents
| where EventName == "PutBucketPolicy"
| extend BucketPolicy=parse_json(RequestParameters).bucketPolicy
| mv-expand  Statement=BucketPolicy.Statement
| where Statement.Effect =~ "Allow"
| mv-expand AddedAccount=Statement.Principal.AWS
);
let LambdaSharing=(
    SharingEvents
| where EventName startswith "AddPermission"
| extend RequestParameters=parse_json(RequestParameters)
| where RequestParameters.action == "lambda:InvokeFunction"
| extend AddedAccount=RequestParameters.principal
);
union ImageSharing, SnapshotSharing, DBSnapshotSharing, BucketSharing, LambdaSharing
| extend AddedAccount=iif(AddedAccount contains "*", "*", AddedAccount)
| extend AddedAccount=iif(AddedAccount startswith "arn:", split(AddedAccount, ":")[4], AddedAccount)
| where not(isempty(AddedAccount))
| where not(AddedAccount == UserIdentityAccountId)
| where not(AddedAccount in (TrustedAccounts))
// Excluding AWS services as external accounts, anything in the pattern of ".amazonaws.com"
| where not(AddedAccount endswith ".amazonaws.com")
// Begin environment-specific filter.
// End environment-specific filter.
| extend UserAccount=tostring(split(UserIdentityArn, "/")[-1])
// Begin de-duplication logic.
| extend DedupFieldValues=pack_all()
| mv-apply e=DedupFields to typeof(string) on (
    extend DedupValue=DedupFieldValues[tostring(e)]
| order by e // Sorting is required to ensure make_list is deterministic.
| summarize DedupValues=make_list(DedupValue)
)
| extend DedupEntity=strcat_array(DedupValues, "
| ")
| project-away DedupFieldValues, DedupValues
| join kind=leftanti (
    SecurityAlert
| where AlertName has RuleId and ProviderName has "ASI"
| where TimeGenerated >= ago(timeframe)
| extend DedupEntity = tostring(parse_json(tostring(parse_json(ExtendedProperties)["Custom Details"])).DedupEntity[0])
| project DedupEntity
) on DedupEntity
// End de-duplication logic.

Field Validations

Loading…

Comments (0)

Loading comments...