Merge pull request #82 from projectdiscovery/feature-multi-verb

adding multi-verb support
This commit is contained in:
bauthard 2020-08-30 22:46:32 +05:30 committed by GitHub
commit e2e5501a43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -71,7 +71,7 @@ func main() {
if err != nil {
gologger.Fatalf("Could not parse raw request: %s\n", err)
}
scanopts.Method = rrMethod
scanopts.Methods = append(scanopts.Methods, rrMethod)
scanopts.RequestURI = rrPath
for name, value := range rrHeaders {
httpxOptions.CustomHeaders[name] = value
@ -88,7 +88,12 @@ func main() {
}
}
scanopts.Method = options.Method
if options.Methods != "" {
scanopts.Methods = append(scanopts.Methods, strings.Split(options.Methods, ",")...)
}
if len(scanopts.Methods) == 0 {
scanopts.Methods = append(scanopts.Methods, "GET")
}
protocol := "https"
scanopts.VHost = options.VHost
scanopts.OutputTitle = options.ExtractTitle
@ -97,9 +102,6 @@ func main() {
scanopts.OutputContentLength = options.ContentLength
scanopts.StoreResponse = options.StoreResponse
scanopts.StoreResponseDirectory = options.StoreResponseDir
if options.Method != "" {
scanopts.Method = options.Method
}
scanopts.OutputServerHeader = options.OutputServerHeader
scanopts.OutputWithNoColor = options.NoColor
scanopts.ResponseInStdout = options.responseInStdout
@ -113,6 +115,10 @@ func main() {
scanopts.RequestBody = options.RequestBody
scanopts.Unsafe = options.Unsafe
scanopts.HTTP2Probe = options.HTTP2Probe
scanopts.OutputMethod = options.OutputMethod
if len(scanopts.Methods) > 0 {
scanopts.OutputMethod = true
}
// Try to create output folder if it doesnt exist
if options.StoreResponse && !fileutil.FolderExists(options.StoreResponseDir) {
@ -201,27 +207,29 @@ func process(t string, wg *sizedwaitgroup.SizedWaitGroup, hp *httpx.HTTPX, proto
for target := range targets(stringz.TrimProtocol(t)) {
// if no custom ports specified then test the default ones
if len(customport.Ports) == 0 {
wg.Add()
go func(target string) {
defer wg.Done()
r := analyze(hp, protocol, target, 0, &scanopts)
output <- r
if scanopts.TlsProbe && r.TlsData != nil {
scanopts.TlsProbe = false
for _, tt := range r.TlsData.DNSNames {
process(tt, wg, hp, protocol, scanopts, output)
for _, method := range scanopts.Methods {
wg.Add()
go func(target, method string) {
defer wg.Done()
r := analyze(hp, protocol, target, 0, method, &scanopts)
output <- r
if scanopts.TlsProbe && r.TlsData != nil {
scanopts.TlsProbe = false
for _, tt := range r.TlsData.DNSNames {
process(tt, wg, hp, protocol, scanopts, output)
}
for _, tt := range r.TlsData.CommonName {
process(tt, wg, hp, protocol, scanopts, output)
}
}
for _, tt := range r.TlsData.CommonName {
process(tt, wg, hp, protocol, scanopts, output)
if scanopts.CspProbe && r.CspData != nil {
scanopts.CspProbe = false
for _, tt := range r.CspData.Domains {
process(tt, wg, hp, protocol, scanopts, output)
}
}
}
if scanopts.CspProbe && r.CspData != nil {
scanopts.CspProbe = false
for _, tt := range r.CspData.Domains {
process(tt, wg, hp, protocol, scanopts, output)
}
}
}(target)
}(target, method)
}
}
// the host name shouldn't have any semicolon - in case remove the port
@ -231,21 +239,23 @@ func process(t string, wg *sizedwaitgroup.SizedWaitGroup, hp *httpx.HTTPX, proto
}
for port := range customport.Ports {
wg.Add()
go func(port int) {
defer wg.Done()
r := analyze(hp, protocol, target, port, &scanopts)
output <- r
if scanopts.TlsProbe && r.TlsData != nil {
scanopts.TlsProbe = false
for _, tt := range r.TlsData.DNSNames {
process(tt, wg, hp, protocol, scanopts, output)
for _, method := range scanopts.Methods {
wg.Add()
go func(port int, method string) {
defer wg.Done()
r := analyze(hp, protocol, target, port, method, &scanopts)
output <- r
if scanopts.TlsProbe && r.TlsData != nil {
scanopts.TlsProbe = false
for _, tt := range r.TlsData.DNSNames {
process(tt, wg, hp, protocol, scanopts, output)
}
for _, tt := range r.TlsData.CommonName {
process(tt, wg, hp, protocol, scanopts, output)
}
}
for _, tt := range r.TlsData.CommonName {
process(tt, wg, hp, protocol, scanopts, output)
}
}
}(port)
}(port, method)
}
}
}
}
@ -281,7 +291,7 @@ func targets(target string) chan string {
}
type scanOptions struct {
Method string
Methods []string
VHost bool
OutputTitle bool
OutputStatusCode bool
@ -292,6 +302,7 @@ type scanOptions struct {
OutputServerHeader bool
OutputWebSocket bool
OutputWithNoColor bool
OutputMethod bool
ResponseInStdout bool
TlsProbe bool
CspProbe bool
@ -302,7 +313,7 @@ type scanOptions struct {
HTTP2Probe bool
}
func analyze(hp *httpx.HTTPX, protocol string, domain string, port int, scanopts *scanOptions) Result {
func analyze(hp *httpx.HTTPX, protocol string, domain string, port int, method string, scanopts *scanOptions) Result {
retried := false
retry:
URL := fmt.Sprintf("%s://%s", protocol, domain)
@ -314,7 +325,7 @@ retry:
URL += scanopts.RequestURI
}
req, err := hp.NewRequest(scanopts.Method, URL)
req, err := hp.NewRequest(method, URL)
if err != nil {
return Result{URL: URL, err: err}
}
@ -382,6 +393,16 @@ retry:
builder.WriteRune(']')
}
if scanopts.OutputMethod {
builder.WriteString(" [")
if !scanopts.OutputWithNoColor {
builder.WriteString(aurora.Magenta(method).String())
} else {
builder.WriteString(method)
}
builder.WriteRune(']')
}
if scanopts.OutputContentLength {
builder.WriteString(" [")
if !scanopts.OutputWithNoColor {
@ -441,7 +462,7 @@ retry:
var http2 bool
// if requested probes for http2
if scanopts.HTTP2Probe {
http2 = hp.SupportHTTP2(protocol, scanopts.Method, URL)
http2 = hp.SupportHTTP2(protocol, method, URL)
if http2 {
builder.WriteString(" [http2]")
}
@ -476,7 +497,9 @@ retry:
TlsData: resp.TlsData,
CspData: resp.CspData,
HTTP2: http2,
Method: method,
}
}
// Result of a scan
@ -496,6 +519,7 @@ type Result struct {
TlsData *httpx.TlsData `json:"tls,omitempty"`
CspData *httpx.CspData `json:"csp,omitempty"`
HTTP2 bool `json:"http2"`
Method string `json:"method"`
}
// JSON the result
@ -528,7 +552,7 @@ type Options struct {
SocksProxy string
JSONOutput bool
InputFile string
Method string
Methods string
Silent bool
Version bool
Verbose bool
@ -537,6 +561,7 @@ type Options struct {
OutputWebSocket bool
responseInStdout bool
FollowHostRedirects bool
OutputMethod bool
TLSProbe bool
CSPProbe bool
RequestURI string
@ -579,7 +604,8 @@ func ParseOptions() *Options {
flag.StringVar(&options.HttpProxy, "http-proxy", "", "HTTP Proxy, eg http://127.0.0.1:8080")
flag.BoolVar(&options.JSONOutput, "json", false, "JSON Output")
flag.StringVar(&options.InputFile, "l", "", "File containing domains")
flag.StringVar(&options.Method, "x", "", "Request Method")
flag.StringVar(&options.Methods, "x", "", "Request Methods")
flag.BoolVar(&options.OutputMethod, "method", false, "Output method")
flag.BoolVar(&options.Silent, "silent", false, "Silent mode")
flag.BoolVar(&options.Version, "version", false, "Show version of httpx")
flag.BoolVar(&options.Verbose, "verbose", false, "Verbose Mode")