/
scanner.go
164 lines (147 loc) · 4.36 KB
/
scanner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/lair-framework/go-nmap"
"os/exec"
)
type Instance struct {
name string
ip string
dns string
securityGroups []*ec2.GroupIdentifier
rawXmlScanResult string
parsedXmlScanResult *nmap.NmapRun
NmapOpenPorts []OpenPort
SecurityGroupOpenPorts []OpenPort
}
type OpenPort struct {
Protocol string
Port int
Type string
}
func getName(tags []*ec2.Tag) string {
for _, element := range tags {
if *element.Key == "Name" {
return *element.Value
}
}
return ""
}
// Given instance object lets parse out important info
func parseInstanceInfo(inst *ec2.Instance) Instance {
instanceInfo := Instance{}
// Grab these pointers first and nil check them
ip := inst.PublicIpAddress
dns := inst.PublicDnsName
sg := inst.SecurityGroups
instanceInfo.name = getName(inst.Tags)
// Do nil checks or go explodes then deref to get values
if ip != nil {
instanceInfo.ip = *inst.PublicIpAddress
}
if dns != nil {
instanceInfo.dns = *inst.PublicDnsName
}
if sg != nil {
instanceInfo.securityGroups = inst.SecurityGroups
}
return instanceInfo
}
func scanHost(host *Instance) {
cmd := exec.Command("nmap", "-Pn", "-n", "-F", "--host-timeout", "300", "--open", "-T4", host.ip, "-oX", "-")
stdout, err := cmd.Output()
if err != nil {
println(err.Error())
return
}
host.rawXmlScanResult = string(stdout)
}
func parseOpenPorts(instance *Instance) {
if len(instance.parsedXmlScanResult.Hosts) > 0 {
fmt.Println("Open ports on host: ")
for _, host := range instance.parsedXmlScanResult.Hosts {
for _, ports := range host.Ports {
openPort := OpenPort{Protocol: ports.Protocol, Port: ports.PortId, Type: ports.Service.Name}
instance.NmapOpenPorts = append(instance.NmapOpenPorts, openPort)
//fmt.Println(instance.NmapOpenPorts)
//fmt.Printf("%+v\n", ports)
}
}
} else {
fmt.Println("No open ports found")
}
}
//func describeSecurityGroups(svc *ec2.EC2, groupId []*ec2.GroupIdentifier) {
func describeSecurityGroups(svc *ec2.EC2, instance *Instance) {
//groupId []*ec2.GroupIdentifier) {
//func describeSecurityGroups(svc string, groupId []string) {
//fmt.Printf("%+v\n", groupId)
for _, sgGroupId := range instance.securityGroups {
params := &ec2.DescribeSecurityGroupsInput{
GroupIds: []*string{
aws.String(*sgGroupId.GroupId),
},
}
//resp, err := svc.DescribeSecurityGroups(params)
resp, err := svc.DescribeSecurityGroups(params)
if err != nil {
panic(err)
}
//fmt.Printf("%+v\n", resp)
for _, openPorts := range resp.SecurityGroups[0].IpPermissions {
//openPort := OpenPort{Protocol: ports.Protocol, Port: ports.PortId, Type: ports.Service.Name}
//instance.NmapOpenPorts = append(instance.NmapOpenPorts, openPort)
//if openPorts.FromPort != nil {
// fmt.Println(*openPorts.FromPort)
//}
//if openPorts.ToPort != nil {
// fmt.Println(*openPorts.ToPort)
//}
//if openPorts.IpProtocol != nil {
// fmt.Println(*openPorts.IpProtocol)
//}
if openPorts.IpRanges != nil {
//fmt.Println("Ranges open for ports ", *openPorts.FromPort, "to", *openPorts.ToPort)
for _, ranges := range openPorts.IpRanges {
if *ranges.CidrIp == "0.0.0.0/0" {
fmt.Println("Found open SG, comparing...")
var port int
if openPorts.FromPort != nil {
port = *openPorts.FromPort
}
}
//fmt.Println(ranges)
}
}
// compare
}
}
}
func main() {
svc := ec2.New(session.New(), &aws.Config{Region: aws.String("us-east-1")})
// Call the DescribeInstances Operation
resp, err := svc.DescribeInstances(nil)
if err != nil {
panic(err)
}
fmt.Println("> Number of reservation sets: ", len(resp.Reservations))
for idx := range resp.Reservations {
for _, inst := range resp.Reservations[idx].Instances {
// for each instance lets parse out the info we want
instance := parseInstanceInfo(inst)
fmt.Println("Processing: ", instance.name, " (", instance.ip, ")")
scanHost(&instance)
instance.parsedXmlScanResult, err = nmap.Parse([]byte(instance.rawXmlScanResult))
if err != nil {
fmt.Println(err.Error())
return
}
parseOpenPorts(&instance)
describeSecurityGroups(svc, &instance)
//fmt.Println(instance.securityGroups)
}
}
}