From cbb4718feeb26ad618cd7bfa58ebf4e8b85cfc05 Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Thu, 8 Aug 2024 20:15:06 +0200 Subject: [PATCH 1/4] refactor(matcher): adapt to parsing of cli for matching criteria simple immigration of models and use of multiple structs --- src/cli/cli.go | 5 ++--- src/main.go | 7 +++---- src/matching/body.go | 3 ++- src/matching/headers.go | 3 ++- src/matching/matcher.go | 18 ++++++------------ src/models/models.go | 10 +++++++--- src/query/callWorker.go | 3 +-- 7 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/cli/cli.go b/src/cli/cli.go index de4c535..2becae7 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -1,6 +1,7 @@ package cli import ( + "bruteforce/src/matching" "bruteforce/src/models" "errors" "flag" @@ -39,9 +40,7 @@ func Parse_cli_args() (models.Forcing_params, error) { } params.Url = flag.Args()[0] // params.BoolFlags.Verbose = *forkptr - params.Status = *statusPtr - params.Header = *headerPtr - params.Body = *bodyPtr + params.Criteria = matcher.MatchParser(*statusPtr, *headerPtr, *bodyPtr) params.Wordlist = *wordlistPtr if params.Wordlist == "" { return params, WordListError diff --git a/src/main.go b/src/main.go index 2061245..53c950e 100644 --- a/src/main.go +++ b/src/main.go @@ -2,7 +2,7 @@ package main import ( "bruteforce/src/cli" - "bruteforce/src/matching" + // "bruteforce/src/matching" "bruteforce/src/query" "fmt" ) @@ -16,7 +16,6 @@ func main() { } fmt.Println(forcing_params) - criteria := matcher.MatchParser(&forcing_params) - - query.MainRequest(&forcing_params, criteria) // maybe like this? + // matcher.MatchParser(&forcing_params) + query.MainRequest(&forcing_params) } diff --git a/src/matching/body.go b/src/matching/body.go index c6734b9..51563b7 100644 --- a/src/matching/body.go +++ b/src/matching/body.go @@ -1,11 +1,12 @@ package matcher import ( + "bruteforce/src/models" "errors" "strings" ) -func matchContents(body []byte, criteria MatchCriteria) (bool, error) { +func matchContents(body []byte, criteria models.MatchCriteria) (bool, error) { if criteria.BodyContains != "" && !strings.Contains(string(body), criteria.BodyContains) { return false, errors.New("body content mismatch") } diff --git a/src/matching/headers.go b/src/matching/headers.go index 88f2c09..7cdff1e 100644 --- a/src/matching/headers.go +++ b/src/matching/headers.go @@ -1,13 +1,14 @@ package matcher import ( + "bruteforce/src/models" "fmt" "log" "net/http" "strings" ) -func matchHeaders(resp *http.Response, criteria MatchCriteria) (bool, error) { +func matchHeaders(resp *http.Response, criteria models.MatchCriteria) (bool, error) { for key, value := range criteria.Headers { if resp.Header.Get(key) != value { return false, fmt.Errorf("header mismatch: %s=%s\nheaders: %s", key, value, resp.Header) diff --git a/src/matching/matcher.go b/src/matching/matcher.go index cf7d287..a330d48 100644 --- a/src/matching/matcher.go +++ b/src/matching/matcher.go @@ -7,13 +7,7 @@ import ( "net/http" ) -type MatchCriteria struct { - StatusCodes []int - Headers map[string]string - BodyContains string -} - -func MatchResponse(response *http.Response, criteria MatchCriteria) (bool, string) { +func MatchResponse(response *http.Response, criteria models.MatchCriteria) (bool, string) { body, err := io.ReadAll(response.Body) if err != nil { return false, err.Error() @@ -32,17 +26,17 @@ func MatchResponse(response *http.Response, criteria MatchCriteria) (bool, strin return true, "matched successfully" } -func MatchParser(params *models.Forcing_params) MatchCriteria { - matchCodes, err := parseStatusCodes(params.Status) +func MatchParser(statusPtr string, headerPtr string, bodyPtr string) models.MatchCriteria { + matchCodes, err := parseStatusCodes(statusPtr) if err != nil { log.Fatal("Error parsing status codes:", err) } - matchHeaders := parseHeaders(params.Header) - criteria := MatchCriteria{ + matchHeaders := parseHeaders(headerPtr) + criteria := models.MatchCriteria{ StatusCodes: matchCodes, Headers: matchHeaders, - BodyContains: params.Body, + BodyContains: bodyPtr, } return criteria diff --git a/src/models/models.go b/src/models/models.go index 7e173fa..e496d22 100644 --- a/src/models/models.go +++ b/src/models/models.go @@ -4,12 +4,16 @@ type boolflags struct { Verbose bool } +type MatchCriteria struct { + StatusCodes []int + Headers map[string]string + BodyContains string +} + type Forcing_params struct { Workers int Url string Wordlist string BoolFlags boolflags - Status string - Header string - Body string + Criteria MatchCriteria } diff --git a/src/query/callWorker.go b/src/query/callWorker.go index 7102fcc..2bd783b 100644 --- a/src/query/callWorker.go +++ b/src/query/callWorker.go @@ -1,7 +1,6 @@ package query import ( - "bruteforce/src/matching" "bruteforce/src/models" "bruteforce/src/utils" "sync" @@ -14,7 +13,7 @@ func executeQueryFromFile(wg *sync.WaitGroup, params *models.Forcing_params, cur } } -func MainRequest(params *models.Forcing_params, criteria matcher.MatchCriteria) { +func MainRequest(params *models.Forcing_params) { wg := &sync.WaitGroup{} wg.Add(params.Workers) channel := make(chan string) From 692821cf66d58eefb6b9ee998d8ff0266d699fe3 Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Thu, 8 Aug 2024 20:52:02 +0200 Subject: [PATCH 2/4] style: parsing is cleaned up for unecessary code --- src/cli/cli.go | 4 +++- src/main.go | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cli/cli.go b/src/cli/cli.go index 2becae7..567ac50 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -18,7 +18,7 @@ func Parse_cli_args() (models.Forcing_params, error) { // forkptr := flag.Bool("v", false, "Verbose program") statusPtr := flag.String("status-codes", "200,401,403,404,429,500", "Comma-separated list of status codes to match") - headerPtr := flag.String("header", "", "Header to match") + headerPtr := flag.String("header", "", "Header to match, formatted as \"key: value\"") bodyPtr := flag.String("body", "", "String to match in response body") wordlistPtr := flag.String("wordlist", "", "Wordlist to bruteforce url with") flag.IntVar(¶ms.Workers, "threads", 1, "Number of threads to be used") @@ -38,6 +38,7 @@ func Parse_cli_args() (models.Forcing_params, error) { if len(flag.Args()) < 1 { return params, UrlError } + params.Url = flag.Args()[0] // params.BoolFlags.Verbose = *forkptr params.Criteria = matcher.MatchParser(*statusPtr, *headerPtr, *bodyPtr) @@ -45,5 +46,6 @@ func Parse_cli_args() (models.Forcing_params, error) { if params.Wordlist == "" { return params, WordListError } + return params, nil } diff --git a/src/main.go b/src/main.go index 53c950e..9642a22 100644 --- a/src/main.go +++ b/src/main.go @@ -2,7 +2,6 @@ package main import ( "bruteforce/src/cli" - // "bruteforce/src/matching" "bruteforce/src/query" "fmt" ) @@ -16,6 +15,5 @@ func main() { } fmt.Println(forcing_params) - // matcher.MatchParser(&forcing_params) query.MainRequest(&forcing_params) } From bb9f6dd0009330f25bf7974fed949a152e1565a1 Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Mon, 12 Aug 2024 15:45:56 +0200 Subject: [PATCH 3/4] feat(matcher): implement matcher in the query execution --- src/matching/matcher.go | 18 ++++++------------ src/matching/status.go | 9 +++++---- src/query/queryExecute.go | 6 +++++- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/matching/matcher.go b/src/matching/matcher.go index a330d48..7c5039c 100644 --- a/src/matching/matcher.go +++ b/src/matching/matcher.go @@ -2,28 +2,22 @@ package matcher import ( "bruteforce/src/models" - "io" "log" "net/http" ) -func MatchResponse(response *http.Response, criteria models.MatchCriteria) (bool, string) { - body, err := io.ReadAll(response.Body) - if err != nil { - return false, err.Error() - } - - if matched, err := matchStatusCode(response, criteria.StatusCodes); !matched { - return false, err.Error() +func MatchResponse(response *http.Response, body []byte, criteria models.MatchCriteria) error { + if matched, err := matchStatusCode(response, criteria); !matched { + return err } if matched, err := matchHeaders(response, criteria); !matched { - return false, err.Error() + return err } if matched, err := matchContents(body, criteria); !matched { - return false, err.Error() + return err } - return true, "matched successfully" + return nil } func MatchParser(statusPtr string, headerPtr string, bodyPtr string) models.MatchCriteria { diff --git a/src/matching/status.go b/src/matching/status.go index e60c746..3dd681a 100644 --- a/src/matching/status.go +++ b/src/matching/status.go @@ -1,21 +1,22 @@ package matcher import ( + "bruteforce/src/models" "fmt" "log" "net/http" "strings" ) -func matchStatusCode(resp *http.Response, matchCodes []int) (bool, error) { +func matchStatusCode(resp *http.Response, criteria models.MatchCriteria) (bool, error) { isAll := false - if matchCodes[0] == 0 { + if criteria.StatusCodes[0] == 0 { isAll = !isAll } else { - log.Printf("Matching status codes %d...", matchCodes) + log.Printf("Matching status codes %d...", criteria.StatusCodes) } - for _, code := range matchCodes { + for _, code := range criteria.StatusCodes { if resp.StatusCode == code || isAll { return true, nil } diff --git a/src/query/queryExecute.go b/src/query/queryExecute.go index 7a76c97..e2aba3c 100644 --- a/src/query/queryExecute.go +++ b/src/query/queryExecute.go @@ -1,6 +1,7 @@ package query import ( + "bruteforce/src/matching" "bruteforce/src/models" "fmt" "io" @@ -29,5 +30,8 @@ func QueryExecute(params *models.Forcing_params, path string, method string) { log.Fatal(err) } - fmt.Println(string(body)) + if err := matcher.MatchResponse(resp, body, params.Criteria); err == nil { + fmt.Println(string(body)) + } + } From c4a7249786a34c22f0218f57a19384105b9f85b8 Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Mon, 12 Aug 2024 15:50:16 +0200 Subject: [PATCH 4/4] style(matcher): fixup leftover useless bool return --- src/matching/body.go | 6 +++--- src/matching/headers.go | 6 +++--- src/matching/matcher.go | 6 +++--- src/matching/status.go | 6 +++--- src/query/queryExecute.go | 2 ++ 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/matching/body.go b/src/matching/body.go index 51563b7..9ccf9f5 100644 --- a/src/matching/body.go +++ b/src/matching/body.go @@ -6,9 +6,9 @@ import ( "strings" ) -func matchContents(body []byte, criteria models.MatchCriteria) (bool, error) { +func matchContents(body []byte, criteria models.MatchCriteria) error { if criteria.BodyContains != "" && !strings.Contains(string(body), criteria.BodyContains) { - return false, errors.New("body content mismatch") + return errors.New("body content mismatch") } - return true, nil + return nil } diff --git a/src/matching/headers.go b/src/matching/headers.go index 7cdff1e..9bae1bb 100644 --- a/src/matching/headers.go +++ b/src/matching/headers.go @@ -8,13 +8,13 @@ import ( "strings" ) -func matchHeaders(resp *http.Response, criteria models.MatchCriteria) (bool, error) { +func matchHeaders(resp *http.Response, criteria models.MatchCriteria) error { for key, value := range criteria.Headers { if resp.Header.Get(key) != value { - return false, fmt.Errorf("header mismatch: %s=%s\nheaders: %s", key, value, resp.Header) + return fmt.Errorf("header mismatch: %s=%s\nheaders: %s", key, value, resp.Header) } } - return true, nil + return nil } func parseHeaders(headersList string) map[string]string { diff --git a/src/matching/matcher.go b/src/matching/matcher.go index 7c5039c..687dc60 100644 --- a/src/matching/matcher.go +++ b/src/matching/matcher.go @@ -7,13 +7,13 @@ import ( ) func MatchResponse(response *http.Response, body []byte, criteria models.MatchCriteria) error { - if matched, err := matchStatusCode(response, criteria); !matched { + if err := matchStatusCode(response, criteria); err != nil { return err } - if matched, err := matchHeaders(response, criteria); !matched { + if err := matchHeaders(response, criteria); err != nil { return err } - if matched, err := matchContents(body, criteria); !matched { + if err := matchContents(body, criteria); err != nil { return err } diff --git a/src/matching/status.go b/src/matching/status.go index 3dd681a..2a90b01 100644 --- a/src/matching/status.go +++ b/src/matching/status.go @@ -8,7 +8,7 @@ import ( "strings" ) -func matchStatusCode(resp *http.Response, criteria models.MatchCriteria) (bool, error) { +func matchStatusCode(resp *http.Response, criteria models.MatchCriteria) error { isAll := false if criteria.StatusCodes[0] == 0 { @@ -18,10 +18,10 @@ func matchStatusCode(resp *http.Response, criteria models.MatchCriteria) (bool, } for _, code := range criteria.StatusCodes { if resp.StatusCode == code || isAll { - return true, nil + return nil } } - return false, fmt.Errorf("status code is %d", resp.StatusCode) + return fmt.Errorf("status code is %d", resp.StatusCode) } func parseStatusCodes(statusCodeList string) ([]int, error) { diff --git a/src/query/queryExecute.go b/src/query/queryExecute.go index e2aba3c..5185636 100644 --- a/src/query/queryExecute.go +++ b/src/query/queryExecute.go @@ -32,6 +32,8 @@ func QueryExecute(params *models.Forcing_params, path string, method string) { if err := matcher.MatchResponse(resp, body, params.Criteria); err == nil { fmt.Println(string(body)) + } else { + log.Println(err) } }