Skip to content

Commit

Permalink
initial code commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jay-ball-zocdoc committed Jun 13, 2018
1 parent 4f4e6cb commit 3b1352f
Show file tree
Hide file tree
Showing 13 changed files with 474 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .gitigore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
80 changes: 80 additions & 0 deletions EC2-auto-terminate/Backdoor_Shutdown_Lambda.py
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)
69 changes: 69 additions & 0 deletions EC2-auto-terminate/README.md
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
*/
26 changes: 26 additions & 0 deletions EC2-auto-terminate/gd-cloudwatch-rules.json
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"
]
}
}

98 changes: 98 additions & 0 deletions EC2-auto-terminate/test-event-1-positive.json
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."
}
}
9 changes: 9 additions & 0 deletions S3-auto-encypt/README.md
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.




41 changes: 41 additions & 0 deletions S3-auto-encypt/s3-bucket-encrypt-lambda.py
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

18 changes: 18 additions & 0 deletions S3-auto-encypt/s3-cloudwatch-config.json
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 added security-group-auto-update/.DS_Store
Binary file not shown.
8 changes: 8 additions & 0 deletions security-group-auto-update/README.md
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.



Loading

0 comments on commit 3b1352f

Please sign in to comment.