Skip to content

Commit

Permalink
Merge pull request #39 from jaikishantulswani/main
Browse files Browse the repository at this point in the history
Status Code and Unique Filter
  • Loading branch information
devploit authored Jul 27, 2024
2 parents 6ce8b25 + 1003bcd commit 034d0a0
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 67 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Verbose: false
./nomore403 -u https://domain.com/admin -m 10 -d 200
```

## Options
## Options Modded

```bash
./nomore403 -h
Expand All @@ -134,6 +134,8 @@ Flags:
--request-file string Load request configuration and flags from a specified file.
-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])
--timeout int Specify a max timeout time in ms (default 6000)
--status strings Filter output by comma-separated status codes (e.g., 200,301,403)
--unique Show unique output based on status code and response length
-u, --uri string Specify the target URL for the request.
-a, --user-agent string pecify a custom User-Agent string for requests (default: 'nomore403').
-v, --verbose Enable verbose output for detailed request/response logging.
Expand Down
157 changes: 94 additions & 63 deletions cmd/requester.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
package cmd

import (
"bufio"
"fmt"
"log"
"math/rand"
"net/url"
"os"
"os/exec"
"strconv"
"strings"
"sync"
"time"
"unicode"

"github.com/fatih/color"
"github.com/zenthangplus/goccm"
"bufio"
"fmt"
"log"
"math/rand"
"net/url"
"os"
"os/exec"
"strconv"
"strings"
"sync"
"time"
"unicode"

"github.com/fatih/color"
"github.com/zenthangplus/goccm"
)

type Result struct {
line string
statusCode int
contentLength int
defaultReq bool
line string
statusCode int
contentLength int
defaultReq bool
}


type RequestOptions struct {
uri string
headers []header
Expand All @@ -46,34 +47,60 @@ var _verbose bool
var defaultSc int
var defaultCl int
var printMutex = &sync.Mutex{}
var uniqueResults = make(map[string]bool)

// printResponse prints the results of HTTP requests in a tabular format with colored output based on the status codes.
// printResponse prints the results of HTTP requests in a tabular format with colored output based on the status codes.
func printResponse(result Result) {
printMutex.Lock()
defer printMutex.Unlock()

resultContentLength := strconv.Itoa(result.contentLength) + " bytes"

var code string
switch result.statusCode {
case 200, 201, 202, 203, 204, 205, 206:
code = color.GreenString(strconv.Itoa(result.statusCode))
case 300, 301, 302, 303, 304, 307, 308:
code = color.YellowString(strconv.Itoa(result.statusCode))
case 400, 401, 402, 403, 404, 405, 406, 407, 408, 413, 429:
code = color.RedString(strconv.Itoa(result.statusCode))
case 500, 501, 502, 503, 504, 505, 511:
code = color.MagentaString(strconv.Itoa(result.statusCode))
}
if !_verbose {
if ((defaultSc == result.statusCode) && (defaultCl == result.contentLength) || result.contentLength == 0 || result.statusCode == 404 || result.statusCode == 400) && !result.defaultReq {
return
} else {
fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
}
} else {
fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
}
printMutex.Lock()
defer printMutex.Unlock()

// Check if status code filtering is enabled
if len(statusCodes) > 0 {
statusMatch := false
for _, code := range statusCodes {
if strconv.Itoa(result.statusCode) == code {
statusMatch = true
break
}
}
if !statusMatch {
return
}
}

// Check for unique output if enabled
if uniqueOutput {
key := fmt.Sprintf("%d-%d", result.statusCode, result.contentLength)
if uniqueResults[key] {
return
}
uniqueResults[key] = true
}

resultContentLength := strconv.Itoa(result.contentLength) + " bytes"

var code string
switch result.statusCode {
case 200, 201, 202, 203, 204, 205, 206:
code = color.GreenString(strconv.Itoa(result.statusCode))
case 300, 301, 302, 303, 304, 307, 308:
code = color.YellowString(strconv.Itoa(result.statusCode))
case 400, 401, 402, 403, 404, 405, 406, 407, 408, 413, 429:
code = color.RedString(strconv.Itoa(result.statusCode))
case 500, 501, 502, 503, 504, 505, 511:
code = color.MagentaString(strconv.Itoa(result.statusCode))
}

if !_verbose {
if ((defaultSc == result.statusCode) && (defaultCl == result.contentLength) || result.contentLength == 0 || result.statusCode == 404 || result.statusCode == 400) && !result.defaultReq {
return
} else {
fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
}
} else {
fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
}
}

func showInfo(options RequestOptions) {
Expand Down Expand Up @@ -541,6 +568,7 @@ func randomLine(filePath string) (string, error) {

// requester is the main function that runs all the tests.
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) {

// Set up proxy if provided.
if len(proxy) != 0 {
if !strings.Contains(proxy, "http") {
Expand Down Expand Up @@ -589,25 +617,28 @@ func requester(uri string, proxy string, userAgent string, reqHeaders []string,

_verbose = verbose

options := RequestOptions{
uri: uri,
headers: headers,
method: method,
proxy: userProxy,
userAgent: userAgent,
redirect: redirect,
folder: folder,
bypassIP: bypassIP,
timeout: timeout,
rateLimit: rateLimit,
verbose: verbose,
techniques: techniques,
reqHeaders: reqHeaders,
banner: banner,
}

// Call each function that will send HTTP requests with different variations of headers and URLs.
showInfo(options)
options := RequestOptions{
uri: uri,
headers: headers,
method: method,
proxy: userProxy,
userAgent: userAgent,
redirect: redirect,
folder: folder,
bypassIP: bypassIP,
timeout: timeout,
rateLimit: rateLimit,
verbose: verbose,
techniques: techniques,
reqHeaders: reqHeaders,
banner: banner,
}

// Reset uniqueResults map before starting new requests
uniqueResults = make(map[string]bool)

// Call each function that will send HTTP requests with different variations of headers and URLs.
showInfo(options)

for _, tech := range techniques {
switch tech {
Expand Down
12 changes: 9 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ var (
uri string
userAgent string
verbose bool
statusCodes []string // New flag for filtering status codes
uniqueOutput bool // New flag for unique output
)

// rootCmd
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "nomore403",
Short: "Tool to bypass 40X response codes.",
Expand Down Expand Up @@ -99,8 +101,12 @@ func init() {
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).")
rootCmd.PersistentFlags().IntVarP(&timeout, "timeout", "", 6000, "Specify a max timeout time in ms.")
rootCmd.PersistentFlags().StringVarP(&uri, "uri", "u", "", "Specify the target URL for the request.")
rootCmd.PersistentFlags().StringVarP(&userAgent, "user-agent", "a", "", "pecify a custom User-Agent string for requests (default: 'nomore403').")
rootCmd.PersistentFlags().StringVarP(&userAgent, "user-agent", "a", "", "Specify a custom User-Agent string for requests (default: 'nomore403').")
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose output for detailed request/response logging.")

// New flags
rootCmd.PersistentFlags().StringSliceVarP(&statusCodes, "status", "", []string{}, "Filter output by comma-separated status codes (e.g., 200,301,403)")
rootCmd.PersistentFlags().BoolVarP(&uniqueOutput, "unique", "", false, "Show unique output based on status code and response length")
}

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

0 comments on commit 034d0a0

Please sign in to comment.