Finding all Vulnerable Security groups in AWS using golang

Aravindhan
Lynk Miles
Published in
2 min readApr 15, 2019

Security is very important for any AWS infrastructure. Security groups are essential component for AWS security. Security group acts a virtual firewall for all instances and services (RDS, Elasticache etc.). Security groups provides ingress and egress permissions for an instance. Generally public access is provided to HTTP (80) and HTTPS (443) ports. Additionally SMTP ports 25, 465, 587 can also have public access. Any other ports should be restricted to internal security groups or internal IP addresses.

Script in golang

New let us look at the script to get all vulnerable security groups. As discussed, we need to find all security groups which has ports other than 80, 443, 25, 465 and 587 exposed to public. Let us use aws-sdk-go to get all the vulnerable security groups:

package main

import (
"log"
"os"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
)

func main() {
svc := ec2.New(session.New())
var maxResults int64
maxResults = 500
var nextToken string
for {
descSGInput := &ec2.DescribeSecurityGroupsInput{
MaxResults: aws.Int64(maxResults),
}

if nextToken != "" {
descSGInput.NextToken = aws.String(nextToken)
}

descSGOut, err := svc.DescribeSecurityGroups(descSGInput)
if err != nil {
log.Println("Unable to get security groups. Err:", err)
os.Exit(1)
}

for _, sg := range descSGOut.SecurityGroups {
for _, ingress := range sg.IpPermissions {
if (ingress.FromPort != nil && *ingress.FromPort == 80 && *ingress.ToPort == 80) ||
(ingress.ToPort != nil && *ingress.FromPort == 443 && *ingress.ToPort == 443) ||
(ingress.ToPort != nil && *ingress.FromPort == 25 && *ingress.ToPort == 25) ||
(ingress.ToPort != nil && *ingress.FromPort == 465 && *ingress.ToPort == 465) ||
(ingress.ToPort != nil && *ingress.FromPort == 587 && *ingress.ToPort == 587) {
continue
}

if len(ingress.IpRanges) > 0 {
for _, ipRange := range ingress.IpRanges {
if *ipRange.CidrIp == "0.0.0.0/0" {
var fromPort, toPort int64
if ingress.FromPort != nil {
fromPort = *ingress.FromPort
}

if ingress.ToPort != nil {
toPort = *ingress.ToPort
}

log.Printf(`Unsafe security group. ID: %s , Name: %s, FromPort: %d, ToPort: %d`,
*sg.GroupId, *sg.GroupName,
fromPort, toPort)
}
}
}
}
}

if descSGOut.NextToken != nil {
nextToken = *descSGOut.NextToken
} else {
break
}
}
}

The following environmental variables are set before running the script.

  • AWS_ACCESS_KEY_ID - Access key ID from you IAM user credentials.
  • AWS_SECRET_ACCESS_KEY - Secret Key ID from your IAM user credentials.
  • AWS_REGION - AWS region to clean up the security group

To run script:

go run main.go

Originally published at https://www.fenixara.com on April 15, 2019.

--

--

Aravindhan
Lynk Miles

Aravindhan leads engineering at Radar Ventures. Passionate about microservices, Kubernetes, and containers. Avid gamer.