Skip to content

Commit

Permalink
Merge pull request #21 from PoCInnovation/16-feature-flag-to-include-…
Browse files Browse the repository at this point in the history
…data-when-http-method-post-for-posting-data

feat: added --data and --method
  • Loading branch information
pierrelissope authored Oct 1, 2024
2 parents 13acde2 + 36667a8 commit add1c0a
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 47 deletions.
57 changes: 36 additions & 21 deletions autocompletion/bash/_bruteforce
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
#!/bin/bash
_bruteforce() {
local cur prev opts methods

_bruteforce_completion() {
local cur prev opts
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="--threads -v --status-codes --header --body --wordlist"

if [[ ${COMP_CWORD} -eq 1 ]]; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
elif [[ ${COMP_CWORD} -eq 2 ]]; then
case "${prev}" in
--threads)
COMPREPLY=( $(compgen -W "1 2 4 8 16 32" -- "${cur}") )
;;
--status-codes)
COMPREPLY=( $(compgen -W "200 401 403 404 429 500" -- "${cur}") )
;;
--header|--body|--wordlist)
COMPREPLY=()
;;
esac
else
COMPREPLY=( $(compgen -W "http:// https://" -- "${cur}") )
opts="-v --threads --status-codes --header --body --wordlist --method --data"

methods="POST GET PUT PATCH DELETE HEAD OPTIONS"

case "$prev" in
--threads)
COMPREPLY=( $(compgen -W "1 2 4 8 16 32" -- "$cur") )
return 0
;;
--status-codes)
COMPREPLY=( $(compgen -W "200 401 403 404 429 500" -- "$cur") )
return 0
;;
--method)
COMPREPLY=( $(compgen -W "$methods" -- "$cur") )
return 0
;;
--wordlist)
COMPREPLY=( $(compgen -f -- "$cur") )
return 0
;;
--header|--body|--data)
return 0
;;
*)
;;
esac

if [[ "$cur" == http* ]]; then
COMPREPLY=( $(compgen -W "http:// https://" -- "$cur") )
return 0
fi

COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
}

complete -F _bruteforce_completion bruteforce
complete -F _bruteforce bruteforce
4 changes: 3 additions & 1 deletion autocompletion/zsh/_bruteforce
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ _bruteforce() {
args=(
'-v[verbose mode]'
'--threads=[number of threads]:number of threads:(1 2 4 8 16 32)'
'--status-codes=[Comma-separated list of status codes to match]:status codes:'
'--status-codes=[Comma-separated list of status codes to match]:codes:(200 401 403 404 429 500)'
'--header=[Header to match]:header:'
'--body=[String to match in response body]:body:'
'--wordlist=[Wordlist to bruteforce URLs with]:wordlist:_files'
'--method=[Method to bruteforce with]:methodes:(POST GET PUT PATCH DELETE HEAD OPTIONS)'
'--data=[JSON Data to inlude in body when bruteforcing]':data
'*:url:_bruteforce_urls'
)

Expand Down
45 changes: 33 additions & 12 deletions src/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,49 @@ package cli
import (
"bruteforce/src/matching"
"bruteforce/src/models"
"encoding/json"
"errors"
"flag"
"fmt"
"os"
)

func errorHandling(params models.ForcingParams) (models.ForcingParams, error) {
ThreadsError := errors.New("wrong number of threads given")
WordListError := errors.New("no wordlist given")
DataError := errors.New("Invalid JSON data")
methodError := errors.New("Invalid HTTP method")
var method_list = [7]string{"POST", "GET", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"}

if params.Data != "" && !json.Valid([]byte(params.Data)) {
return params, DataError
}
if params.Workers < 1 {
return params, ThreadsError
}
if params.Wordlist == "" {
return params, WordListError
}
for i := 0; i < 7; i++ {
if params.Method == method_list[i] {
return params, nil
}
}
return params, methodError
}

func ParseCliArgs() (models.ForcingParams, error) {
var params models.ForcingParams

UrlError := errors.New("no url given")
ThreadsError := errors.New("wrong number of threads given")
WordListError := errors.New("no wordlist given")

forkptr := flag.Bool("v", false, "Verbose program")
printbodyptr := flag.Bool("p", false, "Prints body when matched")
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, formatted as \"key: value\"")
bodyPtr := flag.String("body", "", "String to match in response body")
wordlistPtr := flag.String("wordlist", "default-wordlist.txt", "Wordlist to bruteforce url with")
wordlistPtr := flag.String("wordlist", "", "Wordlist to bruteforce url with")
methodPtr := flag.String("method", "POST", "Method to bruteforce with")
postDataptr := flag.String("data", "", "JSON Data to inlude in body when bruteforcing")
flag.IntVar(&params.Workers, "threads", 1, "Number of threads to be used")

flag.Usage = func() {
Expand All @@ -39,13 +64,9 @@ func ParseCliArgs() (models.ForcingParams, error) {
params.BoolFlags.Verbose = *forkptr
params.Wordlist = *wordlistPtr
params.Criteria = matcher.MatchParser(*statusPtr, *headerPtr, *bodyPtr)
params.Data = *postDataptr
params.Method = *methodPtr
params.BoolFlags.BodyToFile = *printbodyptr

if params.Workers < 1 {
return params, ThreadsError
}
if params.Wordlist == "" {
return params, WordListError
}

return params, nil
return errorHandling(params)
}
5 changes: 2 additions & 3 deletions src/matching/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"net/http"
)

func MatchResponse(response *http.Response, body []byte, criteria models.MatchCriteria) error {
if err := matchStatusCode(response, criteria); err != nil {
func MatchResponse(response *http.Response, body []byte, criteria models.MatchCriteria, params *models.ForcingParams) error {
if err := matchStatusCode(response, criteria, params); err != nil {
return err
}
if err := matchHeaders(response, criteria); err != nil {
Expand All @@ -16,7 +16,6 @@ func MatchResponse(response *http.Response, body []byte, criteria models.MatchCr
if err := matchContents(body, criteria); err != nil {
return err
}

return nil
}

Expand Down
6 changes: 4 additions & 2 deletions src/matching/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (
"strings"
)

func matchStatusCode(resp *http.Response, criteria models.MatchCriteria) error {
func matchStatusCode(resp *http.Response, criteria models.MatchCriteria, params *models.ForcingParams) error {
isAll := false

if criteria.StatusCodes[0] == 0 {
isAll = !isAll
} else {
log.Printf("Matching status codes %d...", criteria.StatusCodes)
if params.BoolFlags.Verbose {
log.Printf("Matching status codes %d...", criteria.StatusCodes)
}
}
for _, code := range criteria.StatusCodes {
if resp.StatusCode == code || isAll {
Expand Down
5 changes: 4 additions & 1 deletion src/models/models.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package models

type boolflags struct {
Verbose bool
Verbose bool
BodyToFile bool
}

type HeaderMatch struct {
Expand All @@ -26,4 +27,6 @@ type ForcingParams struct {
Wordlist string
BoolFlags boolflags
Criteria MatchCriteria
Data string
Method string
}
2 changes: 1 addition & 1 deletion src/query/callWorker.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func executeQueryFromFile(wg *sync.WaitGroup, params *models.ForcingParams, curr
}

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

Expand Down
22 changes: 16 additions & 6 deletions src/query/queryExecute.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package query
import (
"bruteforce/src/matching"
"bruteforce/src/models"
"bytes"
"fmt"
"io"
"log"
Expand All @@ -11,12 +12,16 @@ import (

func QueryExecute(params *models.ForcingParams, path string, method string) {
client := &http.Client{}
req, err := http.NewRequest(method, params.Url+path, nil)
body_req := []byte(params.Data)

req, err := http.NewRequest(method, params.Url+path, bytes.NewBuffer(body_req))

if err != nil {
log.Fatal(err)
}
log.Printf("NewRequest(%s)", params.Url+path)

if params.BoolFlags.Verbose {
log.Printf("NewRequest(%s)", params.Url+path)
}
q := req.URL.Query()
req.URL.RawQuery = q.Encode()

Expand All @@ -31,9 +36,14 @@ func QueryExecute(params *models.ForcingParams, path string, method string) {
log.Fatal(err)
}

if err := matcher.MatchResponse(resp, body, params.Criteria); err == nil {
fmt.Println(string(body))
if err := matcher.MatchResponse(resp, body, params.Criteria, params); err == nil {
if params.BoolFlags.BodyToFile {
fmt.Println(string(body))
}
log.Printf("Successfully Matched %s", params.Url+path)
} else {
log.Println(err)
if params.BoolFlags.Verbose {
log.Println(err)
}
}
}

0 comments on commit add1c0a

Please sign in to comment.