yellow.git


yellow

~ opinionated web scanning pipeline for pentesters in a hurry
git clone https://github.com/djnnvx/yellow.git
log | files | refs | archive | README | LICENSE

commit 71764cc2cd26586e847d20cd98b383ea6369e1f5
parent 0d91a3c92a05abe38a0ebeded7bf165e821a3a94
Author: djnn <[email protected]>
Date: Thu, 5 Dec 2024 15:29:43 +0900

feat(scan): adding runtime checks to speed up scans * adding check to see if web pannel is online * adding option to enable port scanning (disabled by default)

Diffstat:
Mcli/parser.go | 2++
Mcli/types.go | 4++++
Mhelpers/net.go | 28++++++++++++++++++++++++++++
Mscan/run.go | 44++++++++++++++++++++++++++++----------------

4 files changed, 62 insertions(+), 16 deletions(-)

diff --git a/cli/parser.go b/cli/parser.go
@@ -42,6 +42,7 @@ func GetParser(opts *StandardOptions) *cobra.Command {
 			scanOpts.SetRateLimit(opts.RateLimit)
 			scanOpts.SetWordlistPath(opts.WordlistPath)
 			scanOpts.SetForceInsecure(opts.UseHttpInsecure)
+			scanOpts.SetWithPortScan(opts.WithPortScan)
 
 			if opts.TargetFilePath == "" {
 				scanOpts.Run()
@@ -148,6 +149,7 @@ func GetParser(opts *StandardOptions) *cobra.Command {
 	scanCmd.Flags().StringVarP(&opts.OutDirName, "dir-name", "d", defaults.OutDirName, "Outfile directory name (if no target-file is specified, will also be target domain)")
 	scanCmd.Flags().StringVarP(&opts.Proxy, "proxy", "p", defaults.Proxy, "Proxy URL (used for the tools supporting it. Other will prompt a warning msg)")
 	scanCmd.Flags().BoolVarP(&opts.RunDry, "dry", "", defaults.RunDry, "Run a dry-run (test mode)")
+	scanCmd.Flags().BoolVarP(&opts.UseHttpInsecure, "with-port-scanning", "", defaults.WithPortScan, "enable port-scanning")
 	scanCmd.Flags().BoolVarP(&opts.UseHttpInsecure, "insecure", "k", defaults.UseHttpInsecure, "Ignore SSL warnings and force http")
 	scanCmd.Flags().Int32VarP(&opts.RateLimit, "rate-limit", "r", defaults.RateLimit, "Requests rate-limit (used for the tools supporting it. Other will prompt a warning msg)")
 	scanCmd.Flags().StringVarP(&opts.WordlistPath, "wordlist", "w", defaults.WordlistPath, "Wordlist to use")
diff --git a/cli/types.go b/cli/types.go
@@ -23,10 +23,14 @@ type StandardOptions struct {
 
 	// File containing list of targets (should be a list of IP Addresses or domains)
 	TargetFilePath string
+
+	// With port scanning
+	WithPortScan bool
 }
 
 func GetDefaultOptions() StandardOptions {
 	opts := StandardOptions{
+		WithPortScan:    false,
 		OutDirName:      "",
 		RunDry:          false,
 		Proxy:           "",
diff --git a/helpers/net.go b/helpers/net.go
@@ -1,10 +1,12 @@
 package helper
 
 import (
+	"crypto/tls"
 	"fmt"
 	"io/ioutil"
 	"net/http"
 	"net/url"
+
 	"os"
 	"strings"
 )
@@ -92,3 +94,29 @@ func CheckProxy(proxy string) {
 		fmt.Println("[+] No proxy has been set")
 	}
 }
+
+func HasUnavailableWebInterface(url string) bool {
+	url = strings.TrimSuffix(url, "/")
+
+	transport := GetHttpTransport()
+	transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
+
+	client := &http.Client{
+		Transport: transport,
+	}
+
+	req, err := http.NewRequest("GET", url, nil)
+	if err != nil {
+		return true
+	}
+	req.Header.Add("User-Agent", GetUserAgent())
+	resp, err := client.Do(req)
+	if err != nil {
+		return true
+	}
+
+	if resp == nil || resp.StatusCode >= http.StatusBadGateway {
+		return true
+	}
+	return false
+}
diff --git a/scan/run.go b/scan/run.go
@@ -14,6 +14,11 @@ type ScanOpts struct {
 	rateLimit     int32
 	wordlistPath  string
 	forceInsecure bool
+	withPortScan  bool
+}
+
+func (opts *ScanOpts) SetWithPortScan(data bool) {
+	opts.withPortScan = data
 }
 
 func (opts *ScanOpts) SetForceInsecure(data bool) {
@@ -103,7 +108,7 @@ func (opts ScanOpts) runNaabu() {
 }
 
 func (opts *ScanOpts) Run() {
-	fmt.Printf("\n[SCAN] domain: %s\n\n", opts.domain)
+	fmt.Printf("\n[SCAN] domain: %s\n", opts.domain)
 
 	/* make a directory with the domain name to organize results a bit */
 	fullPath := opts.scanPath + "/" + opts.domain
@@ -114,14 +119,14 @@ func (opts *ScanOpts) Run() {
 		}
 	}
 
-	/*
-
-	    oldScan := opts.scanPath
+	if opts.withPortScan {
+		oldScan := opts.scanPath
 		naabuScanFile := fullPath + "/open-ports-top-1000.txt"
 		opts.SetScanPath(naabuScanFile)
 
 		opts.runNaabu()
-	    opts.SetScanPath(oldScan) */
+		opts.SetScanPath(oldScan)
+	}
 
 	if opts.forceInsecure {
 		opts.SetDomain("http://" + opts.domain)
@@ -129,15 +134,22 @@ func (opts *ScanOpts) Run() {
 		opts.SetDomain("https://" + opts.domain)
 	}
 
-	opts.runSitemap()
-	opts.runRobots()
-	opts.runWappalyzerGo()
-
-	/*
-	   - gobuster
-	   - katana
-	   - nuclei
-	   - httpx
-	   - gowitness
-	*/
+	if !helper.HasUnavailableWebInterface(opts.domain) {
+
+		fmt.Printf("[SCAN %s] web panel online....running web scans\n", opts.domain)
+
+		opts.runSitemap()
+		opts.runRobots()
+		opts.runWappalyzerGo()
+
+		/*
+		   - gobuster
+		   - katana
+		   - nuclei
+		   - httpx
+		   - gowitness
+		*/
+	} else {
+		fmt.Printf("[SCAN %s] => no web panel online. skipping\n", opts.domain)
+	}
 }