Skip to content

Instantly share code, notes, and snippets.

@giuliocalzolari
Last active September 14, 2018 09:02
Show Gist options
  • Save giuliocalzolari/7325dfa3ff63cb2f83008a9c8feada32 to your computer and use it in GitHub Desktop.
Save giuliocalzolari/7325dfa3ff63cb2f83008a9c8feada32 to your computer and use it in GitHub Desktop.
AWS insecure Security Group Scanner
#!/usr/bin/env python
import boto3
import json
import sys
def find_public_addresses(ec2):
public_instances = {}
instance_public_ips = {}
instance_private_ips = {}
instance_ident = {}
instances = ec2.instances.filter(Filters=[{'Name': 'instance-state-name', 'Values': ['running'] }])
# Ranges that you define as public subnets in AWS go here.
public_subnet_ranges = ['10', '192.168', '172']
for instance in instances:
# I only care if the private address falls into a public subnet range
# because if it doesnt Internet ingress cant reach it directly anyway even with a public IP
if any(cidr in instance.private_ip_address for cidr in public_subnet_ranges):
owner_tag = "None"
instance_name = "None"
if instance.tags:
for i in range(len(instance.tags)):
#comment OwnerEmail tag out if you do not tag your instances with it.
if instance.tags[i]['Key'] == "OwnerEmail":
owner_tag = instance.tags[i]['Value']
if instance.tags[i]['Key'] == "Name":
instance_name = instance.tags[i]['Value']
instance_ident[instance.id] = "Name: %s\n\tKeypair: %s\n\tOwner: %s" % (instance_name, instance.key_name, owner_tag)
if instance.public_ip_address is not None:
values=[]
for i in range(len(instance.security_groups)):
values.append(instance.security_groups[i]['GroupId'])
public_instances[instance.id] = values
instance_public_ips[instance.id] = instance.public_ip_address
instance_private_ips[instance.id] = instance.private_ip_address
return (public_instances, instance_public_ips,instance_private_ips, instance_ident)
def inspect_security_group(ec2, sg_id):
sg = ec2.SecurityGroup(sg_id)
open_cidrs = []
for i in range(len(sg.ip_permissions)):
to_port = ''
ip_proto = ''
if 'ToPort' in sg.ip_permissions[i]:
to_port = sg.ip_permissions[i]['ToPort']
if 'IpProtocol' in sg.ip_permissions[i]:
ip_proto = sg.ip_permissions[i]['IpProtocol']
if '-1' in ip_proto:
ip_proto = 'All'
for j in range(len(sg.ip_permissions[i]['IpRanges'])):
if to_port in [80, 443]:
continue
cidr_string = "%s %s %s" % (sg.ip_permissions[i]['IpRanges'][j]['CidrIp'], ip_proto, to_port)
if sg.ip_permissions[i]['IpRanges'][j]['CidrIp'] == '0.0.0.0/0':
#preventing an instance being flagged for only ICMP being open
if ip_proto != 'icmp':
open_cidrs.append(cidr_string)
# print open_cidrs
# sys.exit(0)
return open_cidrs
if __name__ == "__main__":
with open("secrets.json") as file_config:
accounts = json.loads(file_config.read())
count = 0
for account, data in accounts.items():
# print data
regions = data.get("regions", boto3.session.Session().get_available_regions('ec2'))
for region in regions:
print "account {} in region {}".format(data["alias"],region)
ec2 = boto3.resource('ec2',
region_name=region,
aws_access_key_id=data["aws_access_key_id"],
aws_secret_access_key=data["aws_secret_access_key"])
for sg in ec2.meta.client.describe_security_groups()["SecurityGroups"]:
open_cidrs = inspect_security_group(ec2, sg["GroupId"])
if open_cidrs: #only print if there are open cidrs
print "\t=========================="
print "\t open ingress rules {}".format(sg["GroupName"])
print "\t=========================="
for cidr in open_cidrs:
print "\t\t" + cidr
{
"11111111111111": {
"alias": "account1",
"aws_access_key_id": "AAAAAAAAAAAAAAAAAA",
"aws_secret_access_key": "BBBBBBBBBBBBBBBBBBBBB",
"regions": ["eu-west-1"]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment