Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Robust requests #18

Merged
merged 3 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,22 @@ For example, `./bruteforce -status-codes="200,201,202,401,404"`.

For example, `./bruteforce -header="Content-Type: application/json"`.

To match multiple headers, use commas to separate each querie. Specify `ALL` if you wish to have all matches be true, if not don't add the `ALL`. As so:

- should match all of the headers:

`./bruteforce -header="all,Content-Type: application/json,Content-Type: text/css"`

- match on any of the headers:

`./bruteforce -header="one,Content-Type: application/json,Content-Type: text/css"`

`-body` : match based on a body.

For example, `./bruteforce -body="Hello World"`.

Same applies the body for multiple queries of strings in the body as the header.

## Get involved

You're invited to join this project ! Check out the [contributing guide](./CONTRIBUTING.md).
Expand Down
41 changes: 38 additions & 3 deletions src/matching/body.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,48 @@ package matcher

import (
"bruteforce/src/models"
"errors"
"fmt"
"log"
"strings"
)

func matchContents(body []byte, criteria models.MatchCriteria) error {
if criteria.BodyContains != "" && !strings.Contains(string(body), criteria.BodyContains) {
return errors.New("body content mismatch")
bodyStr := string(body)

if len(criteria.Body.BodyContains) > 0 {
for _, content := range criteria.Body.BodyContains {
if !strings.Contains(bodyStr, content) {
return fmt.Errorf("body content mismatch: missing %s", content)
}
}
}
return nil
}

func parseBody(body string) models.BodyMatch {
if body == "" {
return models.BodyMatch{}
}

parts := strings.Split(body, ",")
firstPart := strings.TrimSpace(parts[0])
mode := true

if firstPart == "all" {
parts = parts[1:]
log.Println("[INFO] Matching criteria for body is set to check if.")
} else if firstPart == "one" {
mode = !mode
parts = parts[1:]
log.Println("[INFO] Matching criteria for body is set to check if one true.")
}

var parsedBody []string
for _, part := range parts {
part = strings.TrimSpace(part)
if part != "" {
parsedBody = append(parsedBody, part)
}
}
return models.BodyMatch{BodyContains: parsedBody, MatchAllBody: mode}
}
25 changes: 20 additions & 5 deletions src/matching/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,44 @@ import (
)

func matchHeaders(resp *http.Response, criteria models.MatchCriteria) error {
for key, value := range criteria.Headers {
for key, value := range criteria.Header.Headers {
if resp.Header.Get(key) != value {
return fmt.Errorf("header mismatch: %s=%s\nheaders: %s", key, value, resp.Header)
}
}
return nil
}

func parseHeaders(headersList string) map[string]string {
func parseHeaders(headersList string) models.HeaderMatch {
if headersList == "" {
return nil
return models.HeaderMatch{}
}

headers := make(map[string]string)
headerPairs := strings.Split(headersList, ",")
mode := true
firstPair := strings.TrimSpace(headerPairs[0])

if strings.HasPrefix(firstPair, "all") {
headerPairs = headerPairs[1:]
log.Println("[INFO] Matching criteria for header is set to check if.")
} else if strings.HasPrefix(firstPair, "one") {
mode = !mode
headerPairs = headerPairs[1:]
log.Println("[INFO] Matching criteria for header is set to check if one true.")
}

for _, pair := range headerPairs {
parts := strings.SplitN(pair, ":", 2)
if len(parts) == 2 {
headers[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])

log.Printf("[INFO] Parsed header: %s=%s", key, value)
headers[key] = value
} else {
log.Printf("[WARN] Invalid header format: %s", pair)
}
}
return headers
return models.HeaderMatch{Headers: headers, MatchAllHeader: mode}
}
8 changes: 5 additions & 3 deletions src/matching/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ func MatchParser(statusPtr string, headerPtr string, bodyPtr string) models.Matc
}

matchHeaders := parseHeaders(headerPtr)
matchBody := parseBody(bodyPtr)

criteria := models.MatchCriteria{
StatusCodes: matchCodes,
Headers: matchHeaders,
BodyContains: bodyPtr,
StatusCodes: matchCodes,
Header: matchHeaders,
Body: matchBody,
}

return criteria
Expand Down
16 changes: 13 additions & 3 deletions src/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@ type boolflags struct {
Verbose bool
}

type HeaderMatch struct {
Headers map[string]string
MatchAllHeader bool
}

type BodyMatch struct {
BodyContains []string
MatchAllBody bool
}

type MatchCriteria struct {
StatusCodes []int
Headers map[string]string
BodyContains string
StatusCodes []int
Header HeaderMatch
Body BodyMatch
}

type ForcingParams struct {
Expand Down
7 changes: 6 additions & 1 deletion src/query/callWorker.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ import (

func executeQueryFromFile(wg *sync.WaitGroup, params *models.ForcingParams, currentPath chan string) {
defer wg.Done()

if params.Url[len(params.Url)-1] != '/' {
params.Url = params.Url + "/"
}

for taskData := range currentPath {
QueryExecute(params, taskData, "GET")
QueryExecute(params, taskData, "POST")
}
}

Expand Down
Loading