-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4f4e6cb
commit 3b1352f
Showing
13 changed files
with
474 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Backdoor_Shutdown_Lambda.py || part of ZocSec.SecurityAsCode.AWS | ||
# | ||
# An AWS Lambda for terminating EC2 instances for which GuardDuty detects malware. | ||
# | ||
# Owner: Copyright 2018 Zocdoc Inc. www.zocdoc.com | ||
# Author: Jay Ball @veggiespam | ||
# | ||
|
||
import boto3 | ||
from botocore.exceptions import ClientError | ||
import json | ||
|
||
def lambda_handler(event, context): | ||
print("Event is: ", json.dumps(event)) | ||
|
||
source = event['source'] | ||
if source != "aws.guardduty": | ||
# wrong caller, just silently return | ||
print("Wrong Filter on CW Events, source=", source) | ||
return | ||
|
||
detail_type = event['detail-type'] | ||
if detail_type != 'GuardDuty Finding': | ||
# wrong caller, just silently return | ||
print("Wrong Filter on CW Events, source=", source, " / detail_type=", detail_type) | ||
return | ||
|
||
event_type = event['detail']['type'] | ||
|
||
# https://docs.aws.amazon.com/guardduty/latest/ug//guardduty_finding-types.html | ||
bad_event_list = [ | ||
'Backdoor:EC2/XORDDOS', | ||
'Backdoor:EC2/Spambot', | ||
'Backdoor:EC2/C&CActivity.B!DNS', | ||
'CryptoCurrency:EC2/BitcoinTool.B!DNS', | ||
'Trojan:EC2/BlackholeTraffic', | ||
'Trojan:EC2/DropPoint', | ||
'Trojan:EC2/BlackholeTraffic!DNS', | ||
'Trojan:EC2/DriveBySourceTraffic!DNS', | ||
'Trojan:EC2/DropPoint!DNS', | ||
'Trojan:EC2/DGADomainRequest.B', | ||
'Trojan:EC2/DGADomainRequest.C!DNS', | ||
'Trojan:EC2/DNSDataExfiltration', | ||
'Trojan:EC2/PhishingDomainRequest!DNS' ] | ||
|
||
if not(event_type in bad_event_list): | ||
# single event example: | ||
#if event_type != 'Backdoor:EC2/C&CActivity.B!DNS': | ||
print("We received the wrong event type: " , event_type) | ||
return | ||
|
||
# we will shut this one down | ||
instance_id = event['detail']['resource']['instanceDetails']['instanceId'] | ||
|
||
# only shutdown certain tags: | ||
taglist = event['detail']['resource']['instanceDetails']['tags'] | ||
runme=False | ||
|
||
for nvp in taglist: | ||
if "infosecadmin" == nvp['key'].lower(): | ||
runme=True | ||
|
||
if not(runme): | ||
print("We are not part of our auto-shutdown EC2 group") | ||
return | ||
|
||
|
||
print("Shutting down instance ", instance_id) | ||
|
||
ec2 = boto3.client('ec2') | ||
|
||
try: | ||
response = ec2.stop_instances(InstanceIds=[ instance_id ]) | ||
# ec2.reboot_instances(InstanceIds=['INSTANCE_ID'], DryRun=True) | ||
except ClientError as e: | ||
if 'DryRunOperation' not in str(e): | ||
print("You don't have permission to reboot instances.") | ||
raise | ||
else: | ||
print('Error', e) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# EC2 Malware Automated Termination | ||
|
||
*Part of the Zocdoc's ZocSec.SecurityAsCode initiative* | ||
|
||
This auto-termination script kills off an EC2 instance if GuardDuty detects that malware has infested a server. To install, follow these simple directions. | ||
|
||
# IAM Permissions | ||
|
||
First off, create a new IAM group so that we can the right permissions. Your Lambda will need access to perform EC2 calls and also to write information into logs (for auditing and debugging). | ||
|
||
1. Go to IAM | ||
1. Create a new role | ||
1. Choose the trust entity, AWS Service, with Lambda use case. | ||
1. Attach a policy for EC2, such as *AmazonEC2FullAccess* (or other as appropriate for your environment) | ||
1. Attach a policy for logging, such as *CloudWatchLogsFullAccess* (again, customize to your setup) | ||
1. Give it a name, we called ours `Backdoor_Shutdown_Role` | ||
1. And a description: "Role used by Infosec functions which will shut down of EC2 during security event. This is a high privileged role." | ||
|
||
|
||
# GuardDuty | ||
|
||
Be sure to active GuardDuty for your account. Make sure it has the right permissions. That's about it. Mine was already set properly. | ||
|
||
# Lambdas | ||
|
||
Now, code it up! Create a new Lambda and configure the events for it. | ||
|
||
1. Go to Lambda | ||
2. Create a new function: | ||
a. we called ours `Backdoor_Shutdown_Lambda` | ||
b. this is python 3.6 | ||
c. The role is Backdoor_Shutdown_Role | ||
3. Add the code from the [file Backdoor_Shutdown_Lambda.py](Backdoor_Shutdown_Lambda.py). | ||
4. Add a test event, which we called `BackdoorDNSTrigger` loaded [from this file](test-event-1-positive.json). | ||
5. Click Test to see if it works {hint: you'll get "Instance not found" error message}. | ||
|
||
|
||
# Cloud Watch Events | ||
|
||
First off, did the Lambda properly send its audit logs to CloudWatch? If you see /aws/lambda/Backdoor_Shutdown_Lambda in your Log stream, then your permission to write to the logs is correct. | ||
|
||
Now, to configure out rule which scans Guard Duty and they fires the Lambda when needed. | ||
|
||
1. Go to CloudWatch | ||
1. Click on Events → Rules | ||
1. Create a new rule | ||
1. Do an Event Pattern and choose "Build custom event pattern" | ||
1. Edit the Pattern use the information found in the file [gd-cloudwatch-rules.json](gd-cloudwatch-rules.json). | ||
|
||
Now, add the target | ||
|
||
1. Choose Lambda Function | ||
1. Pick the Backdoor_Shutdown_Lambda that we created earlier | ||
1. Go to the next screen with "Configure Details" | ||
1. Give it a name, we called ours `GuardDuty_Backdoor_Alerts_Force_EC2_Shudown` | ||
1. Add a Description, such as: "Infosec rule executes EC2 shutdown Lambda when GuardDuty detects Backdoor on instance." | ||
|
||
# Test It! | ||
|
||
To test, `ssh` into the machine. Then, run the test canary: | ||
|
||
``` | ||
dig guarddutyc2activityb.com any | ||
``` | ||
|
||
This triggers CloudWatch to call the Lambda to shut down the server. Please note that GuardDuty and CloudWatch can have lag between the running of the test and when the machine is shutdown, please see the documentation on both for further information. | ||
|
||
/* vim: spell expandtab | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"source": [ | ||
"aws.guardduty" | ||
], | ||
"detail-type": [ | ||
"GuardDuty Finding" | ||
], | ||
"detail": { | ||
"type": [ | ||
"Backdoor:EC2/XORDDOS", | ||
"Backdoor:EC2/Spambot", | ||
"Backdoor:EC2/C&CActivity.B!DNS", | ||
"CryptoCurrency:EC2/BitcoinTool.B!DNS", | ||
"Trojan:EC2/BlackholeTraffic", | ||
"Trojan:EC2/DropPoint", | ||
"Trojan:EC2/BlackholeTraffic!DNS", | ||
"Trojan:EC2/DriveBySourceTraffic!DNS", | ||
"Trojan:EC2/DropPoint!DNS", | ||
"Trojan:EC2/DGADomainRequest.B", | ||
"Trojan:EC2/DGADomainRequest.C!DNS", | ||
"Trojan:EC2/DNSDataExfiltration", | ||
"Trojan:EC2/PhishingDomainRequest!DNS" | ||
] | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
{ | ||
"Test_Event_Name": "BackdoorDNSTrigger", | ||
"Test_Event_Desc": "Test Event: Backdoor trigger: Backdoor:EC2/C&CActivity.B!DNS", | ||
"version": "0", | ||
"id": "6d4fe264-d8dd-1628-b4aa-c71a18ca404e", | ||
"detail-type": "GuardDuty Finding", | ||
"source": "aws.guardduty", | ||
"account": "033074250527", | ||
"time": "2018-05-23T15:25:01Z", | ||
"region": "us-east-1", | ||
"resources": [], | ||
"detail": { | ||
"schemaVersion": "2.0", | ||
"accountId": "033074250527", | ||
"region": "us-east-1", | ||
"partition": "aws", | ||
"id": "feb1c6cb00b54c86a82635a284e89e32", | ||
"arn": "arn:aws:guardduty:us-east-1:033074250527:detector/acb1127c34e6d8328167ca25c2b85ea4/finding/feb1c6cb00b54c86a82635a284e89e32", | ||
"type": "Backdoor:EC2/C&CActivity.B!DNS", | ||
"resource": { | ||
"resourceType": "Instance", | ||
"instanceDetails": { | ||
"instanceId": "i-0238a54270332d4c8", | ||
"instanceType": "t2.micro", | ||
"launchTime": "2018-05-23T14:22:55Z", | ||
"platform": "None", | ||
"productCodes": [], | ||
"iamInstanceProfile": { | ||
"arn": "arn:aws:iam::033074250527:instance-profile/InfoSecAdmin", | ||
"id": "AIPAIDMDC6J3EGQA7KZNO" | ||
}, | ||
"networkInterfaces": [ | ||
{ | ||
"ipv6Addresses": [], | ||
"networkInterfaceId": "eni-21fa15b0", | ||
"privateDnsName": "None", | ||
"privateIpAddress": "172.16.0.88", | ||
"privateIpAddresses": [ | ||
{ | ||
"privateDnsName": "None", | ||
"privateIpAddress": "172.16.0.88" | ||
} | ||
], | ||
"subnetId": "subnet-428aec09", | ||
"vpcId": "vpc-17305c6f", | ||
"securityGroups": [ | ||
{ | ||
"groupName": "launch-wizard-11", | ||
"groupId": "sg-08c8aa40" | ||
} | ||
], | ||
"publicDnsName": "", | ||
"publicIp": "34.224.97.157" | ||
} | ||
], | ||
"tags": [ | ||
{ | ||
"key": "InfoSecAdmin", | ||
"value": "Test" | ||
}, | ||
{ | ||
"key": "Name", | ||
"value": "Infosec-Jay-Test-VM" | ||
} | ||
], | ||
"instanceState": "running", | ||
"availabilityZone": "us-east-1a", | ||
"imageId": "ami-14c5486b", | ||
"imageDescription": "Amazon Linux AMI 2018.03.0.20180508 x86_64 HVM GP2" | ||
} | ||
}, | ||
"service": { | ||
"serviceName": "guardduty", | ||
"detectorId": "acb1127c34e6d8328167ca25c2b85ea4", | ||
"action": { | ||
"actionType": "DNS_REQUEST", | ||
"dnsRequestAction": { | ||
"domain": "guarddutyc2activityb.com", | ||
"protocol": "UDP", | ||
"blocked": false | ||
} | ||
}, | ||
"resourceRole": "TARGET", | ||
"additionalInfo": { | ||
"threatListName": "TestDomain" | ||
}, | ||
"eventFirstSeen": "2018-05-23T14:42:26Z", | ||
"eventLastSeen": "2018-05-23T14:42:26Z", | ||
"archived": false, | ||
"count": "1" | ||
}, | ||
"severity": "8.0", | ||
"createdAt": "2018-05-23T15:20:08.298Z", | ||
"updatedAt": "2018-05-23T15:20:08.298Z", | ||
"title": "Command and Control server domain name queried by EC2 instance i-0238a54270332d4c8.", | ||
"description": "EC2 instance i-0238a54270332d4c8 is querying a domain name associated with a known Command & Control server." | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# S3 Automated Bucket Encryption | ||
|
||
*Part of the Zocdoc's ZocSec.SecurityAsCode initiative* | ||
|
||
Full readme coming soon. | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# s3-bucket-encrypt-lambda.py || part of ZocSec.SecurityAsCode.AWS | ||
# | ||
# An AWS Lambda for adding encryption to a bucket which had its encryption removed. | ||
# | ||
# Owner: Copyright 2018 Zocdoc Inc. www.zocdoc.com | ||
# Authors: Suved Adkar, Jay Ball @veggiespam | ||
# | ||
from __future__ import print_function | ||
import boto3 | ||
import json | ||
import logging | ||
from botocore.exceptions import ClientError | ||
|
||
|
||
#initialize the s3 client | ||
s3 = boto3.client('s3') | ||
|
||
#initialize the SNS client | ||
sns = boto3.client('sns') | ||
|
||
#define Lambda Fucntion. The event variable will pass the full CloudWatch event to this function | ||
def lambda_handler(event, context): | ||
#get bucket Name from event | ||
bucket_name = (event['detail']['requestParameters']['bucketName']) | ||
|
||
#get bucket Creators Name | ||
bucket_creator = (event['detail']['userIdentity']['principalId']) | ||
bucket_user = bucket_creator.split(":",1) | ||
|
||
|
||
|
||
#Get the buckets current encryption, if it errors, there is no Default Encryption on the bucket and we set the encryption wiith Put Bucket encryption, else do nothing! | ||
try: | ||
currEncrypt = s3.get_bucket_encryption (Bucket=bucket_name) | ||
except ClientError as e: | ||
toEncrypt = s3.put_bucket_encryption (Bucket=bucket_name,ServerSideEncryptionConfiguration={'Rules':[{'ApplyServerSideEncryptionByDefault': {'SSEAlgorithm': 'AES256'}}]}) | ||
message = 'An Unencrypted Bucketed was created by ' + bucket_user[1] + '.' + ' Default AES-256 encryption has been applied to the bucket'; | ||
response = sns.publish(TopicArn='arn:aws:sns:us-east-1:000123456:unEncryptedS3BucketCreated', Message = message) | ||
else: | ||
return currEncrypt | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"source": [ | ||
"aws.s3" | ||
], | ||
"detail-type": [ | ||
"AWS API Call via CloudTrail" | ||
], | ||
"detail": { | ||
"eventSource": [ | ||
"s3.amazonaws.com" | ||
], | ||
"eventName": [ | ||
"CreateBucket", | ||
"PutBucketAcl", | ||
"PutBucketPolicy" | ||
] | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Security Group Automated Excessive IP Range Correction | ||
|
||
*Part of the Zocdoc's ZocSec.SecurityAsCode initiative* | ||
|
||
Full readme coming soon. | ||
|
||
|
||
|
Oops, something went wrong.