Skip to content

Commit 3b6b495

Browse files
committed
Update flags order and set new flags to banner
1 parent 034d0a0 commit 3b6b495

2 files changed

Lines changed: 128 additions & 123 deletions

File tree

cmd/requester.go

Lines changed: 126 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,30 @@
11
package cmd
22

33
import (
4-
"bufio"
5-
"fmt"
6-
"log"
7-
"math/rand"
8-
"net/url"
9-
"os"
10-
"os/exec"
11-
"strconv"
12-
"strings"
13-
"sync"
14-
"time"
15-
"unicode"
16-
17-
"github.com/fatih/color"
18-
"github.com/zenthangplus/goccm"
4+
"bufio"
5+
"fmt"
6+
"log"
7+
"math/rand"
8+
"net/url"
9+
"os"
10+
"os/exec"
11+
"strconv"
12+
"strings"
13+
"sync"
14+
"time"
15+
"unicode"
16+
17+
"github.com/fatih/color"
18+
"github.com/zenthangplus/goccm"
1919
)
2020

2121
type Result struct {
22-
line string
23-
statusCode int
24-
contentLength int
25-
defaultReq bool
22+
line string
23+
statusCode int
24+
contentLength int
25+
defaultReq bool
2626
}
2727

28-
2928
type RequestOptions struct {
3029
uri string
3130
headers []header
@@ -49,61 +48,67 @@ var defaultCl int
4948
var printMutex = &sync.Mutex{}
5049
var uniqueResults = make(map[string]bool)
5150

52-
// printResponse prints the results of HTTP requests in a tabular format with colored output based on the status codes.
5351
// printResponse prints the results of HTTP requests in a tabular format with colored output based on the status codes.
5452
func printResponse(result Result) {
55-
printMutex.Lock()
56-
defer printMutex.Unlock()
57-
58-
// Check if status code filtering is enabled
59-
if len(statusCodes) > 0 {
60-
statusMatch := false
61-
for _, code := range statusCodes {
62-
if strconv.Itoa(result.statusCode) == code {
63-
statusMatch = true
64-
break
65-
}
66-
}
67-
if !statusMatch {
68-
return
69-
}
70-
}
71-
72-
// Check for unique output if enabled
73-
if uniqueOutput {
74-
key := fmt.Sprintf("%d-%d", result.statusCode, result.contentLength)
75-
if uniqueResults[key] {
76-
return
77-
}
78-
uniqueResults[key] = true
79-
}
80-
81-
resultContentLength := strconv.Itoa(result.contentLength) + " bytes"
82-
83-
var code string
84-
switch result.statusCode {
85-
case 200, 201, 202, 203, 204, 205, 206:
86-
code = color.GreenString(strconv.Itoa(result.statusCode))
87-
case 300, 301, 302, 303, 304, 307, 308:
88-
code = color.YellowString(strconv.Itoa(result.statusCode))
89-
case 400, 401, 402, 403, 404, 405, 406, 407, 408, 413, 429:
90-
code = color.RedString(strconv.Itoa(result.statusCode))
91-
case 500, 501, 502, 503, 504, 505, 511:
92-
code = color.MagentaString(strconv.Itoa(result.statusCode))
93-
}
94-
95-
if !_verbose {
96-
if ((defaultSc == result.statusCode) && (defaultCl == result.contentLength) || result.contentLength == 0 || result.statusCode == 404 || result.statusCode == 400) && !result.defaultReq {
97-
return
98-
} else {
99-
fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
100-
}
101-
} else {
102-
fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
103-
}
53+
printMutex.Lock()
54+
defer printMutex.Unlock()
55+
56+
// Check if status code filtering is enabled
57+
if len(statusCodes) > 0 {
58+
statusMatch := false
59+
for _, code := range statusCodes {
60+
if strconv.Itoa(result.statusCode) == code {
61+
statusMatch = true
62+
break
63+
}
64+
}
65+
if !statusMatch {
66+
return
67+
}
68+
}
69+
70+
// Check for unique output if enabled
71+
if uniqueOutput {
72+
key := fmt.Sprintf("%d-%d", result.statusCode, result.contentLength)
73+
if uniqueResults[key] {
74+
return
75+
}
76+
uniqueResults[key] = true
77+
}
78+
79+
resultContentLength := strconv.Itoa(result.contentLength) + " bytes"
80+
81+
var code string
82+
switch result.statusCode {
83+
case 200, 201, 202, 203, 204, 205, 206:
84+
code = color.GreenString(strconv.Itoa(result.statusCode))
85+
case 300, 301, 302, 303, 304, 307, 308:
86+
code = color.YellowString(strconv.Itoa(result.statusCode))
87+
case 400, 401, 402, 403, 404, 405, 406, 407, 408, 413, 429:
88+
code = color.RedString(strconv.Itoa(result.statusCode))
89+
case 500, 501, 502, 503, 504, 505, 511:
90+
code = color.MagentaString(strconv.Itoa(result.statusCode))
91+
}
92+
93+
if !_verbose {
94+
if ((defaultSc == result.statusCode) && (defaultCl == result.contentLength) || result.contentLength == 0 || result.statusCode == 404 || result.statusCode == 400) && !result.defaultReq {
95+
return
96+
} else {
97+
fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
98+
}
99+
} else {
100+
fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
101+
}
104102
}
105103

106104
func showInfo(options RequestOptions) {
105+
var statusCodeStrings []string
106+
107+
for _, code := range statusCodes {
108+
statusCodeStrings = append(statusCodeStrings, code)
109+
}
110+
statusCodesString := strings.Join(statusCodeStrings, ", ")
111+
107112
if !nobanner {
108113
fmt.Println(`
109114
________ ________ ________ ________ ________ ________ ________ ________ ________
@@ -112,34 +117,36 @@ func showInfo(options RequestOptions) {
112117
╱ ╱ ╱ ╱ ╱ _╱ __/____ ╱ ╱ ╱
113118
╲__╱_____╱╲________╱╲__╱__╱__╱╲________╱╲____╱___╱╲________╱ ╱____╱╲________╱╲________╱
114119
`)
115-
}
116-
fmt.Printf("%s \t\t%s\n", "Target:", options.uri)
117-
if len(options.reqHeaders[0]) != 0 {
118-
for _, header := range options.headers {
119-
fmt.Printf("%s \t\t%s\n", "Headers:", header)
120+
fmt.Printf("%s \t\t%s\n", "Target:", options.uri)
121+
if len(options.reqHeaders[0]) != 0 {
122+
for _, header := range options.headers {
123+
fmt.Printf("%s \t\t%s\n", "Headers:", header)
124+
}
125+
} else {
126+
fmt.Printf("%s \t\t%s\n", "Headers:", "false")
120127
}
121-
} else {
122-
fmt.Printf("%s \t\t%s\n", "Headers:", "false")
123-
}
124-
if len(options.proxy.Host) != 0 {
125-
fmt.Printf("%s \t\t\t%s\n", "Proxy:", options.proxy.Host)
126-
} else {
127-
fmt.Printf("%s \t\t\t%s\n", "Proxy:", "false")
128+
if len(options.proxy.Host) != 0 {
129+
fmt.Printf("%s \t\t\t%s\n", "Proxy:", options.proxy.Host)
130+
} else {
131+
fmt.Printf("%s \t\t\t%s\n", "Proxy:", "false")
132+
}
133+
fmt.Printf("%s \t\t%s\n", "User Agent:", options.userAgent)
134+
fmt.Printf("%s \t\t%s\n", "Method:", options.method)
135+
fmt.Printf("%s \t%s\n", "Payloads folder:", options.folder)
136+
if len(bypassIP) != 0 {
137+
fmt.Printf("%s \t%s\n", "Custom bypass IP:", options.bypassIP)
138+
} else {
139+
fmt.Printf("%s \t%s\n", "Custom bypass IP:", "false")
140+
}
141+
fmt.Printf("%s \t%s\n", "Follow Redirects:", strconv.FormatBool(options.redirect))
142+
fmt.Printf("%s \t%s\n", "Rate Limit detection:", strconv.FormatBool(options.rateLimit))
143+
fmt.Printf("%s \t\t%s\n", "Status:", statusCodesString)
144+
fmt.Printf("%s \t\t%d\n", "Timeout (ms):", options.timeout)
145+
fmt.Printf("%s \t\t%d\n", "Delay (ms):", delay)
146+
fmt.Printf("%s \t\t%s\n", "Techniques:", strings.Join(options.techniques, ", "))
147+
fmt.Printf("%s \t\t%t\n", "Unique:", uniqueOutput)
148+
fmt.Printf("%s \t\t%t\n", "Verbose:", options.verbose)
128149
}
129-
fmt.Printf("%s \t\t%s\n", "User Agent:", options.userAgent)
130-
fmt.Printf("%s \t\t%s\n", "Method:", options.method)
131-
fmt.Printf("%s \t%s\n", "Payloads folder:", options.folder)
132-
if len(bypassIP) != 0 {
133-
fmt.Printf("%s \t%s\n", "Custom bypass IP:", options.bypassIP)
134-
} else {
135-
fmt.Printf("%s \t%s\n", "Custom bypass IP:", "false")
136-
}
137-
fmt.Printf("%s \t%s\n", "Follow Redirects:", strconv.FormatBool(options.redirect))
138-
fmt.Printf("%s \t%s\n", "Rate Limit detection:", strconv.FormatBool(options.rateLimit))
139-
fmt.Printf("%s \t\t%d\n", "Timeout (ms):", options.timeout)
140-
fmt.Printf("%s \t\t%d\n", "Delay (ms):", delay)
141-
fmt.Printf("%s \t\t%s\n", "Techniques:", strings.Join(options.techniques, ", "))
142-
fmt.Printf("%s \t\t%t\n", "Verbose:", options.verbose)
143150
}
144151

145152
// generateCaseCombinations generates all combinations of uppercase and lowercase letters for a given string.
@@ -592,7 +599,7 @@ func requester(uri string, proxy string, userAgent string, reqHeaders []string,
592599
} else {
593600
line, err := randomLine(folder + "/useragents")
594601
if err != nil {
595-
fmt.Println("Error al leer el archivo:", err)
602+
fmt.Println("Error reading the file:", err)
596603
return
597604
}
598605
userAgent = line
@@ -617,28 +624,28 @@ func requester(uri string, proxy string, userAgent string, reqHeaders []string,
617624

618625
_verbose = verbose
619626

620-
options := RequestOptions{
621-
uri: uri,
622-
headers: headers,
623-
method: method,
624-
proxy: userProxy,
625-
userAgent: userAgent,
626-
redirect: redirect,
627-
folder: folder,
628-
bypassIP: bypassIP,
629-
timeout: timeout,
630-
rateLimit: rateLimit,
631-
verbose: verbose,
632-
techniques: techniques,
633-
reqHeaders: reqHeaders,
634-
banner: banner,
635-
}
636-
637-
// Reset uniqueResults map before starting new requests
638-
uniqueResults = make(map[string]bool)
639-
640-
// Call each function that will send HTTP requests with different variations of headers and URLs.
641-
showInfo(options)
627+
options := RequestOptions{
628+
uri: uri,
629+
headers: headers,
630+
method: method,
631+
proxy: userProxy,
632+
userAgent: userAgent,
633+
redirect: redirect,
634+
folder: folder,
635+
bypassIP: bypassIP,
636+
timeout: timeout,
637+
rateLimit: rateLimit,
638+
verbose: verbose,
639+
techniques: techniques,
640+
reqHeaders: reqHeaders,
641+
banner: banner,
642+
}
643+
644+
// Reset uniqueResults map before starting new requests
645+
uniqueResults = make(map[string]bool)
646+
647+
// Call each function that will send HTTP requests with different variations of headers and URLs.
648+
showInfo(options)
642649

643650
for _, tech := range techniques {
644651
switch tech {

cmd/root.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,13 @@ func init() {
9898
rootCmd.PersistentFlags().BoolVarP(&rateLimit, "rate-limit", "l", false, "Halt requests upon encountering a 429 (rate limit) HTTP status code.")
9999
rootCmd.PersistentFlags().BoolVarP(&redirect, "redirect", "r", false, "Automatically follow redirects in responses.")
100100
rootCmd.PersistentFlags().StringVarP(&requestFile, "request-file", "", "", "Load request configuration and flags from a specified file.")
101+
rootCmd.PersistentFlags().StringSliceVarP(&statusCodes, "status", "", []string{}, "Filter output by comma-separated status codes (e.g., 200,301,403)")
101102
rootCmd.PersistentFlags().StringSliceVarP(&technique, "technique", "k", []string{"verbs", "verbs-case", "headers", "endpaths", "midpaths", "http-versions", "path-case"}, "Specify one or more attack techniques to use (e.g., headers,path-case).")
102103
rootCmd.PersistentFlags().IntVarP(&timeout, "timeout", "", 6000, "Specify a max timeout time in ms.")
104+
rootCmd.PersistentFlags().BoolVarP(&uniqueOutput, "unique", "", false, "Show unique output based on status code and response length")
103105
rootCmd.PersistentFlags().StringVarP(&uri, "uri", "u", "", "Specify the target URL for the request.")
104106
rootCmd.PersistentFlags().StringVarP(&userAgent, "user-agent", "a", "", "Specify a custom User-Agent string for requests (default: 'nomore403').")
105107
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose output for detailed request/response logging.")
106-
107-
// New flags
108-
rootCmd.PersistentFlags().StringSliceVarP(&statusCodes, "status", "", []string{}, "Filter output by comma-separated status codes (e.g., 200,301,403)")
109-
rootCmd.PersistentFlags().BoolVarP(&uniqueOutput, "unique", "", false, "Show unique output based on status code and response length")
110108
}
111109

112110
// initConfig reads in config file and ENV variables if set.

0 commit comments

Comments
 (0)