Skip to content

Commit 034d0a0

Browse files
authored
Merge pull request #39 from jaikishantulswani/main
Status Code and Unique Filter
2 parents 6ce8b25 + 1003bcd commit 034d0a0

3 files changed

Lines changed: 106 additions & 67 deletions

File tree

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ Verbose: false
108108
./nomore403 -u https://domain.com/admin -m 10 -d 200
109109
```
110110

111-
## Options
111+
## Options Modded
112112

113113
```bash
114114
./nomore403 -h
@@ -134,6 +134,8 @@ Flags:
134134
--request-file string Load request configuration and flags from a specified file.
135135
-k, --technique strings Specify one or more attack techniques to use (e.g., headers,path-case). (default [verbs,verbs-case,headers,endpaths,midpaths,http-versions,path-case])
136136
--timeout int Specify a max timeout time in ms (default 6000)
137+
--status strings Filter output by comma-separated status codes (e.g., 200,301,403)
138+
--unique Show unique output based on status code and response length
137139
-u, --uri string Specify the target URL for the request.
138140
-a, --user-agent string pecify a custom User-Agent string for requests (default: 'nomore403').
139141
-v, --verbose Enable verbose output for detailed request/response logging.

cmd/requester.go

Lines changed: 94 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
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+
2829
type RequestOptions struct {
2930
uri string
3031
headers []header
@@ -46,34 +47,60 @@ var _verbose bool
4647
var defaultSc int
4748
var defaultCl int
4849
var printMutex = &sync.Mutex{}
50+
var uniqueResults = make(map[string]bool)
4951

52+
// printResponse prints the results of HTTP requests in a tabular format with colored output based on the status codes.
5053
// printResponse prints the results of HTTP requests in a tabular format with colored output based on the status codes.
5154
func printResponse(result Result) {
52-
printMutex.Lock()
53-
defer printMutex.Unlock()
54-
55-
resultContentLength := strconv.Itoa(result.contentLength) + " bytes"
56-
57-
var code string
58-
switch result.statusCode {
59-
case 200, 201, 202, 203, 204, 205, 206:
60-
code = color.GreenString(strconv.Itoa(result.statusCode))
61-
case 300, 301, 302, 303, 304, 307, 308:
62-
code = color.YellowString(strconv.Itoa(result.statusCode))
63-
case 400, 401, 402, 403, 404, 405, 406, 407, 408, 413, 429:
64-
code = color.RedString(strconv.Itoa(result.statusCode))
65-
case 500, 501, 502, 503, 504, 505, 511:
66-
code = color.MagentaString(strconv.Itoa(result.statusCode))
67-
}
68-
if !_verbose {
69-
if ((defaultSc == result.statusCode) && (defaultCl == result.contentLength) || result.contentLength == 0 || result.statusCode == 404 || result.statusCode == 400) && !result.defaultReq {
70-
return
71-
} else {
72-
fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
73-
}
74-
} else {
75-
fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
76-
}
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+
}
77104
}
78105

79106
func showInfo(options RequestOptions) {
@@ -541,6 +568,7 @@ func randomLine(filePath string) (string, error) {
541568

542569
// requester is the main function that runs all the tests.
543570
func requester(uri string, proxy string, userAgent string, reqHeaders []string, bypassIP string, folder string, method string, verbose bool, techniques []string, banner bool, rateLimit bool, timeout int, redirect bool, randomAgent bool) {
571+
544572
// Set up proxy if provided.
545573
if len(proxy) != 0 {
546574
if !strings.Contains(proxy, "http") {
@@ -589,25 +617,28 @@ func requester(uri string, proxy string, userAgent string, reqHeaders []string,
589617

590618
_verbose = verbose
591619

592-
options := RequestOptions{
593-
uri: uri,
594-
headers: headers,
595-
method: method,
596-
proxy: userProxy,
597-
userAgent: userAgent,
598-
redirect: redirect,
599-
folder: folder,
600-
bypassIP: bypassIP,
601-
timeout: timeout,
602-
rateLimit: rateLimit,
603-
verbose: verbose,
604-
techniques: techniques,
605-
reqHeaders: reqHeaders,
606-
banner: banner,
607-
}
608-
609-
// Call each function that will send HTTP requests with different variations of headers and URLs.
610-
showInfo(options)
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)
611642

612643
for _, tech := range techniques {
613644
switch tech {

cmd/root.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ var (
3131
uri string
3232
userAgent string
3333
verbose bool
34+
statusCodes []string // New flag for filtering status codes
35+
uniqueOutput bool // New flag for unique output
3436
)
3537

36-
// rootCmd
38+
// rootCmd represents the base command when called without any subcommands
3739
var rootCmd = &cobra.Command{
3840
Use: "nomore403",
3941
Short: "Tool to bypass 40X response codes.",
@@ -99,8 +101,12 @@ func init() {
99101
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).")
100102
rootCmd.PersistentFlags().IntVarP(&timeout, "timeout", "", 6000, "Specify a max timeout time in ms.")
101103
rootCmd.PersistentFlags().StringVarP(&uri, "uri", "u", "", "Specify the target URL for the request.")
102-
rootCmd.PersistentFlags().StringVarP(&userAgent, "user-agent", "a", "", "pecify a custom User-Agent string for requests (default: 'nomore403').")
104+
rootCmd.PersistentFlags().StringVarP(&userAgent, "user-agent", "a", "", "Specify a custom User-Agent string for requests (default: 'nomore403').")
103105
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")
104110
}
105111

106112
// initConfig reads in config file and ENV variables if set.
@@ -125,7 +131,7 @@ func initConfig() {
125131
if err := viper.ReadInConfig(); err == nil {
126132
_, err := fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
127133
if err != nil {
128-
log.Fatalf("{#err}")
134+
log.Fatalf("Error writing to stderr: %v", err)
129135
}
130136
}
131137
}

0 commit comments

Comments
 (0)