Skip to content

Commit

Permalink
Merge pull request #18 from PoCInnovation/robust-requests
Browse files Browse the repository at this point in the history
Robust requests
  • Loading branch information
pierrelissope committed Sep 18, 2024
2 parents 25108c5 + abcab13 commit 4ec7bf2
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 15 deletions.
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

0 comments on commit 4ec7bf2

Please sign in to comment.