mirror of https://github.com/daffainfo/nuclei.git
Add support for CLI payload variables
parent
514d6f94ec
commit
12b6b2ca89
|
@ -31,11 +31,11 @@ require (
|
|||
github.com/pkg/errors v0.9.1
|
||||
github.com/projectdiscovery/clistats v0.0.8
|
||||
github.com/projectdiscovery/fastdialer v0.0.13-0.20210917073912-cad93d88e69e
|
||||
github.com/projectdiscovery/goflags v0.0.7
|
||||
github.com/projectdiscovery/fileutil v0.0.0-20210928100737-cab279c5d4b5
|
||||
github.com/projectdiscovery/goflags v0.0.8-0.20211007103353-9b9229e8a240
|
||||
github.com/projectdiscovery/gologger v1.1.4
|
||||
github.com/projectdiscovery/hmap v0.0.2-0.20210917080408-0fd7bd286bfa
|
||||
github.com/projectdiscovery/interactsh v0.0.4
|
||||
github.com/projectdiscovery/nuclei-updatecheck-api v0.0.0-20210914222811-0a072d262f77
|
||||
github.com/projectdiscovery/rawhttp v0.0.7
|
||||
github.com/projectdiscovery/retryabledns v1.0.13-0.20210916165024-76c5b76fd59a
|
||||
github.com/projectdiscovery/retryablehttp-go v1.0.2
|
||||
|
@ -102,6 +102,7 @@ require (
|
|||
github.com/projectdiscovery/iputil v0.0.0-20210804143329-3a30fcde43f3 // indirect
|
||||
github.com/projectdiscovery/mapcidr v0.0.8 // indirect
|
||||
github.com/projectdiscovery/networkpolicy v0.0.1 // indirect
|
||||
github.com/projectdiscovery/nuclei-updatecheck-api v0.0.0-20211006155443-c0a8d610a4df // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.7 // indirect
|
||||
github.com/tklauser/numcpus v0.2.3 // indirect
|
||||
|
|
10
v2/go.sum
10
v2/go.sum
|
@ -341,8 +341,14 @@ github.com/projectdiscovery/cryptoutil v0.0.0-20210805184155-b5d2512f9345/go.mod
|
|||
github.com/projectdiscovery/fastdialer v0.0.12/go.mod h1:RkRbxqDCcCFhfNUbkzBIz/ieD4uda2JuUA4WJ+RLee0=
|
||||
github.com/projectdiscovery/fastdialer v0.0.13-0.20210917073912-cad93d88e69e h1:xMAFYJgRxopAwKrj7HDwMBKJGCGDbHqopS8f959xges=
|
||||
github.com/projectdiscovery/fastdialer v0.0.13-0.20210917073912-cad93d88e69e/go.mod h1:O1l6+vAQy1QRo9FqyuyJ57W3CwpIXXg7oGo14Le6ZYQ=
|
||||
github.com/projectdiscovery/fileutil v0.0.0-20210928100737-cab279c5d4b5 h1:2dbm7UhrAKnccZttr78CAmG768sSCd+MBn4ayLVDeqA=
|
||||
github.com/projectdiscovery/fileutil v0.0.0-20210928100737-cab279c5d4b5/go.mod h1:U+QCpQnX8o2N2w0VUGyAzjM3yBAe4BKedVElxiImsx0=
|
||||
github.com/projectdiscovery/goflags v0.0.7-0.20211007101748-dd9c32bab303 h1:5ownIWK6jZYdg/pM+H5wfC4zF0rOvDeHtejbpScZt8I=
|
||||
github.com/projectdiscovery/goflags v0.0.7-0.20211007101748-dd9c32bab303/go.mod h1:Jjwsf4eEBPXDSQI2Y+6fd3dBumJv/J1U0nmpM+hy2YY=
|
||||
github.com/projectdiscovery/goflags v0.0.7 h1:aykmRkrOgDyRwcvGrK3qp+9aqcjGfAMs/+LtRmtyxwk=
|
||||
github.com/projectdiscovery/goflags v0.0.7/go.mod h1:Jjwsf4eEBPXDSQI2Y+6fd3dBumJv/J1U0nmpM+hy2YY=
|
||||
github.com/projectdiscovery/goflags v0.0.8-0.20211007103353-9b9229e8a240 h1:b7zDUSsgN5f4/IlhKF6RVGsp/NkHIuty0o1YjzAMKUs=
|
||||
github.com/projectdiscovery/goflags v0.0.8-0.20211007103353-9b9229e8a240/go.mod h1:Jjwsf4eEBPXDSQI2Y+6fd3dBumJv/J1U0nmpM+hy2YY=
|
||||
github.com/projectdiscovery/gologger v1.0.1/go.mod h1:Ok+axMqK53bWNwDSU1nTNwITLYMXMdZtRc8/y1c7sWE=
|
||||
github.com/projectdiscovery/gologger v1.1.4 h1:qWxGUq7ukHWT849uGPkagPKF3yBPYAsTtMKunQ8O2VI=
|
||||
github.com/projectdiscovery/gologger v1.1.4/go.mod h1:Bhb6Bdx2PV1nMaFLoXNBmHIU85iROS9y1tBuv7T5pMY=
|
||||
|
@ -365,8 +371,8 @@ github.com/projectdiscovery/mapcidr v0.0.8 h1:16U05F2x3o/jSTsxSCY2hCuCs9xOSwVxjo
|
|||
github.com/projectdiscovery/mapcidr v0.0.8/go.mod h1:7CzdUdjuLVI0s33dQ33lWgjg3vPuLFw2rQzZ0RxkT00=
|
||||
github.com/projectdiscovery/networkpolicy v0.0.1 h1:RGRuPlxE8WLFF9tdKSjTsYiTIKHNHW20Kl0nGGiRb1I=
|
||||
github.com/projectdiscovery/networkpolicy v0.0.1/go.mod h1:asvdg5wMy3LPVMGALatebKeOYH5n5fV5RCTv6DbxpIs=
|
||||
github.com/projectdiscovery/nuclei-updatecheck-api v0.0.0-20210914222811-0a072d262f77 h1:SNtAiRRrJtDJJDroaa/bFXt/Tix2LA6+rHRib0ORlJQ=
|
||||
github.com/projectdiscovery/nuclei-updatecheck-api v0.0.0-20210914222811-0a072d262f77/go.mod h1:pxWVDgq88t9dWv4+J2AIaWgY+EqOE1AyfHS0Tn23w4M=
|
||||
github.com/projectdiscovery/nuclei-updatecheck-api v0.0.0-20211006155443-c0a8d610a4df h1:CvTNAUD5JbLMqpMFoGNgfk2gOcN0NC57ICu0+oK84vs=
|
||||
github.com/projectdiscovery/nuclei-updatecheck-api v0.0.0-20211006155443-c0a8d610a4df/go.mod h1:pxWVDgq88t9dWv4+J2AIaWgY+EqOE1AyfHS0Tn23w4M=
|
||||
github.com/projectdiscovery/nuclei/v2 v2.5.1/go.mod h1:sU2qcY0MQFS0CqP1BgkR8ZnUyFhqK0BdnY6bvTKNjXY=
|
||||
github.com/projectdiscovery/rawhttp v0.0.7 h1:5m4peVgjbl7gqDcRYMTVEuX+Xs/nh76ohTkkvufucLg=
|
||||
github.com/projectdiscovery/rawhttp v0.0.7/go.mod h1:PQERZAhAv7yxI/hR6hdDPgK1WTU56l204BweXrBec+0=
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/projectdiscovery/fileutil"
|
||||
"github.com/projectdiscovery/gologger"
|
||||
"github.com/projectdiscovery/gologger/formatter"
|
||||
"github.com/projectdiscovery/gologger/levels"
|
||||
|
@ -61,6 +62,14 @@ func ParseOptions(options *types.Options) {
|
|||
// Load the resolvers if user asked for them
|
||||
loadResolvers(options)
|
||||
|
||||
// removes all cli variables containing payloads and add them to the internal struct
|
||||
for key, value := range options.Vars.AsMap() {
|
||||
if fileutil.FileExists(value.(string)) {
|
||||
options.Vars.Del(key)
|
||||
options.AddVarPayload(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
err := protocolinit.Init(options)
|
||||
if err != nil {
|
||||
gologger.Fatal().Msgf("Could not initialize protocols: %s\n", err)
|
||||
|
|
|
@ -30,3 +30,27 @@ func ContainsUnresolvedVariables(data string) error {
|
|||
errorMessage := errorString.String()
|
||||
return errors.New(errorMessage)
|
||||
}
|
||||
|
||||
func ContainsVariablesWithNames(data string, names map[string]interface{}) error {
|
||||
matches := unresolvedVariablesRegex.FindAllStringSubmatch(data, -1)
|
||||
if len(matches) == 0 {
|
||||
return nil
|
||||
}
|
||||
errorString := &strings.Builder{}
|
||||
errorString.WriteString("unresolved variables with values found: ")
|
||||
|
||||
for i, match := range matches {
|
||||
if len(match) < 2 {
|
||||
continue
|
||||
}
|
||||
matchName := match[1]
|
||||
if _, ok := names[matchName]; !ok {
|
||||
errorString.WriteString(matchName)
|
||||
if i != len(matches)-1 {
|
||||
errorString.WriteString(",")
|
||||
}
|
||||
}
|
||||
}
|
||||
errorMessage := errorString.String()
|
||||
return errors.New(errorMessage)
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/projectdiscovery/fileutil"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/operators"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/expressions"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/httpclientpool"
|
||||
"github.com/projectdiscovery/rawhttp"
|
||||
|
@ -225,6 +228,36 @@ func (r *Request) Compile(options *protocols.ExecuterOptions) error {
|
|||
r.CompiledOperators = compiled
|
||||
}
|
||||
|
||||
// Resolve payload paths from vars if they exists
|
||||
for name, payload := range r.options.Options.VarsPayload() {
|
||||
payloadStr, ok := payload.(string)
|
||||
// check if inputs contains the payload
|
||||
var hasPayloadName bool
|
||||
// search for markers in all request parts
|
||||
var inputs []string
|
||||
inputs = append(inputs, r.Method, r.Body)
|
||||
inputs = append(inputs, r.Raw...)
|
||||
for k, v := range r.customHeaders {
|
||||
inputs = append(inputs, fmt.Sprintf("%s: %s", k, v))
|
||||
}
|
||||
for k, v := range r.Headers {
|
||||
inputs = append(inputs, fmt.Sprintf("%s: %s", k, v))
|
||||
}
|
||||
|
||||
for _, input := range inputs {
|
||||
if expressions.ContainsVariablesWithNames(input, map[string]interface{}{name: payload}) == nil {
|
||||
hasPayloadName = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if ok && hasPayloadName && fileutil.FileExists(payloadStr) {
|
||||
if r.Payloads == nil {
|
||||
r.Payloads = make(map[string]interface{})
|
||||
}
|
||||
r.Payloads[name] = payloadStr
|
||||
}
|
||||
}
|
||||
|
||||
if len(r.Payloads) > 0 {
|
||||
attackType := r.AttackType
|
||||
if attackType == "" {
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
"github.com/projectdiscovery/gologger"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/expressions"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/interactsh"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/tostring"
|
||||
|
@ -288,12 +287,6 @@ func (r *Request) executeRequest(reqURL string, request *generatedRequest, previ
|
|||
}
|
||||
dumpedRequestString := string(dumpedRequest)
|
||||
|
||||
// Check if are there any unresolved variables. If yes, skip unless overriden by user.
|
||||
if varErr := expressions.ContainsUnresolvedVariables(dumpedRequestString); varErr != nil && !r.SkipVariablesCheck {
|
||||
gologger.Warning().Msgf("[%s] Could not make http request for %s: %v\n", r.options.TemplateID, reqURL, varErr)
|
||||
return errStopExecution
|
||||
}
|
||||
|
||||
if r.options.Options.Debug || r.options.Options.DebugRequests {
|
||||
gologger.Info().Msgf("[%s] Dumped HTTP request for %s\n\n", r.options.TemplateID, reqURL)
|
||||
gologger.Print().Msgf("%s", dumpedRequestString)
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/projectdiscovery/fastdialer/fastdialer"
|
||||
"github.com/projectdiscovery/fileutil"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/operators"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/expressions"
|
||||
|
@ -150,6 +151,28 @@ func (r *Request) Compile(options *protocols.ExecuterOptions) error {
|
|||
}
|
||||
}
|
||||
|
||||
// Resolve payload paths from vars if they exists
|
||||
for name, payload := range r.options.Options.VarsPayload() {
|
||||
payloadStr, ok := payload.(string)
|
||||
// check if inputs contains the payload
|
||||
var hasPayloadName bool
|
||||
for _, input := range r.Inputs {
|
||||
if input.Type != "" {
|
||||
continue
|
||||
}
|
||||
if expressions.ContainsVariablesWithNames(input.Data, map[string]interface{}{name: payload}) == nil {
|
||||
hasPayloadName = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if ok && hasPayloadName && fileutil.FileExists(payloadStr) {
|
||||
if r.Payloads == nil {
|
||||
r.Payloads = make(map[string]interface{})
|
||||
}
|
||||
r.Payloads[name] = payloadStr
|
||||
}
|
||||
}
|
||||
|
||||
if len(r.Payloads) > 0 {
|
||||
attackType := r.AttackType
|
||||
if attackType == "" {
|
||||
|
|
|
@ -23,6 +23,8 @@ type Options struct {
|
|||
CustomHeaders goflags.StringSlice
|
||||
// Vars is the list of custom global vars
|
||||
Vars goflags.RuntimeMap
|
||||
// vars to use as iterative payload
|
||||
varsPayload map[string]interface{}
|
||||
// Severities filters templates based on their severity and only run the matching ones.
|
||||
Severities severity.Severities
|
||||
// Author filters templates based on their author and only run the matching ones.
|
||||
|
@ -159,3 +161,15 @@ type Options struct {
|
|||
// EnvironmentVariables enables support for environment variables
|
||||
EnvironmentVariables bool
|
||||
}
|
||||
|
||||
func (options *Options) AddVarPayload(key string, value interface{}) {
|
||||
if options.varsPayload == nil {
|
||||
options.varsPayload = make(map[string]interface{})
|
||||
}
|
||||
|
||||
options.varsPayload[key] = value
|
||||
}
|
||||
|
||||
func (options *Options) VarsPayload() map[string]interface{} {
|
||||
return options.varsPayload
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue