Finding all Vulnerable Security groups in AWS using golang
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
}
}
}