diff --git a/v2/go.mod b/v2/go.mod index 39a54ff3d..d7a1dfc67 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -77,6 +77,7 @@ require ( github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/andybalholm/cascadia v1.1.0 // indirect github.com/antchfx/xpath v1.1.6 // indirect + github.com/aws/aws-sdk-go v1.42.3 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/bits-and-blooms/bitset v1.2.0 // indirect github.com/bits-and-blooms/bloom/v3 v3.0.1 // indirect @@ -99,6 +100,7 @@ require ( github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect github.com/itchyny/timefmt-go v0.1.3 // indirect github.com/jasonlvhit/gocron v0.0.1 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/karlseguin/ccache/v2 v2.0.8 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/klauspost/pgzip v1.2.5 // indirect diff --git a/v2/go.sum b/v2/go.sum index a497178f8..47dfe6c05 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -100,6 +100,8 @@ github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:W github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.42.3 h1:lBKr3tQ06m1uykiychMNKLK1bRfOzaIEQpsI/S3QiNc= +github.com/aws/aws-sdk-go v1.42.3/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= @@ -392,6 +394,9 @@ github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrn github.com/jasonlvhit/gocron v0.0.1 h1:qTt5qF3b3srDjeOIR4Le1LfeyvoYzJlYpqvG7tJX5YU= github.com/jasonlvhit/gocron v0.0.1/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -1206,6 +1211,7 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/v2/pkg/protocols/http/build_request.go b/v2/pkg/protocols/http/build_request.go index 4b4ac9f21..adf940af9 100644 --- a/v2/pkg/protocols/http/build_request.go +++ b/v2/pkg/protocols/http/build_request.go @@ -19,6 +19,7 @@ import ( "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/replacer" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/race" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/raw" "github.com/projectdiscovery/nuclei/v2/pkg/types" @@ -126,6 +127,13 @@ func (r *requestGenerator) makeSelfContainedRequest(dynamicValues map[string]int if len(parts) < 3 { return nil, fmt.Errorf("malformed request supplied") } + + // the url might contain placeholders + parts[1] = replacer.Replace(parts[1], generators.BuildPayloadFromOptions(r.request.options.Options)) + if expressions.ContainsUnresolvedVariables(parts[1]) != nil { + return nil, err + } + parsed, err := url.Parse(parts[1]) if err != nil { return nil, fmt.Errorf("could not parse request URL: %s", err) diff --git a/v2/pkg/protocols/http/http.go b/v2/pkg/protocols/http/http.go index 304f1a497..c1adef103 100644 --- a/v2/pkg/protocols/http/http.go +++ b/v2/pkg/protocols/http/http.go @@ -140,6 +140,7 @@ type Request struct { // description: | // SelfContained specifies if the request is self contained. SelfContained bool `yaml:"-" json:"-"` + AwsSign bool `yaml:"-" json:"-"` // description: | // CookieReuse is an optional setting that enables cookie reuse for diff --git a/v2/pkg/protocols/http/request.go b/v2/pkg/protocols/http/request.go index 3958d6c74..afb8efb8c 100644 --- a/v2/pkg/protocols/http/request.go +++ b/v2/pkg/protocols/http/request.go @@ -13,6 +13,8 @@ import ( "sync" "time" + "github.com/aws/aws-sdk-go/aws/credentials" + v4 "github.com/aws/aws-sdk-go/aws/signer/v4" "github.com/pkg/errors" "github.com/remeh/sizedwaitgroup" "go.uber.org/multierr" @@ -342,6 +344,39 @@ func (request *Request) executeRequest(reqURL string, generatedRequest *generate } } if resp == nil { + // aws sign the request if necessary + if request.AwsSign { + generatedRequest.request.Header.Del("Host") + payloads := request.options.Options.Vars.AsMap() + var creds *credentials.Credentials + if request.options.Options.EnvironmentVariables { + // get from env + creds = credentials.NewEnvCredentials() + } else { // get from variables { + awsAccessKeyId := payloads["aws-id"] + awsSecretAccessKey := payloads["aws-secret"] + creds = credentials.NewStaticCredentials(awsAccessKeyId.(string), awsSecretAccessKey.(string), "") + } + + signer := v4.NewSigner(creds) + var body *bytes.Reader + if generatedRequest.request.Request.Body != nil { + bodyBytes, err := ioutil.ReadAll(generatedRequest.request.Request.Body) + if err != nil { + return err + } + generatedRequest.request.Request.Body.Close() + body = bytes.NewReader(bodyBytes) + } + + service := payloads["service"].(string) + region := payloads["region"].(string) + now := time.Now() + _, err = signer.Sign(generatedRequest.request.Request, body, service, region, now) + if err != nil { + return err + } + } resp, err = request.httpClient.Do(generatedRequest.request) } } diff --git a/v2/pkg/templates/compile.go b/v2/pkg/templates/compile.go index bf4e79b18..07ee2c753 100644 --- a/v2/pkg/templates/compile.go +++ b/v2/pkg/templates/compile.go @@ -152,6 +152,11 @@ func Parse(filePath string, preprocessor Preprocessor, options protocols.Execute // parseSelfContainedRequests parses the self contained template requests. func (t *Template) parseSelfContainedRequests() { + if t.AwsSign { + for _, request := range t.RequestsHTTP { + request.AwsSign = true + } + } if !t.SelfContained { return } diff --git a/v2/pkg/templates/templates.go b/v2/pkg/templates/templates.go index ff9e527f4..f317e10bd 100644 --- a/v2/pkg/templates/templates.go +++ b/v2/pkg/templates/templates.go @@ -66,6 +66,7 @@ type Template struct { // description: | // Self Contained marks Requests for the template as self-contained SelfContained bool `yaml:"self-contained,omitempty" jsonschema:"title=mark requests as self-contained,description=Mark Requests for the template as self-contained"` + AwsSign bool `yaml:"aws-sign,omitempty"` // TotalRequests is the total number of requests for the template. TotalRequests int `yaml:"-" json:"-"`