Skip to content

Commit

Permalink
Refactorings for life
Browse files Browse the repository at this point in the history
  • Loading branch information
topscoder committed May 11, 2023
1 parent 4eb8f42 commit 0cbf30b
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 185 deletions.
209 changes: 25 additions & 184 deletions fourohme.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down Expand Up @@ -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)
}
}
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/topscoder/fourohme

go 1.18
go 1.20
6 changes: 6 additions & 0 deletions libs/fourohme/header.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package fourohme

type Header struct {
Key string
Value string
}
59 changes: 59 additions & 0 deletions libs/fourohme/input.go
Original file line number Diff line number Diff line change
@@ -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
}
Loading

0 comments on commit 0cbf30b

Please sign in to comment.