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
}
}
}
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.