mirror of https://github.com/daffainfo/nuclei.git
introduce `self-contained` to headless (#4322)
* introduce `self-contained` to headless * fix matched url printdev
parent
595ba8e3a5
commit
83abe0969e
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
var headlessTestcases = []TestCaseInfo{
|
||||
{Path: "protocols/headless/headless-basic.yaml", TestCase: &headlessBasic{}},
|
||||
{Path: "protocols/headless/headless-self-contained.yaml", TestCase: &headlessSelfContained{}},
|
||||
{Path: "protocols/headless/headless-header-action.yaml", TestCase: &headlessHeaderActions{}},
|
||||
{Path: "protocols/headless/headless-extract-values.yaml", TestCase: &headlessExtractValues{}},
|
||||
{Path: "protocols/headless/headless-payloads.yaml", TestCase: &headlessPayloads{}},
|
||||
|
@ -41,6 +42,18 @@ func (h *headlessBasic) Execute(filePath string) error {
|
|||
return expectResultsCount(results, 1)
|
||||
}
|
||||
|
||||
type headlessSelfContained struct{}
|
||||
|
||||
// Execute executes a test case and returns an error if occurred
|
||||
func (h *headlessSelfContained) Execute(filePath string) error {
|
||||
results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "", debug, "-headless", "-var query=selfcontained")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return expectResultsCount(results, 1)
|
||||
}
|
||||
|
||||
type headlessLocal struct{}
|
||||
|
||||
// Execute executes a test case and returns an error if occurred
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
id: headless-self-contained
|
||||
info:
|
||||
name: Headless Self Contained
|
||||
author: pdteam
|
||||
severity: info
|
||||
tags: headless
|
||||
|
||||
self-contained: true
|
||||
|
||||
headless:
|
||||
- steps:
|
||||
- action: navigate
|
||||
args:
|
||||
url: "https://postman-echo.com/get?q={{query}}"
|
||||
|
||||
- action: waitload
|
||||
matchers:
|
||||
- type: word
|
||||
words:
|
||||
- "selfcontained"
|
|
@ -59,6 +59,10 @@ type Request struct {
|
|||
// Fuzzing describes schema to fuzz headless requests
|
||||
Fuzzing []*fuzz.Rule `yaml:"fuzzing,omitempty" json:"fuzzing,omitempty" jsonschema:"title=fuzzin rules for http fuzzing,description=Fuzzing describes rule schema to fuzz headless requests"`
|
||||
|
||||
// description: |
|
||||
// SelfContained specifies if the request is self-contained.
|
||||
SelfContained bool `yaml:"-" json:"-"`
|
||||
|
||||
// description: |
|
||||
// CookieReuse is an optional setting that enables cookie reuse
|
||||
CookieReuse bool `yaml:"cookie-reuse,omitempty" json:"cookie-reuse,omitempty" jsonschema:"title=optional cookie reuse enable,description=Optional setting that enables cookie reuse"`
|
||||
|
|
|
@ -39,6 +39,14 @@ func (request *Request) Type() templateTypes.ProtocolType {
|
|||
|
||||
// ExecuteWithResults executes the protocol requests and returns results instead of writing them.
|
||||
func (request *Request) ExecuteWithResults(input *contextargs.Context, metadata, previous output.InternalEvent, callback protocols.OutputEventCallback) error {
|
||||
if request.SelfContained {
|
||||
url, err := extractBaseURLFromActions(request.Steps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
input = contextargs.NewWithInput(url)
|
||||
}
|
||||
|
||||
if request.options.Browser.UserAgent() == "" {
|
||||
request.options.Browser.SetUserAgent(request.compiledUserAgent)
|
||||
}
|
||||
|
@ -86,6 +94,21 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, metadata,
|
|||
return nil
|
||||
}
|
||||
|
||||
// This function extracts the base URL from actions.
|
||||
func extractBaseURLFromActions(steps []*engine.Action) (string, error) {
|
||||
for _, action := range steps {
|
||||
if action.ActionType.ActionType == engine.ActionNavigate {
|
||||
navigateURL := action.GetArg("url")
|
||||
url, err := urlutil.Parse(navigateURL)
|
||||
if err != nil {
|
||||
return "", errors.Errorf("could not parse URL '%s': %s", navigateURL, err.Error())
|
||||
}
|
||||
return fmt.Sprintf("%s://%s", url.Scheme, url.Host), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("no navigation action found")
|
||||
}
|
||||
|
||||
func (request *Request) executeRequestWithPayloads(input *contextargs.Context, payloads map[string]interface{}, previous output.InternalEvent, callback protocols.OutputEventCallback) error {
|
||||
instance, err := request.options.Browser.NewInstance()
|
||||
if err != nil {
|
||||
|
@ -157,7 +180,7 @@ func (request *Request) executeRequestWithPayloads(input *contextargs.Context, p
|
|||
responseBody, _ = html.HTML()
|
||||
}
|
||||
|
||||
outputEvent := request.responseToDSLMap(responseBody, out["header"], out["status_code"], reqBuilder.String(), input.MetaInput.Input, input.MetaInput.Input, page.DumpHistory())
|
||||
outputEvent := request.responseToDSLMap(responseBody, out["header"], out["status_code"], reqBuilder.String(), input.MetaInput.Input, navigatedURL, page.DumpHistory())
|
||||
// add response fields to template context and merge templatectx variables to output event
|
||||
request.options.AddTemplateVars(input.MetaInput, request.Type(), request.ID, outputEvent)
|
||||
outputEvent = generators.MergeMaps(outputEvent, request.options.GetTemplateCtx(input.MetaInput).GetAll())
|
||||
|
|
|
@ -110,6 +110,9 @@ func (template *Template) parseSelfContainedRequests() {
|
|||
for _, request := range template.RequestsNetwork {
|
||||
request.SelfContained = true
|
||||
}
|
||||
for _, request := range template.RequestsHeadless {
|
||||
request.SelfContained = true
|
||||
}
|
||||
}
|
||||
|
||||
// Requests returns the total request count for the template
|
||||
|
|
Loading…
Reference in New Issue