From 0cbf30bdc6df9c87c8e047286671e268bc4091ed Mon Sep 17 00:00:00 2001 From: topscoder <86197446+topscoder@users.noreply.github.com> Date: Thu, 11 May 2023 11:25:39 +0200 Subject: [PATCH] Refactorings for life --- fourohme.go | 209 +++++------------------------------- go.mod | 2 +- libs/fourohme/header.go | 6 ++ libs/fourohme/input.go | 59 ++++++++++ libs/fourohme/networking.go | 54 ++++++++++ libs/fourohme/request.go | 7 ++ libs/fourohme/utils.go | 54 ++++++++++ 7 files changed, 206 insertions(+), 185 deletions(-) create mode 100644 libs/fourohme/header.go create mode 100644 libs/fourohme/input.go create mode 100644 libs/fourohme/networking.go create mode 100644 libs/fourohme/request.go create mode 100644 libs/fourohme/utils.go diff --git a/fourohme.go b/fourohme.go index a1cd340..9f0806f 100644 --- a/fourohme.go +++ b/fourohme.go @@ -27,32 +27,18 @@ For example: cat domains.txt | httpx -silent -mc 401,402,403,404,405 | fourohme package main import ( - "bufio" - "flag" "fmt" - "net/http" "net/url" - "os" - "strings" "sync" -) - -type Header struct { - Key string - Value string -} -type Request struct { - Verb string - Url string - Headers []Header -} + "github.com/topscoder/fourohme/libs/fourohme" +) func main() { - urlPtr, filePtr, silentPtr, threadsPtr := parseCommandLineFlags() + urlPtr, filePtr, silentPtr, threadsPtr := fourohme.ParseCommandLineFlags() if !*silentPtr { - showBanner() + fourohme.ShowBanner() } headerKeysList := []string{ @@ -122,10 +108,10 @@ func main() { "0", } - var composedHeadersList []Header + var composedHeadersList []fourohme.Header for _, key := range headerKeysList { for _, value := range headerValuesList { - header := Header{Key: key, Value: value} + header := fourohme.Header{Key: key, Value: value} composedHeadersList = append(composedHeadersList, header) } } @@ -140,7 +126,7 @@ func main() { } // Let's Rock - urls := readUrlsFromInput(urlPtr, filePtr) + urls := fourohme.ReadUrlsFromInput(urlPtr, filePtr) for _, pUrl := range urls { parsedURL, err := url.Parse(pUrl) @@ -150,75 +136,75 @@ func main() { // Try each header in composedHeadersList var wg sync.WaitGroup - ch := make(chan Request, *threadsPtr) + ch := make(chan fourohme.Request, *threadsPtr) for _, header := range composedHeadersList { wg.Add(1) - var headerList []Header + var headerList []fourohme.Header headerList = append(headerList, header) - request := Request{Verb: "GET", Url: pUrl, Headers: headerList} + request := fourohme.Request{Verb: "GET", Url: pUrl, Headers: headerList} ch <- request - go talkHttpBaby(ch, &wg) + go fourohme.TalkHttpBaby(ch, &wg) } // Try each header with %URL% variable for _, headerKey := range headerKeysList { wg.Add(1) - var headerList []Header - header := Header{Key: headerKey, Value: pUrl} + var headerList []fourohme.Header + header := fourohme.Header{Key: headerKey, Value: pUrl} headerList = append(headerList, header) - request := Request{Verb: "GET", Url: pUrl, Headers: headerList} + request := fourohme.Request{Verb: "GET", Url: pUrl, Headers: headerList} ch <- request - go talkHttpBaby(ch, &wg) + go fourohme.TalkHttpBaby(ch, &wg) } - sUrl, sPath := getHostAndPath(parsedURL) + sUrl, sPath := fourohme.GetHostAndPath(parsedURL) // Try each header with %PATH% variable for _, headerKey := range headerKeysList { wg.Add(1) - var headerList []Header - header := Header{Key: headerKey, Value: sPath} + var headerList []fourohme.Header + header := fourohme.Header{Key: headerKey, Value: sPath} headerList = append(headerList, header) - request := Request{Verb: "GET", Url: pUrl, Headers: headerList} + request := fourohme.Request{Verb: "GET", Url: pUrl, Headers: headerList} ch <- request - go talkHttpBaby(ch, &wg) + go fourohme.TalkHttpBaby(ch, &wg) } // Try each URL payload in urlPayloadsList - var headerList []Header + var headerList []fourohme.Header for _, payload := range urlPayloadsList { wg.Add(1) loadedUrl := fmt.Sprintf("%s%s%s", sUrl, sPath, payload) - request := Request{Verb: "GET", Url: loadedUrl, Headers: headerList} + request := fourohme.Request{Verb: "GET", Url: loadedUrl, Headers: headerList} ch <- request - go talkHttpBaby(ch, &wg) + go fourohme.TalkHttpBaby(ch, &wg) } // Try with different HTTP Verbs for _, verb := range httpVerbsList { wg.Add(1) - request := Request{Verb: verb, Url: pUrl, Headers: headerList} + request := fourohme.Request{Verb: verb, Url: pUrl, Headers: headerList} ch <- request - go talkHttpBaby(ch, &wg) + go fourohme.TalkHttpBaby(ch, &wg) } close(ch) @@ -227,148 +213,3 @@ func main() { fmt.Println("") } } - -func talkHttpBaby(ch chan Request, wg *sync.WaitGroup) { - defer wg.Done() // Schedule the wg.Done() function call to be executed when the function returns - - request := <-ch - - statusCode := executeHttpRequest(request) - - printOutput(statusCode, request.Verb, request.Url, request.Headers) -} - -func executeHttpRequest(request Request) int { - verb := request.Verb - url := request.Url - headers := request.Headers - - req := createRequest(verb, url) - - if req == nil { - return -1 - } - - for _, header := range headers { - req.Header.Add(header.Key, header.Value) - } - - resp, err := http.DefaultClient.Do(req) - if err != nil { - fmt.Println(err) - resp.Body.Close() - return -1 - } - - resp.Body.Close() - return resp.StatusCode -} - -func parseCommandLineFlags() (*string, *string, *bool, *int) { - urlPtr := flag.String("url", "", "URL to make requests to") - filePtr := flag.String("file", "", "Path to a file containing URLs") - silentPtr := flag.Bool("silent", false, "Don't print shizzle. Only what matters.") - threadsPtr := flag.Int("threads", 4, "The amount of threads to be used to execute the HTTP requests. Be gentle or get blocked.") - flag.Parse() - - return urlPtr, filePtr, silentPtr, threadsPtr -} - -func readUrlsFromInput(urlPtr, filePtr *string) []string { - var urls []string - - urls = readUrlsFromStdin() - - if urls != nil { - return urls - } - - if *filePtr != "" { - urls = readUrlsFromFile(*filePtr) - } else if *urlPtr != "" { - urls = strings.Split(*urlPtr, ",") - } - - return urls -} - -func readUrlsFromStdin() []string { - stat, _ := os.Stdin.Stat() - if (stat.Mode() & os.ModeCharDevice) == 0 { - // Read from stdin - urls := make([]string, 0) - scanner := bufio.NewScanner(os.Stdin) - for scanner.Scan() { - urls = append(urls, scanner.Text()) - } - - return urls - } - - return nil -} - -func readUrlsFromFile(filepath string) []string { - file, err := os.Open(filepath) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - defer file.Close() - - var urls []string - scanner := bufio.NewScanner(file) - for scanner.Scan() { - urls = append(urls, scanner.Text()) - } - - return urls -} - -func getHostAndPath(parsedURL *url.URL) (string, string) { - sUrl := parsedURL.Scheme + "://" + parsedURL.Host - sPath := parsedURL.Path - if sPath == "" { - sPath = "/" - } - - return sUrl, sPath -} - -func createRequest(verb string, pUrl string) *http.Request { - req, err := http.NewRequest(verb, pUrl, nil) - - if err != nil { - fmt.Println(err) - return nil - } - - return req -} - -func printOutput(statusCode int, verb string, url string, headers []Header) { - // Print in green if it's 200 - if statusCode == 200 { - fmt.Printf("\033[32m%d => HTTP %s %s %v\033[0m\n", statusCode, verb, url, headers) - } else { - fmt.Printf("\033[31m%d => HTTP %s %s %v\033[0m\n", statusCode, verb, url, headers) - } -} - -func showBanner() { - const banner = ` - - - ███████╗ ██████╗ ██╗ ██╗██████╗ ██████╗ ██╗ ██╗ ███╗ ███╗███████╗ - ██╔════╝██╔═══██╗██║ ██║██╔══██╗ ██╔═══██╗██║ ██║ ████╗ ████║██╔════╝ - █████╗ ██║ ██║██║ ██║██████╔╝ ██║ ██║███████║ ██╔████╔██║█████╗ - ██╔══╝ ██║ ██║██║ ██║██╔══██╗ ██║ ██║██╔══██║ ██║╚██╔╝██║██╔══╝ - ██║ ╚██████╔╝╚██████╔╝██║ ██║ ╚██████╔╝██║ ██║ ██║ ╚═╝ ██║███████╗ - ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ - - by @topscoder - - ` - - fmt.Println(banner) -} diff --git a/go.mod b/go.mod index 3739073..c630cb2 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/topscoder/fourohme -go 1.18 \ No newline at end of file +go 1.20 diff --git a/libs/fourohme/header.go b/libs/fourohme/header.go new file mode 100644 index 0000000..f5d5e46 --- /dev/null +++ b/libs/fourohme/header.go @@ -0,0 +1,6 @@ +package fourohme + +type Header struct { + Key string + Value string +} diff --git a/libs/fourohme/input.go b/libs/fourohme/input.go new file mode 100644 index 0000000..557ef53 --- /dev/null +++ b/libs/fourohme/input.go @@ -0,0 +1,59 @@ +package fourohme + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +func ReadUrlsFromInput(urlPtr, filePtr *string) []string { + var urls []string + + urls = readUrlsFromStdin() + + if urls != nil { + return urls + } + + if *filePtr != "" { + urls = readUrlsFromFile(*filePtr) + } else if *urlPtr != "" { + urls = strings.Split(*urlPtr, ",") + } + + return urls +} + +func readUrlsFromStdin() []string { + stat, _ := os.Stdin.Stat() + if (stat.Mode() & os.ModeCharDevice) == 0 { + // Read from stdin + urls := make([]string, 0) + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + urls = append(urls, scanner.Text()) + } + + return urls + } + + return nil +} + +func readUrlsFromFile(filepath string) []string { + file, err := os.Open(filepath) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer file.Close() + + var urls []string + scanner := bufio.NewScanner(file) + for scanner.Scan() { + urls = append(urls, scanner.Text()) + } + + return urls +} diff --git a/libs/fourohme/networking.go b/libs/fourohme/networking.go new file mode 100644 index 0000000..ccf69d8 --- /dev/null +++ b/libs/fourohme/networking.go @@ -0,0 +1,54 @@ +package fourohme + +import ( + "fmt" + "net/http" + "sync" +) + +func TalkHttpBaby(ch chan Request, wg *sync.WaitGroup) { + defer wg.Done() // Schedule the wg.Done() function call to be executed when the function returns + + request := <-ch + + statusCode := executeHttpRequest(request) + + printOutput(statusCode, request.Verb, request.Url, request.Headers) +} + +func executeHttpRequest(request Request) int { + verb := request.Verb + url := request.Url + headers := request.Headers + + req := createRequest(verb, url) + + if req == nil { + return -1 + } + + for _, header := range headers { + req.Header.Add(header.Key, header.Value) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + fmt.Println(err) + resp.Body.Close() + return -1 + } + + resp.Body.Close() + return resp.StatusCode +} + +func createRequest(verb string, pUrl string) *http.Request { + req, err := http.NewRequest(verb, pUrl, nil) + + if err != nil { + fmt.Println(err) + return nil + } + + return req +} diff --git a/libs/fourohme/request.go b/libs/fourohme/request.go new file mode 100644 index 0000000..bcad80e --- /dev/null +++ b/libs/fourohme/request.go @@ -0,0 +1,7 @@ +package fourohme + +type Request struct { + Verb string + Url string + Headers []Header +} diff --git a/libs/fourohme/utils.go b/libs/fourohme/utils.go new file mode 100644 index 0000000..6166bca --- /dev/null +++ b/libs/fourohme/utils.go @@ -0,0 +1,54 @@ +package fourohme + +import ( + "flag" + "fmt" + "net/url" +) + +func ParseCommandLineFlags() (*string, *string, *bool, *int) { + urlPtr := flag.String("url", "", "URL to make requests to") + filePtr := flag.String("file", "", "Path to a file containing URLs") + silentPtr := flag.Bool("silent", false, "Don't print shizzle. Only what matters.") + threadsPtr := flag.Int("threads", 4, "The amount of threads to be used to execute the HTTP requests. Be gentle or get blocked.") + flag.Parse() + + return urlPtr, filePtr, silentPtr, threadsPtr +} + +func GetHostAndPath(parsedURL *url.URL) (string, string) { + sUrl := parsedURL.Scheme + "://" + parsedURL.Host + sPath := parsedURL.Path + if sPath == "" { + sPath = "/" + } + + return sUrl, sPath +} + +func printOutput(statusCode int, verb string, url string, headers []Header) { + // Print in green if it's 200 + if statusCode == 200 { + fmt.Printf("\033[32m%d => HTTP %s %s %v\033[0m\n", statusCode, verb, url, headers) + } else { + fmt.Printf("\033[31m%d => HTTP %s %s %v\033[0m\n", statusCode, verb, url, headers) + } +} + +func ShowBanner() { + const banner = ` + + + ███████╗ ██████╗ ██╗ ██╗██████╗ ██████╗ ██╗ ██╗ ███╗ ███╗███████╗ + ██╔════╝██╔═══██╗██║ ██║██╔══██╗ ██╔═══██╗██║ ██║ ████╗ ████║██╔════╝ + █████╗ ██║ ██║██║ ██║██████╔╝ ██║ ██║███████║ ██╔████╔██║█████╗ + ██╔══╝ ██║ ██║██║ ██║██╔══██╗ ██║ ██║██╔══██║ ██║╚██╔╝██║██╔══╝ + ██║ ╚██████╔╝╚██████╔╝██║ ██║ ╚██████╔╝██║ ██║ ██║ ╚═╝ ██║███████╗ + ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ + + by @topscoder + + ` + + fmt.Println(banner) +}