Skip to content

Commit

Permalink
feat: added --data and --method
Browse files Browse the repository at this point in the history
data allows the user to input data to pass to the body of the requests
method allows the user to change the http method to bruteforce with
  • Loading branch information
SIMLUKE committed Sep 30, 2024
1 parent 4ec7bf2 commit c9847cb
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 44 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
42 changes: 31 additions & 11 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")
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", "", "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,8 @@ 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

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
2 changes: 2 additions & 0 deletions src/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,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
17 changes: 12 additions & 5 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,11 @@ func QueryExecute(params *models.ForcingParams, path string, method string) {
log.Fatal(err)
}

if err := matcher.MatchResponse(resp, body, params.Criteria); err == nil {
if err := matcher.MatchResponse(resp, body, params.Criteria, params); err == nil {
fmt.Println(string(body))
} else {
log.Println(err)
if params.BoolFlags.Verbose {
log.Println(err)
}
}
}

0 comments on commit c9847cb

Please sign in to comment.