-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
merge: pull request #6 from PoCInnovation/connect-match-reqs to main
Connect match reqs
- Loading branch information
Showing
14 changed files
with
386 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/bin/bash | ||
|
||
_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}") ) | ||
fi | ||
} | ||
|
||
complete -F _bruteforce_completion bruteforce |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#compdef bruteforce | ||
|
||
_bruteforce() { | ||
local -a args | ||
|
||
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:' | ||
'--header=[Header to match]:header:' | ||
'--body=[String to match in response body]:body:' | ||
'--wordlist=[Wordlist to bruteforce URLs with]:wordlist:_files' | ||
'*:url:_bruteforce_urls' | ||
) | ||
|
||
_arguments -s $args | ||
} | ||
|
||
_bruteforce_urls() { | ||
_urls -p 'http://' 'https://' | ||
} | ||
|
||
compdef _bruteforce bruteforce |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package cli | ||
|
||
import ( | ||
"bruteforce/src/matching" | ||
"bruteforce/src/models" | ||
"errors" | ||
"flag" | ||
"fmt" | ||
"os" | ||
) | ||
|
||
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") | ||
flag.IntVar(¶ms.Workers, "threads", 1, "Number of threads to be used") | ||
|
||
flag.Usage = func() { | ||
fmt.Fprintf(os.Stderr, "Usage: bruteforce [options] --wordlist=[./path/to/wordlist] <url>\n") | ||
fmt.Fprintf(os.Stderr, "Options:\n") | ||
flag.PrintDefaults() | ||
} | ||
|
||
flag.Parse() | ||
|
||
if len(flag.Args()) < 1 { | ||
return params, UrlError | ||
} | ||
|
||
params.Url = flag.Args()[0] | ||
params.BoolFlags.Verbose = *forkptr | ||
params.Wordlist = *wordlistPtr | ||
params.Criteria = matcher.MatchParser(*statusPtr, *headerPtr, *bodyPtr) | ||
|
||
if params.Workers < 1 { | ||
return params, ThreadsError | ||
} | ||
if params.Wordlist == "" { | ||
return params, WordListError | ||
} | ||
|
||
return params, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,19 @@ | ||
package main | ||
|
||
import ( | ||
"bruteforce/src/cli" | ||
"bruteforce/src/query" | ||
"fmt" | ||
) | ||
|
||
func main() { | ||
fmt.Println("Hello World") | ||
|
||
forcingParams, err := cli.ParseCliArgs() | ||
|
||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(forcingParams) | ||
|
||
query.MainRequest(&forcingParams) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package matcher | ||
|
||
import ( | ||
"bruteforce/src/models" | ||
"errors" | ||
"strings" | ||
) | ||
|
||
func matchContents(body []byte, criteria models.MatchCriteria) error { | ||
if criteria.BodyContains != "" && !strings.Contains(string(body), criteria.BodyContains) { | ||
return errors.New("body content mismatch") | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package matcher | ||
|
||
import ( | ||
"bruteforce/src/models" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
func matchHeaders(resp *http.Response, criteria models.MatchCriteria) error { | ||
for key, value := range criteria.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 { | ||
if headersList == "" { | ||
return nil | ||
} | ||
|
||
headers := make(map[string]string) | ||
headerPairs := strings.Split(headersList, ",") | ||
|
||
for _, pair := range headerPairs { | ||
parts := strings.SplitN(pair, ":", 2) | ||
if len(parts) == 2 { | ||
headers[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1]) | ||
} else { | ||
log.Printf("[WARN] Invalid header format: %s", pair) | ||
} | ||
} | ||
return headers | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package matcher | ||
|
||
import ( | ||
"bruteforce/src/models" | ||
"log" | ||
"net/http" | ||
) | ||
|
||
func MatchResponse(response *http.Response, body []byte, criteria models.MatchCriteria) error { | ||
if err := matchStatusCode(response, criteria); err != nil { | ||
return err | ||
} | ||
if err := matchHeaders(response, criteria); err != nil { | ||
return err | ||
} | ||
if err := matchContents(body, criteria); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
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(headerPtr) | ||
criteria := models.MatchCriteria{ | ||
StatusCodes: matchCodes, | ||
Headers: matchHeaders, | ||
BodyContains: bodyPtr, | ||
} | ||
|
||
return criteria | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package matcher | ||
|
||
import ( | ||
"bruteforce/src/models" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
func matchStatusCode(resp *http.Response, criteria models.MatchCriteria) error { | ||
isAll := false | ||
|
||
if criteria.StatusCodes[0] == 0 { | ||
isAll = !isAll | ||
} else { | ||
log.Printf("Matching status codes %d...", criteria.StatusCodes) | ||
} | ||
for _, code := range criteria.StatusCodes { | ||
if resp.StatusCode == code || isAll { | ||
return nil | ||
} | ||
} | ||
return fmt.Errorf("status code is %d", resp.StatusCode) | ||
} | ||
|
||
func parseStatusCodes(statusCodeList string) ([]int, error) { | ||
codeStrs := strings.Split(statusCodeList, ",") | ||
if statusCodeList == "all" { | ||
log.Println("Matching all status codes") | ||
return []int{0}, nil | ||
} | ||
|
||
var codes []int | ||
for _, codeStr := range codeStrs { | ||
var code int | ||
if _, err := fmt.Sscanf(codeStr, "%d", &code); err != nil { | ||
return nil, err | ||
} | ||
if code < 600 && code >= 100 { | ||
codes = append(codes, code) | ||
} else { | ||
log.Printf("[WARN] `%d` not considered, invalid status code.", code) | ||
} | ||
} | ||
|
||
if len(codes) == 1 && codes[0] == 0 { | ||
return nil, fmt.Errorf("no valid status code given") | ||
} | ||
return codes, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package models | ||
|
||
type boolflags struct { | ||
Verbose bool | ||
} | ||
|
||
type MatchCriteria struct { | ||
StatusCodes []int | ||
Headers map[string]string | ||
BodyContains string | ||
} | ||
|
||
type ForcingParams struct { | ||
Workers int | ||
Url string | ||
Wordlist string | ||
BoolFlags boolflags | ||
Criteria MatchCriteria | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package query | ||
|
||
import ( | ||
"bruteforce/src/models" | ||
"bruteforce/src/utils" | ||
"sync" | ||
) | ||
|
||
func executeQueryFromFile(wg *sync.WaitGroup, params *models.ForcingParams, currentPath chan string) { | ||
defer wg.Done() | ||
for taskData := range currentPath { | ||
QueryExecute(params, taskData, "GET") | ||
} | ||
} | ||
|
||
func MainRequest(params *models.ForcingParams) { | ||
wg := &sync.WaitGroup{} | ||
wg.Add(params.Workers) | ||
channel := make(chan string) | ||
wordArray := utils.GetFileContent(params.Wordlist) | ||
|
||
for i := 0; i < params.Workers; i++ { | ||
go executeQueryFromFile(wg, params, channel) | ||
} | ||
|
||
for i := 0; i < len(wordArray); i++ { | ||
channel <- wordArray[i] | ||
} | ||
|
||
close(channel) | ||
wg.Wait() | ||
} |
Oops, something went wrong.