package recon import ( "net" "sort" "strconv" "strings" "time" ) const ( PortProfileWeb = "web" PortProfileWindows = "windows" PortProfileLinux = "linux" PortProfileCloudMetadata = "cloud_metadata" ) var portProfilePorts = map[string][]int{ PortProfileWeb: {80, 443, 6262}, PortProfileWindows: {445, 5985, 3389}, PortProfileLinux: {22}, } var dialPortFn func(host string, port int, timeout time.Duration) bool func ScanPorts(host string, ports []int) []PortResult { if len(ports) == 0 { ports = FleetPorts } out := make([]PortResult, 0, len(ports)) for _, port := range ports { out = append(out, PortResult{Port: port, Open: dialPort(host, port, DefaultPortDialTimeout)}) } return out } func dialPort(host string, port int, timeout time.Duration) bool { if dialPortFn != nil { return dialPortFn(host, port, timeout) } conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, strconv.Itoa(port)), timeout) if err != nil { return false } _ = conn.Close() return true } func ResolveScanPortsFromRequest(req ScanRequest) ([]int, []string) { return ResolveScanPorts(req.Profiles) } func ResolveScanPorts(profiles []string) ([]int, []string) { seen := map[int]bool{} var ports []int for _, p := range FleetPorts { if !seen[p] { seen[p] = true ports = append(ports, p) } } var used []string for _, raw := range profiles { name := strings.ToLower(strings.TrimSpace(raw)) if name == "" { continue } if name == PortProfileCloudMetadata { if !containsPortProfile(used, name) { used = append(used, name) } continue } bundle, ok := portProfilePorts[name] if !ok { continue } if !containsPortProfile(used, name) { used = append(used, name) } for _, p := range bundle { if !seen[p] { seen[p] = true ports = append(ports, p) } } } sort.Ints(ports) return ports, used } func containsPortProfile(list []string, want string) bool { for _, s := range list { if s == want { return true } } return false } func TargetLooksEC2(host string) bool { host = strings.ToLower(strings.TrimSpace(host)) if host == "" { return false } if host == "169.254.169.254" { return true } return strings.Contains(host, ".compute.amazonaws.com") || strings.Contains(host, ".compute.internal") || strings.HasPrefix(host, "ip-10-") || strings.HasPrefix(host, "ec2-") }