From 867c3dff5252240f1128e5ff450dde246c3fa162 Mon Sep 17 00:00:00 2001 From: Sol Fisher Romanoff Date: Sat, 2 Sep 2023 16:29:20 +0300 Subject: [PATCH] Add port scanning --- cmd/assets.go | 4 +++ cmd/ports.go | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++ config.go | 8 ++++-- main.go | 4 +++ 4 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 cmd/ports.go diff --git a/cmd/assets.go b/cmd/assets.go index 4a6bdde..115e467 100644 --- a/cmd/assets.go +++ b/cmd/assets.go @@ -17,3 +17,7 @@ var directorystyle = lipgloss.NewStyle(). var dnsstyle = lipgloss.NewStyle(). Bold(true). Underline(true) + +var portstyle = lipgloss.NewStyle(). + Bold(true). + Underline(true) diff --git a/cmd/ports.go b/cmd/ports.go new file mode 100644 index 0000000..e49c5c0 --- /dev/null +++ b/cmd/ports.go @@ -0,0 +1,80 @@ +package cmd + +import ( + "bufio" + "fmt" + "net" + "net/http" + "os" + "strconv" + "strings" + "time" + + "github.com/charmbracelet/log" +) + +const commonPorts = "https://raw.githubusercontent.com/pushfs/sif-runtime/main/ports/top-ports.txt" + +func Ports(scope string, url string, timeout time.Duration, logdir string) { + fmt.Println(separator.Render("🚪 Starting " + statusstyle.Render("port scanning") + "...")) + + sanitizedURL := strings.Split(url, "://")[1] + if logdir != "" { + f, err := os.OpenFile(logdir+"/"+sanitizedURL+".log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) + if err != nil { + log.Errorf("Error creating log file: %s", err) + return + } + defer f.Close() + f.WriteString(fmt.Sprintf("\n\n--------------\nStarting %s port scanning\n--------------\n", scope)) + } + + portlog := log.NewWithOptions(os.Stderr, log.Options{ + Prefix: "Ports 🚪", + }) + + portlog.Infof("Starting %s port scanning", scope) + + var ports []int + switch scope { + case "common": + resp, err := http.Get(commonPorts) + if err != nil { + log.Errorf("Error downloading ports list: %s", err) + return + } + scanner := bufio.NewScanner(resp.Body) + scanner.Split(bufio.ScanLines) + for scanner.Scan() { + if port, err := strconv.Atoi(scanner.Text()); err == nil { + ports = append(ports, port) + } + } + case "full": + ports = make([]int, 65536) + for i := range ports { + ports[i] = i + } + default: + log.Errorf("Invalid ports scope %s. Please choose either common or full", portstyle.Render(scope)) + return + } + + for _, port := range ports { + log.Debugf("Looking up: %d", port) + tcp, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", sanitizedURL, port), timeout) + if err != nil { + log.Debugf("Error %d: %v", port, err) + } else { + portlog.Infof("%s %s:%s", statusstyle.Render("[tcp]"), sanitizedURL, portstyle.Render(strconv.Itoa(port))) + tcp.Close() + } + udp, err := net.DialTimeout("udp", fmt.Sprintf("%s:%d", sanitizedURL, port), timeout) + if err != nil { + log.Debugf("Error %d: %v", port, err) + } else { + portlog.Infof("%s %s:%s", statusstyle.Render("[udp]"), sanitizedURL, portstyle.Render(strconv.Itoa(port))) + defer udp.Close() + } + } +} diff --git a/config.go b/config.go index 24efc48..cdf26bb 100644 --- a/config.go +++ b/config.go @@ -16,20 +16,20 @@ type Settings struct { Debug bool LogDir string NoScan bool + Ports string Timeout time.Duration } func parseURLs() Settings { var debug = pflag.BoolP("debug", "d", false, "Enable debug logging") - var timeout = pflag.DurationP("timeout", "t", 10*time.Second, "General http timeout value - Default is 10 seconds") - var logdir = pflag.StringP("log", "l", "", "Directory to store logs") - var url = pflag.StringArrayP("url", "u", []string{}, "URL to check") var file = pflag.StringP("file", "f", "", "File that includes URLs to check") var dirlist = pflag.String("dirlist", "none", "Directory fuzzing scan size (small, medium, large)") var dnslist = pflag.String("dnslist", "none", "DNS fuzzing scan size (small, medium, large)") + var ports = pflag.StringP("ports", "p", "none", "Scan common ports") + pflag.Lookup("ports").NoOptDefVal = "common" var noscan = pflag.Bool("noscan", false, "Do not perform base URL (robots.txt, etc) scanning") pflag.Parse() @@ -41,6 +41,7 @@ func parseURLs() Settings { Dnslist: *dnslist, NoScan: *noscan, URLs: *url, + Ports: *ports, LogDir: *logdir, } } else if *file != "" { @@ -68,6 +69,7 @@ func parseURLs() Settings { Dirlist: *dirlist, Dnslist: *dnslist, NoScan: *noscan, + Ports: *ports, URLs: urls, LogDir: *logdir, } diff --git a/main.go b/main.go index 9a5d638..d2baa45 100644 --- a/main.go +++ b/main.go @@ -90,6 +90,10 @@ func main() { cmd.Dnslist(settings.Dnslist, url, settings.Timeout, settings.LogDir) } + if settings.Ports != "none" { + cmd.Ports(settings.Ports, url, settings.Timeout, settings.LogDir) + } + // TODO: WHOIS fmt.Println()