nuclei/pkg/protocols/protocols.go

495 lines
20 KiB
Go
Raw Normal View History

package protocols
import (
"context"
"encoding/base64"
"sync/atomic"
"github.com/projectdiscovery/fastdialer/fastdialer"
Remove singletons from Nuclei engine (continuation of #6210) (#6296) * introducing execution id * wip * . * adding separate execution context id * lint * vet * fixing pg dialers * test ignore * fixing loader FD limit * test * fd fix * wip: remove CloseProcesses() from dev merge * wip: fix merge issue * protocolstate: stop memguarding on last dialer delete * avoid data race in dialers.RawHTTPClient * use shared logger and avoid race conditions * use shared logger and avoid race conditions * go mod * patch executionId into compiled template cache * clean up comment in Parse * go mod update * bump echarts * address merge issues * fix use of gologger * switch cmd/nuclei to options.Logger * address merge issues with go.mod * go vet: address copy of lock with new Copy function * fixing tests * disable speed control * fix nil ExecuterOptions * removing deprecated code * fixing result print * default logger * cli default logger * filter warning from results * fix performance test * hardcoding path * disable upload * refactor(runner): uses `Warning` instead of `Print` for `pdcpUploadErrMsg` Signed-off-by: Dwi Siswanto <git@dw1.io> * Revert "disable upload" This reverts commit 114fbe6663361bf41cf8b2645fd2d57083d53682. * Revert "hardcoding path" This reverts commit cf12ca800e0a0e974bd9fd4826a24e51547f7c00. --------- Signed-off-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Mzack9999 <mzack9999@protonmail.com> Co-authored-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Dwi Siswanto <25837540+dwisiswant0@users.noreply.github.com>
2025-07-09 14:47:26 -05:00
"github.com/projectdiscovery/gologger"
2022-10-12 22:04:37 -05:00
"github.com/projectdiscovery/ratelimit"
mapsutil "github.com/projectdiscovery/utils/maps"
stringsutil "github.com/projectdiscovery/utils/strings"
2021-09-07 17:31:46 +03:00
"github.com/logrusorgru/aurora"
2021-11-25 17:09:20 +02:00
Fuzzing layer enhancements + input-types support (#4477) * feat: move fuzz package to root directory * feat: added support for input providers like openapi,postman,etc * feat: integration of new fuzzing logic in engine * bugfix: use and instead of or * fixed lint errors * go mod tidy * add new reqresp type + bump utils * custom http request parser * use new struct type RequestResponse * introduce unified input/target provider * abstract input formats via new inputprovider * completed input provider refactor * remove duplicated code * add sdk method to load targets * rename component url->path * add new yaml format + remove duplicated code * use gopkg.in/yaml.v3 for parsing * update .gitignore * refactor/move + docs fuzzing in http protocol * fuzz: header + query integration test using fuzzplayground * fix integration test runner in windows * feat add support for filter in http fuzz * rewrite header/query integration test with filter * add replace regex rule * support kv fuzzing + misc updates * add path fuzzing example + misc improvements * fix matchedURL + skip httpx on multi formats * cookie fuzz integration test * add json body + params body tests * feat add multipart/form-data fuzzing support * add all fuzz body integration test * misc bug fixes + minor refactor * add multipart form + body form unit tests * only run fuzzing templates if -fuzz flag is given * refactor/move fuzz playground server to pkg * fix integration test + refactor * add auth types and strategies * add file auth provider * start implementing auth logic in http * add logic in http protocol * static auth implemented for http * default :80,:443 normalization * feat: dynamic auth init * feat: dynamic auth using templates * validate targets count in openapi+swagger * inputformats: add support to accept variables * fix workflow integration test * update lazy cred fetch logic * fix unit test * drop postman support * domain related normalization * update secrets.yaml file format + misc updates * add auth prefetch option * remove old secret files * add fuzzing+auth related sdk options * fix/support multiple mode in kv header fuzzing * rename 'headers' -> 'header' in fuzzing rules * fix deadlock due to merge conflict resolution * misc update * add bool type in parsed value * add openapi validation+override+ new flags * misc updates * remove optional path parameters when unavailable * fix swagger.yaml file * misc updates * update print msg * multiple openapi validation enchancements + appMode * add optional params in required_openapi_vars.yaml file * improve warning/verbose msgs in format * fix skip-format-validation not working * use 'params/parameter' instead of 'variable' in openapi * add retry support for falky tests * fix nuclei loading ignored templates (#4849) * fix tag include logic * fix unit test * remove quoting in extractor output * remove quote in debug code command * feat: issue tracker URLs in JSON + misc fixes (#4855) * feat: issue tracker URLs in JSON + misc fixes * misc changes * feat: status update support for issues * feat: report metadata generation hook support * feat: added CLI summary of tickets created * misc changes * introduce `disable-unsigned-templates` flag (#4820) * introduce `disable-unsigned-templates` flag * minor * skip instead of exit * remove duplicate imports * use stats package + misc enhancements * force display warning + adjust skipped stats in unsigned count * include unsigned skipped templates without -dut flag --------- Co-authored-by: Tarun Koyalwar <tarun@projectdiscovery.io> * Purge cache on global callback set (#4840) * purge cache on global callback set * lint * purging cache * purge cache in runner after loading templates * include internal cache from parsers + add global cache register/purge via config * remove disable cache purge option --------- Co-authored-by: Tarun Koyalwar <tarun@projectdiscovery.io> * misc update * add application/octet-stream support * openapi: support path specific params * misc option + readme update --------- Co-authored-by: Sandeep Singh <sandeep@projectdiscovery.io> Co-authored-by: sandeep <8293321+ehsandeep@users.noreply.github.com> Co-authored-by: Tarun Koyalwar <tarun@projectdiscovery.io> Co-authored-by: Tarun Koyalwar <45962551+tarunKoyalwar@users.noreply.github.com> Co-authored-by: Dogan Can Bakir <65292895+dogancanbakir@users.noreply.github.com> Co-authored-by: Mzack9999 <mzack9999@protonmail.com>
2024-03-14 03:08:53 +05:30
"github.com/projectdiscovery/nuclei/v3/pkg/authprovider"
"github.com/projectdiscovery/nuclei/v3/pkg/catalog"
"github.com/projectdiscovery/nuclei/v3/pkg/fuzz/frequency"
feat: added initial live DAST server implementation (#5772) * feat: added initial live DAST server implementation * feat: more logging + misc additions * feat: auth file support enhancements for more complex scenarios + misc * feat: added io.Reader support to input providers for http * feat: added stats db to fuzzing + use sdk for dast server + misc * feat: more additions and enhancements * misc changes to live server * misc * use utils pprof server * feat: added simpler stats tracking system * feat: fixed analyzer timeout issue + missing case fix * misc changes fix * feat: changed the logics a bit + misc changes and additions * feat: re-added slope checks + misc * feat: added baseline measurements for time based checks * chore(server): fix typos Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix(templates): potential DOM XSS Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix(authx): potential NIL deref Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * feat: misc review changes * removed debug logging * feat: remove existing cookies only * feat: lint fixes * misc * misc text update * request endpoint update * feat: added tracking for status code, waf-detection & grouped errors (#6028) * feat: added tracking for status code, waf-detection & grouped errors * lint error fixes * feat: review changes + moving to package + misc --------- Co-authored-by: sandeep <8293321+ehsandeep@users.noreply.github.com> * fix var dump (#5921) * fix var dump * fix dump test * Added filename length restriction for debug mode (-srd flag) (#5931) Co-authored-by: Andrey Matveenko <an.matveenko@vkteam.ru> * more updates * Update pkg/output/stats/waf/waf.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: sandeep <8293321+ehsandeep@users.noreply.github.com> Co-authored-by: Dwi Siswanto <25837540+dwisiswant0@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Dogan Can Bakir <65292895+dogancanbakir@users.noreply.github.com> Co-authored-by: 9flowers <51699499+Lercas@users.noreply.github.com> Co-authored-by: Andrey Matveenko <an.matveenko@vkteam.ru> Co-authored-by: Sandeep Singh <sandeep@projectdiscovery.io>
2025-02-13 18:46:28 +05:30
"github.com/projectdiscovery/nuclei/v3/pkg/fuzz/stats"
"github.com/projectdiscovery/nuclei/v3/pkg/input"
"github.com/projectdiscovery/nuclei/v3/pkg/js/compiler"
2024-03-13 21:46:30 +01:00
"github.com/projectdiscovery/nuclei/v3/pkg/loader/parser"
"github.com/projectdiscovery/nuclei/v3/pkg/model"
"github.com/projectdiscovery/nuclei/v3/pkg/operators"
"github.com/projectdiscovery/nuclei/v3/pkg/operators/extractors"
"github.com/projectdiscovery/nuclei/v3/pkg/operators/matchers"
"github.com/projectdiscovery/nuclei/v3/pkg/output"
"github.com/projectdiscovery/nuclei/v3/pkg/progress"
"github.com/projectdiscovery/nuclei/v3/pkg/projectfile"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
feat: global matchers (#5701) * feat: global matchers Signed-off-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Ice3man543 <ice3man543@users.noreply.github.com> * feat(globalmatchers): make `Callback` as type Signed-off-by: Dwi Siswanto <git@dw1.io> * feat: update `passive` term to `(matchers-)static` Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(globalmatchers): add `origin-template-*` event also use `Set` method instead of `maps.Clone` Signed-off-by: Dwi Siswanto <git@dw1.io> * feat: update `matchers-static` term to `global-matchers` Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(globalmatchers): clone event before `operator.Execute` Signed-off-by: Dwi Siswanto <git@dw1.io> * fix(tmplexec): don't store `matched` on `global-matchers` templ This will end up generating 2 events from the same `scan.ScanContext` if one of the templates has `global-matchers` enabled. This way, non- `global-matchers` templates can enter the `writeFailureCallback` func to log failure output. Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(globalmatchers): initializes `requests` on `New` Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(globalmatchers): add `hasStorage` method Signed-off-by: Dwi Siswanto <git@dw1.io> * refactor(templates): rename global matchers checks method Signed-off-by: Dwi Siswanto <git@dw1.io> * fix(loader): handle nil `templates.Template` pointer Signed-off-by: Dwi Siswanto <git@dw1.io> --------- Signed-off-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Ice3man543 <ice3man543@users.noreply.github.com>
2024-10-14 20:55:46 +07:00
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/globalmatchers"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/hosterrorscache"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/interactsh"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/utils/excludematchers"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/variables"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/headless/engine"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting"
"github.com/projectdiscovery/nuclei/v3/pkg/scan"
templateTypes "github.com/projectdiscovery/nuclei/v3/pkg/templates/types"
"github.com/projectdiscovery/nuclei/v3/pkg/types"
2024-05-15 15:34:59 +02:00
unitutils "github.com/projectdiscovery/utils/unit"
)
var (
2024-05-15 15:34:59 +02:00
MaxTemplateFileSizeForEncoding = unitutils.Mega
)
// Executer is an interface implemented any protocol based request executer.
type Executer interface {
// Compile compiles the execution generators preparing any requests possible.
Compile() error
2020-12-22 03:54:55 +05:30
// Requests returns the total number of requests the rule will perform
Requests() int
// Execute executes the protocol group and returns true or false if results were found.
Execute(ctx *scan.ScanContext) (bool, error)
// ExecuteWithResults executes the protocol requests and returns results instead of writing them.
ExecuteWithResults(ctx *scan.ScanContext) ([]*output.ResultEvent, error)
}
// ExecutorOptions contains the configuration options for executer clients
type ExecutorOptions struct {
// TemplateID is the ID of the template for the request
TemplateID string
2020-12-29 12:08:46 +05:30
// TemplatePath is the path of the template for the request
TemplatePath string
// TemplateInfo contains information block of the template request
TemplateInfo model.Info
// TemplateVerifier is the verifier for the template
TemplateVerifier string
// RawTemplate is the raw template for the request
RawTemplate []byte
// Output is a writer interface for writing output events from executer.
Output output.Writer
2020-12-24 01:42:04 +05:30
// Options contains configuration options for the executer.
Options *types.Options
// IssuesClient is a client for nuclei issue tracker reporting
IssuesClient reporting.Client
// Progress is a progress client for scan reporting
Progress progress.Progress
2020-12-24 01:42:04 +05:30
// RateLimiter is a rate-limiter for limiting sent number of requests.
RateLimiter *ratelimit.Limiter
2021-02-26 13:13:11 +05:30
// Catalog is a template catalog implementation for nuclei
Catalog catalog.Catalog
// ProjectFile is the project file for nuclei
ProjectFile *projectfile.ProjectFile
// Browser is a browser engine for running headless templates
Browser *engine.Browser
2021-04-16 16:56:41 +05:30
// Interactsh is a client for interactsh oob polling server
Interactsh *interactsh.Client
// HostErrorsCache is an optional cache for handling host errors
HostErrorsCache hosterrorscache.CacheInterface
// Stop execution once first match is found (Assigned while parsing templates)
// Note: this is different from Options.StopAtFirstMatch (Assigned from CLI option)
StopAtFirstMatch bool
// Variables is a list of variables from template
Variables variables.Variable
// Constants is a list of constants from template
Constants map[string]interface{}
// ExcludeMatchers is the list of matchers to exclude
ExcludeMatchers *excludematchers.ExcludeMatchers
// InputHelper is a helper for input normalization
InputHelper *input.Helper
// FuzzParamsFrequency is a cache for parameter frequency
FuzzParamsFrequency *frequency.Tracker
feat: added initial live DAST server implementation (#5772) * feat: added initial live DAST server implementation * feat: more logging + misc additions * feat: auth file support enhancements for more complex scenarios + misc * feat: added io.Reader support to input providers for http * feat: added stats db to fuzzing + use sdk for dast server + misc * feat: more additions and enhancements * misc changes to live server * misc * use utils pprof server * feat: added simpler stats tracking system * feat: fixed analyzer timeout issue + missing case fix * misc changes fix * feat: changed the logics a bit + misc changes and additions * feat: re-added slope checks + misc * feat: added baseline measurements for time based checks * chore(server): fix typos Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix(templates): potential DOM XSS Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix(authx): potential NIL deref Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * feat: misc review changes * removed debug logging * feat: remove existing cookies only * feat: lint fixes * misc * misc text update * request endpoint update * feat: added tracking for status code, waf-detection & grouped errors (#6028) * feat: added tracking for status code, waf-detection & grouped errors * lint error fixes * feat: review changes + moving to package + misc --------- Co-authored-by: sandeep <8293321+ehsandeep@users.noreply.github.com> * fix var dump (#5921) * fix var dump * fix dump test * Added filename length restriction for debug mode (-srd flag) (#5931) Co-authored-by: Andrey Matveenko <an.matveenko@vkteam.ru> * more updates * Update pkg/output/stats/waf/waf.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: sandeep <8293321+ehsandeep@users.noreply.github.com> Co-authored-by: Dwi Siswanto <25837540+dwisiswant0@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Dogan Can Bakir <65292895+dogancanbakir@users.noreply.github.com> Co-authored-by: 9flowers <51699499+Lercas@users.noreply.github.com> Co-authored-by: Andrey Matveenko <an.matveenko@vkteam.ru> Co-authored-by: Sandeep Singh <sandeep@projectdiscovery.io>
2025-02-13 18:46:28 +05:30
// FuzzStatsDB is a database for fuzzing stats
FuzzStatsDB *stats.Tracker
Operators []*operators.Operators // only used by offlinehttp module
// DoNotCache bool disables optional caching of the templates structure
DoNotCache bool
Colorizer aurora.Aurora
WorkflowLoader model.WorkflowLoader
2021-11-29 14:38:45 +01:00
ResumeCfg *types.ResumeCfg
// ProtocolType is the type of the template
ProtocolType templateTypes.ProtocolType
// Flow is execution flow for the template (written in javascript)
Flow string
// IsMultiProtocol is true if template has more than one protocol
IsMultiProtocol bool
// templateStore is a map which contains template context for each scan (i.e input * template-id pair)
templateCtxStore *mapsutil.SyncLockMap[string, *contextargs.Context]
javascript protocol for scripting (includes 15+ proto libs) (#4109) * rebase js-layer PR from @ice3man543 * package restructuring * working * fix duplicated event & matcher status * fix lint error * fix response field * add new functions * multiple minor improvements * fix incorrect stats in js protocol * sort output metadata in cli * remove temp files * remove dead code * add unit and integration test * fix lint error * add jsdoclint using llm * fix error in test * add js lint using llm * generate docs of libs * llm lint * remove duplicated docs * update generated docs * update prompt in doclint * update docs * temp disable version check test * fix unit test and add retry * fix panic in it * update and move jsdocs * updated jsdocs * update docs * update container platform in test * dir restructure and adding docs * add api_reference and remove markdown docs * fix imports * add javascript design and contribution docs * add js protocol documentation * update integration test and docs * update doc ext mdx->md * minor update to docs * new integration test and more * move go libs and add docs * gen new net docs and more * final docs update * add new devtool * use fastdialer * fix build fail * use fastdialer + network sandbox support * add reserved keyword 'Port' * update Port to new syntax * misc update * always enable templatectx in js protocol * move docs to 'js-proto-docs' repo * remove scrapefuncs binary --------- Co-authored-by: sandeep <8293321+ehsandeep@users.noreply.github.com>
2023-09-16 16:02:17 +05:30
// JsCompiler is abstracted javascript compiler which adds node modules and provides execution
// environment for javascript templates
JsCompiler *compiler.Compiler
Fuzzing layer enhancements + input-types support (#4477) * feat: move fuzz package to root directory * feat: added support for input providers like openapi,postman,etc * feat: integration of new fuzzing logic in engine * bugfix: use and instead of or * fixed lint errors * go mod tidy * add new reqresp type + bump utils * custom http request parser * use new struct type RequestResponse * introduce unified input/target provider * abstract input formats via new inputprovider * completed input provider refactor * remove duplicated code * add sdk method to load targets * rename component url->path * add new yaml format + remove duplicated code * use gopkg.in/yaml.v3 for parsing * update .gitignore * refactor/move + docs fuzzing in http protocol * fuzz: header + query integration test using fuzzplayground * fix integration test runner in windows * feat add support for filter in http fuzz * rewrite header/query integration test with filter * add replace regex rule * support kv fuzzing + misc updates * add path fuzzing example + misc improvements * fix matchedURL + skip httpx on multi formats * cookie fuzz integration test * add json body + params body tests * feat add multipart/form-data fuzzing support * add all fuzz body integration test * misc bug fixes + minor refactor * add multipart form + body form unit tests * only run fuzzing templates if -fuzz flag is given * refactor/move fuzz playground server to pkg * fix integration test + refactor * add auth types and strategies * add file auth provider * start implementing auth logic in http * add logic in http protocol * static auth implemented for http * default :80,:443 normalization * feat: dynamic auth init * feat: dynamic auth using templates * validate targets count in openapi+swagger * inputformats: add support to accept variables * fix workflow integration test * update lazy cred fetch logic * fix unit test * drop postman support * domain related normalization * update secrets.yaml file format + misc updates * add auth prefetch option * remove old secret files * add fuzzing+auth related sdk options * fix/support multiple mode in kv header fuzzing * rename 'headers' -> 'header' in fuzzing rules * fix deadlock due to merge conflict resolution * misc update * add bool type in parsed value * add openapi validation+override+ new flags * misc updates * remove optional path parameters when unavailable * fix swagger.yaml file * misc updates * update print msg * multiple openapi validation enchancements + appMode * add optional params in required_openapi_vars.yaml file * improve warning/verbose msgs in format * fix skip-format-validation not working * use 'params/parameter' instead of 'variable' in openapi * add retry support for falky tests * fix nuclei loading ignored templates (#4849) * fix tag include logic * fix unit test * remove quoting in extractor output * remove quote in debug code command * feat: issue tracker URLs in JSON + misc fixes (#4855) * feat: issue tracker URLs in JSON + misc fixes * misc changes * feat: status update support for issues * feat: report metadata generation hook support * feat: added CLI summary of tickets created * misc changes * introduce `disable-unsigned-templates` flag (#4820) * introduce `disable-unsigned-templates` flag * minor * skip instead of exit * remove duplicate imports * use stats package + misc enhancements * force display warning + adjust skipped stats in unsigned count * include unsigned skipped templates without -dut flag --------- Co-authored-by: Tarun Koyalwar <tarun@projectdiscovery.io> * Purge cache on global callback set (#4840) * purge cache on global callback set * lint * purging cache * purge cache in runner after loading templates * include internal cache from parsers + add global cache register/purge via config * remove disable cache purge option --------- Co-authored-by: Tarun Koyalwar <tarun@projectdiscovery.io> * misc update * add application/octet-stream support * openapi: support path specific params * misc option + readme update --------- Co-authored-by: Sandeep Singh <sandeep@projectdiscovery.io> Co-authored-by: sandeep <8293321+ehsandeep@users.noreply.github.com> Co-authored-by: Tarun Koyalwar <tarun@projectdiscovery.io> Co-authored-by: Tarun Koyalwar <45962551+tarunKoyalwar@users.noreply.github.com> Co-authored-by: Dogan Can Bakir <65292895+dogancanbakir@users.noreply.github.com> Co-authored-by: Mzack9999 <mzack9999@protonmail.com>
2024-03-14 03:08:53 +05:30
// AuthProvider is a provider for auth strategies
AuthProvider authprovider.AuthProvider
2024-03-07 15:57:38 +03:00
//TemporaryDirectory is the directory to store temporary files
TemporaryDirectory string
2024-03-13 21:46:30 +01:00
Parser parser.Parser
// ExportReqURLPattern exports the request URL pattern
// in ResultEvent it contains the exact url pattern (ex: {{BaseURL}}/{{randstr}}/xyz) used in the request
ExportReqURLPattern bool
feat: global matchers (#5701) * feat: global matchers Signed-off-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Ice3man543 <ice3man543@users.noreply.github.com> * feat(globalmatchers): make `Callback` as type Signed-off-by: Dwi Siswanto <git@dw1.io> * feat: update `passive` term to `(matchers-)static` Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(globalmatchers): add `origin-template-*` event also use `Set` method instead of `maps.Clone` Signed-off-by: Dwi Siswanto <git@dw1.io> * feat: update `matchers-static` term to `global-matchers` Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(globalmatchers): clone event before `operator.Execute` Signed-off-by: Dwi Siswanto <git@dw1.io> * fix(tmplexec): don't store `matched` on `global-matchers` templ This will end up generating 2 events from the same `scan.ScanContext` if one of the templates has `global-matchers` enabled. This way, non- `global-matchers` templates can enter the `writeFailureCallback` func to log failure output. Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(globalmatchers): initializes `requests` on `New` Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(globalmatchers): add `hasStorage` method Signed-off-by: Dwi Siswanto <git@dw1.io> * refactor(templates): rename global matchers checks method Signed-off-by: Dwi Siswanto <git@dw1.io> * fix(loader): handle nil `templates.Template` pointer Signed-off-by: Dwi Siswanto <git@dw1.io> --------- Signed-off-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Ice3man543 <ice3man543@users.noreply.github.com>
2024-10-14 20:55:46 +07:00
// GlobalMatchers is the storage for global matchers with http passive templates
GlobalMatchers *globalmatchers.Storage
Remove singletons from Nuclei engine (continuation of #6210) (#6296) * introducing execution id * wip * . * adding separate execution context id * lint * vet * fixing pg dialers * test ignore * fixing loader FD limit * test * fd fix * wip: remove CloseProcesses() from dev merge * wip: fix merge issue * protocolstate: stop memguarding on last dialer delete * avoid data race in dialers.RawHTTPClient * use shared logger and avoid race conditions * use shared logger and avoid race conditions * go mod * patch executionId into compiled template cache * clean up comment in Parse * go mod update * bump echarts * address merge issues * fix use of gologger * switch cmd/nuclei to options.Logger * address merge issues with go.mod * go vet: address copy of lock with new Copy function * fixing tests * disable speed control * fix nil ExecuterOptions * removing deprecated code * fixing result print * default logger * cli default logger * filter warning from results * fix performance test * hardcoding path * disable upload * refactor(runner): uses `Warning` instead of `Print` for `pdcpUploadErrMsg` Signed-off-by: Dwi Siswanto <git@dw1.io> * Revert "disable upload" This reverts commit 114fbe6663361bf41cf8b2645fd2d57083d53682. * Revert "hardcoding path" This reverts commit cf12ca800e0a0e974bd9fd4826a24e51547f7c00. --------- Signed-off-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Mzack9999 <mzack9999@protonmail.com> Co-authored-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Dwi Siswanto <25837540+dwisiswant0@users.noreply.github.com>
2025-07-09 14:47:26 -05:00
// Logger is the shared logging instance
Logger *gologger.Logger
// CustomFastdialer is a fastdialer dialer instance
CustomFastdialer *fastdialer.Dialer
}
2024-04-03 19:40:09 +02:00
// todo: centralizing components is not feasible with current clogged architecture
// a possible approach could be an internal event bus with pub-subs? This would be less invasive than
// reworking dep injection from scratch
Remove singletons from Nuclei engine (continuation of #6210) (#6296) * introducing execution id * wip * . * adding separate execution context id * lint * vet * fixing pg dialers * test ignore * fixing loader FD limit * test * fd fix * wip: remove CloseProcesses() from dev merge * wip: fix merge issue * protocolstate: stop memguarding on last dialer delete * avoid data race in dialers.RawHTTPClient * use shared logger and avoid race conditions * use shared logger and avoid race conditions * go mod * patch executionId into compiled template cache * clean up comment in Parse * go mod update * bump echarts * address merge issues * fix use of gologger * switch cmd/nuclei to options.Logger * address merge issues with go.mod * go vet: address copy of lock with new Copy function * fixing tests * disable speed control * fix nil ExecuterOptions * removing deprecated code * fixing result print * default logger * cli default logger * filter warning from results * fix performance test * hardcoding path * disable upload * refactor(runner): uses `Warning` instead of `Print` for `pdcpUploadErrMsg` Signed-off-by: Dwi Siswanto <git@dw1.io> * Revert "disable upload" This reverts commit 114fbe6663361bf41cf8b2645fd2d57083d53682. * Revert "hardcoding path" This reverts commit cf12ca800e0a0e974bd9fd4826a24e51547f7c00. --------- Signed-off-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Mzack9999 <mzack9999@protonmail.com> Co-authored-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Dwi Siswanto <25837540+dwisiswant0@users.noreply.github.com>
2025-07-09 14:47:26 -05:00
func (e *ExecutorOptions) RateLimitTake() {
// The code below can race and there isn't a great way to fix this without adding an idempotent
// function to the rate limiter implementation. For now, stick with whatever rate is already set.
/*
if e.RateLimiter.GetLimit() != uint(e.Options.RateLimit) {
e.RateLimiter.SetLimit(uint(e.Options.RateLimit))
e.RateLimiter.SetDuration(e.Options.RateLimitDuration)
}
*/
if e.RateLimiter != nil {
e.RateLimiter.Take()
2024-04-03 19:40:09 +02:00
}
}
// GetThreadsForPayloadRequests returns the number of threads to use as default for
// given max-request of payloads
func (e *ExecutorOptions) GetThreadsForNPayloadRequests(totalRequests int, currentThreads int) int {
if currentThreads > 0 {
return currentThreads
}
return e.Options.PayloadConcurrency
}
// CreateTemplateCtxStore creates template context store (which contains templateCtx for every scan)
func (e *ExecutorOptions) CreateTemplateCtxStore() {
e.templateCtxStore = &mapsutil.SyncLockMap[string, *contextargs.Context]{
Map: make(map[string]*contextargs.Context),
ReadOnly: atomic.Bool{},
}
}
// RemoveTemplateCtx removes template context of given scan from store
func (e *ExecutorOptions) RemoveTemplateCtx(input *contextargs.MetaInput) {
scanId := input.GetScanHash(e.TemplateID)
if e.templateCtxStore != nil {
e.templateCtxStore.Delete(scanId)
}
}
// HasTemplateCtx returns true if template context exists for given input
func (e *ExecutorOptions) HasTemplateCtx(input *contextargs.MetaInput) bool {
scanId := input.GetScanHash(e.TemplateID)
if e.templateCtxStore != nil {
return e.templateCtxStore.Has(scanId)
}
return false
}
// GetTemplateCtx returns template context for given input
func (e *ExecutorOptions) GetTemplateCtx(input *contextargs.MetaInput) *contextargs.Context {
scanId := input.GetScanHash(e.TemplateID)
if e.templateCtxStore == nil {
// if template context store is not initialized create it
e.CreateTemplateCtxStore()
}
// get template context from store
templateCtx, ok := e.templateCtxStore.Get(scanId)
if !ok {
// if template context does not exist create new and add it to store and return it
templateCtx = contextargs.New(context.Background())
templateCtx.MetaInput = input
_ = e.templateCtxStore.Set(scanId, templateCtx)
}
return templateCtx
}
// AddTemplateVars adds vars to template context with given template type as prefix
// this method is no-op if template is not multi protocol
func (e *ExecutorOptions) AddTemplateVars(input *contextargs.MetaInput, reqType templateTypes.ProtocolType, reqID string, vars map[string]interface{}) {
// if we wan't to disable adding response variables and other variables to template context
// this is the statement that does it . template context is currently only enabled for
// multiprotocol and flow templates
if !e.IsMultiProtocol && e.Flow == "" {
// no-op if not multi protocol template or flow template
return
}
templateCtx := e.GetTemplateCtx(input)
for k, v := range vars {
if stringsutil.HasPrefixAny(k, templateTypes.SupportedProtocolsStrings()...) {
// this was inherited from previous protocols no need to modify it we can directly set it or omit
templateCtx.Set(k, v)
continue
}
if !stringsutil.EqualFoldAny(k, "template-id", "template-info", "template-path") {
if reqID != "" {
k = reqID + "_" + k
} else if reqType < templateTypes.InvalidProtocol {
k = reqType.String() + "_" + k
}
templateCtx.Set(k, v)
}
}
}
// AddTemplateVar adds given var to template context with given template type as prefix
// this method is no-op if template is not multi protocol
func (e *ExecutorOptions) AddTemplateVar(input *contextargs.MetaInput, templateType templateTypes.ProtocolType, reqID string, key string, value interface{}) {
if !e.IsMultiProtocol && e.Flow == "" {
// no-op if not multi protocol template or flow template
return
}
templateCtx := e.GetTemplateCtx(input)
if stringsutil.HasPrefixAny(key, templateTypes.SupportedProtocolsStrings()...) {
// this was inherited from previous protocols no need to modify it we can directly set it or omit
templateCtx.Set(key, value)
return
}
if reqID != "" {
key = reqID + "_" + key
} else if templateType < templateTypes.InvalidProtocol {
key = templateType.String() + "_" + key
}
templateCtx.Set(key, value)
}
2021-10-27 16:50:36 +05:30
// Copy returns a copy of the executeroptions structure
Remove singletons from Nuclei engine (continuation of #6210) (#6296) * introducing execution id * wip * . * adding separate execution context id * lint * vet * fixing pg dialers * test ignore * fixing loader FD limit * test * fd fix * wip: remove CloseProcesses() from dev merge * wip: fix merge issue * protocolstate: stop memguarding on last dialer delete * avoid data race in dialers.RawHTTPClient * use shared logger and avoid race conditions * use shared logger and avoid race conditions * go mod * patch executionId into compiled template cache * clean up comment in Parse * go mod update * bump echarts * address merge issues * fix use of gologger * switch cmd/nuclei to options.Logger * address merge issues with go.mod * go vet: address copy of lock with new Copy function * fixing tests * disable speed control * fix nil ExecuterOptions * removing deprecated code * fixing result print * default logger * cli default logger * filter warning from results * fix performance test * hardcoding path * disable upload * refactor(runner): uses `Warning` instead of `Print` for `pdcpUploadErrMsg` Signed-off-by: Dwi Siswanto <git@dw1.io> * Revert "disable upload" This reverts commit 114fbe6663361bf41cf8b2645fd2d57083d53682. * Revert "hardcoding path" This reverts commit cf12ca800e0a0e974bd9fd4826a24e51547f7c00. --------- Signed-off-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Mzack9999 <mzack9999@protonmail.com> Co-authored-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Dwi Siswanto <25837540+dwisiswant0@users.noreply.github.com>
2025-07-09 14:47:26 -05:00
func (e *ExecutorOptions) Copy() *ExecutorOptions {
copy := &ExecutorOptions{
TemplateID: e.TemplateID,
TemplatePath: e.TemplatePath,
TemplateInfo: e.TemplateInfo,
TemplateVerifier: e.TemplateVerifier,
RawTemplate: e.RawTemplate,
Output: e.Output,
Options: e.Options,
IssuesClient: e.IssuesClient,
Progress: e.Progress,
RateLimiter: e.RateLimiter,
Catalog: e.Catalog,
ProjectFile: e.ProjectFile,
Browser: e.Browser,
Interactsh: e.Interactsh,
HostErrorsCache: e.HostErrorsCache,
StopAtFirstMatch: e.StopAtFirstMatch,
Variables: e.Variables,
Constants: e.Constants,
ExcludeMatchers: e.ExcludeMatchers,
InputHelper: e.InputHelper,
FuzzParamsFrequency: e.FuzzParamsFrequency,
FuzzStatsDB: e.FuzzStatsDB,
Operators: e.Operators,
DoNotCache: e.DoNotCache,
Colorizer: e.Colorizer,
WorkflowLoader: e.WorkflowLoader,
ResumeCfg: e.ResumeCfg,
ProtocolType: e.ProtocolType,
Flow: e.Flow,
IsMultiProtocol: e.IsMultiProtocol,
JsCompiler: e.JsCompiler,
AuthProvider: e.AuthProvider,
TemporaryDirectory: e.TemporaryDirectory,
Parser: e.Parser,
ExportReqURLPattern: e.ExportReqURLPattern,
GlobalMatchers: e.GlobalMatchers,
Logger: e.Logger,
}
copy.CreateTemplateCtxStore()
2021-10-27 16:50:36 +05:30
return copy
}
// Request is an interface implemented any protocol based request generator.
type Request interface {
// Compile compiles the request generators preparing any requests possible.
Compile(options *ExecutorOptions) error
// Requests returns the total number of requests the rule will perform
Requests() int
2021-01-16 14:10:24 +05:30
// GetID returns the ID for the request if any. IDs are used for multi-request
// condition matching. So, two requests can be sent and their match can
// be evaluated from the third request by using the IDs for both requests.
GetID() string
// Match performs matching operation for a matcher on model and returns:
// true and a list of matched snippets if the matcher type is supports it
// otherwise false and an empty string slice
Match(data map[string]interface{}, matcher *matchers.Matcher) (bool, []string)
2021-09-07 17:31:46 +03:00
// Extract performs extracting operation for an extractor on model and returns true or false.
Extract(data map[string]interface{}, matcher *extractors.Extractor) map[string]struct{}
// ExecuteWithResults executes the protocol requests and returns results instead of writing them.
ExecuteWithResults(input *contextargs.Context, dynamicValues, previous output.InternalEvent, callback OutputEventCallback) error
// MakeResultEventItem creates a result event from internal wrapped event. Intended to be used by MakeResultEventItem internally
MakeResultEventItem(wrapped *output.InternalWrappedEvent) *output.ResultEvent
// MakeResultEvent creates a flat list of result events from an internal wrapped event, based on successful matchers and extracted data
MakeResultEvent(wrapped *output.InternalWrappedEvent) []*output.ResultEvent
// GetCompiledOperators returns a list of the compiled operators
GetCompiledOperators() []*operators.Operators
// Type returns the type of the protocol request
Type() templateTypes.ProtocolType
}
// OutputEventCallback is a callback event for any results found during scanning.
type OutputEventCallback func(result *output.InternalWrappedEvent)
func MakeDefaultResultEvent(request Request, wrapped *output.InternalWrappedEvent) []*output.ResultEvent {
// Note: operator result is generated if something was succesfull match/extract/dynamic-extract
// but results should not be generated if
// 1. no match was found and some dynamic values were extracted
// 2. if something was extracted (matchers exist but no match was found)
if len(wrapped.OperatorsResult.DynamicValues) > 0 && !wrapped.OperatorsResult.Matched {
return nil
}
// check if something was extracted (except dynamic values)
extracted := len(wrapped.OperatorsResult.Extracts) > 0 || len(wrapped.OperatorsResult.OutputExtracts) > 0
if extracted && len(wrapped.OperatorsResult.Operators.Matchers) > 0 && !wrapped.OperatorsResult.Matched {
// if extracted and matchers exist but no match was found then don't generate result
return nil
}
results := make([]*output.ResultEvent, 0, len(wrapped.OperatorsResult.Matches)+1)
// If we have multiple matchers with names, write each of them separately.
if len(wrapped.OperatorsResult.Matches) > 0 {
for matcherNames := range wrapped.OperatorsResult.Matches {
data := request.MakeResultEventItem(wrapped)
data.MatcherName = matcherNames
results = append(results, data)
}
} else if len(wrapped.OperatorsResult.Extracts) > 0 {
for k, v := range wrapped.OperatorsResult.Extracts {
data := request.MakeResultEventItem(wrapped)
data.ExtractorName = k
data.ExtractedResults = v
results = append(results, data)
}
} else {
data := request.MakeResultEventItem(wrapped)
results = append(results, data)
}
return results
}
2021-10-29 18:26:06 +05:30
// MakeDefaultExtractFunc performs extracting operation for an extractor on model and returns true or false.
func MakeDefaultExtractFunc(data map[string]interface{}, extractor *extractors.Extractor) map[string]struct{} {
part := extractor.Part
if part == "" {
part = "response"
}
item, ok := data[part]
2022-04-20 11:32:13 +02:00
if !ok && !extractors.SupportsMap(extractor) {
2021-10-29 18:26:06 +05:30
return nil
}
itemStr := types.ToString(item)
switch extractor.GetType() {
case extractors.RegexExtractor:
return extractor.ExtractRegex(itemStr)
case extractors.KValExtractor:
return extractor.ExtractKval(data)
case extractors.JSONExtractor:
return extractor.ExtractJSON(itemStr)
case extractors.XPathExtractor:
return extractor.ExtractXPath(itemStr)
2022-04-20 11:32:13 +02:00
case extractors.DSLExtractor:
return extractor.ExtractDSL(data)
2021-10-29 18:26:06 +05:30
}
return nil
}
// MakeDefaultMatchFunc performs matching operation for a matcher on model and returns true or false.
func MakeDefaultMatchFunc(data map[string]interface{}, matcher *matchers.Matcher) (bool, []string) {
part := matcher.Part
if part == "" {
part = "response"
}
2021-11-08 16:10:04 +05:30
partItem, ok := data[part]
if !ok && matcher.Type.MatcherType != matchers.DSLMatcher {
2021-10-29 18:26:06 +05:30
return false, nil
}
item := types.ToString(partItem)
switch matcher.GetType() {
case matchers.SizeMatcher:
result := matcher.Result(matcher.MatchSize(len(item)))
return result, nil
case matchers.WordsMatcher:
2021-11-03 18:58:00 +05:30
return matcher.ResultWithMatchedSnippet(matcher.MatchWords(item, nil))
2021-10-29 18:26:06 +05:30
case matchers.RegexMatcher:
2021-11-03 18:58:00 +05:30
return matcher.ResultWithMatchedSnippet(matcher.MatchRegex(item))
2021-10-29 18:26:06 +05:30
case matchers.BinaryMatcher:
2021-11-03 18:58:00 +05:30
return matcher.ResultWithMatchedSnippet(matcher.MatchBinary(item))
2021-10-29 18:26:06 +05:30
case matchers.DSLMatcher:
return matcher.Result(matcher.MatchDSL(data)), nil
case matchers.XPathMatcher:
return matcher.Result(matcher.MatchXPath(item)), []string{}
2021-10-29 18:26:06 +05:30
}
return false, nil
}
func (e *ExecutorOptions) EncodeTemplate() string {
if !e.Options.OmitTemplate && len(e.RawTemplate) <= MaxTemplateFileSizeForEncoding {
return base64.StdEncoding.EncodeToString(e.RawTemplate)
}
return ""
}
Remove singletons from Nuclei engine (continuation of #6210) (#6296) * introducing execution id * wip * . * adding separate execution context id * lint * vet * fixing pg dialers * test ignore * fixing loader FD limit * test * fd fix * wip: remove CloseProcesses() from dev merge * wip: fix merge issue * protocolstate: stop memguarding on last dialer delete * avoid data race in dialers.RawHTTPClient * use shared logger and avoid race conditions * use shared logger and avoid race conditions * go mod * patch executionId into compiled template cache * clean up comment in Parse * go mod update * bump echarts * address merge issues * fix use of gologger * switch cmd/nuclei to options.Logger * address merge issues with go.mod * go vet: address copy of lock with new Copy function * fixing tests * disable speed control * fix nil ExecuterOptions * removing deprecated code * fixing result print * default logger * cli default logger * filter warning from results * fix performance test * hardcoding path * disable upload * refactor(runner): uses `Warning` instead of `Print` for `pdcpUploadErrMsg` Signed-off-by: Dwi Siswanto <git@dw1.io> * Revert "disable upload" This reverts commit 114fbe6663361bf41cf8b2645fd2d57083d53682. * Revert "hardcoding path" This reverts commit cf12ca800e0a0e974bd9fd4826a24e51547f7c00. --------- Signed-off-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Mzack9999 <mzack9999@protonmail.com> Co-authored-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Dwi Siswanto <25837540+dwisiswant0@users.noreply.github.com>
2025-07-09 14:47:26 -05:00
// ApplyNewEngineOptions updates an existing ExecutorOptions with options from a new engine. This
// handles things like the ExecutionID that need to be updated.
func (e *ExecutorOptions) ApplyNewEngineOptions(n *ExecutorOptions) {
// TODO: cached code|headless templates have nil ExecuterOptions if -code or -headless are not enabled
if e == nil || n == nil || n.Options == nil {
return
}
// The types.Options include the ExecutionID among other things
e.Options = n.Options.Copy()
// Keep the template-specific fields, but replace the rest
/*
e.TemplateID = n.TemplateID
e.TemplatePath = n.TemplatePath
e.TemplateInfo = n.TemplateInfo
e.TemplateVerifier = n.TemplateVerifier
e.RawTemplate = n.RawTemplate
e.Variables = n.Variables
e.Constants = n.Constants
*/
e.Output = n.Output
e.Options = n.Options
e.IssuesClient = n.IssuesClient
e.Progress = n.Progress
e.RateLimiter = n.RateLimiter
e.Catalog = n.Catalog
e.ProjectFile = n.ProjectFile
e.Browser = n.Browser
e.Interactsh = n.Interactsh
e.HostErrorsCache = n.HostErrorsCache
e.StopAtFirstMatch = n.StopAtFirstMatch
e.ExcludeMatchers = n.ExcludeMatchers
e.InputHelper = n.InputHelper
e.FuzzParamsFrequency = n.FuzzParamsFrequency
e.FuzzStatsDB = n.FuzzStatsDB
e.DoNotCache = n.DoNotCache
e.Colorizer = n.Colorizer
e.WorkflowLoader = n.WorkflowLoader
e.ResumeCfg = n.ResumeCfg
e.ProtocolType = n.ProtocolType
e.Flow = n.Flow
e.IsMultiProtocol = n.IsMultiProtocol
e.templateCtxStore = n.templateCtxStore
e.JsCompiler = n.JsCompiler
e.AuthProvider = n.AuthProvider
e.TemporaryDirectory = n.TemporaryDirectory
e.Parser = n.Parser
e.ExportReqURLPattern = n.ExportReqURLPattern
e.GlobalMatchers = n.GlobalMatchers
e.Logger = n.Logger
e.CustomFastdialer = n.CustomFastdialer
Remove singletons from Nuclei engine (continuation of #6210) (#6296) * introducing execution id * wip * . * adding separate execution context id * lint * vet * fixing pg dialers * test ignore * fixing loader FD limit * test * fd fix * wip: remove CloseProcesses() from dev merge * wip: fix merge issue * protocolstate: stop memguarding on last dialer delete * avoid data race in dialers.RawHTTPClient * use shared logger and avoid race conditions * use shared logger and avoid race conditions * go mod * patch executionId into compiled template cache * clean up comment in Parse * go mod update * bump echarts * address merge issues * fix use of gologger * switch cmd/nuclei to options.Logger * address merge issues with go.mod * go vet: address copy of lock with new Copy function * fixing tests * disable speed control * fix nil ExecuterOptions * removing deprecated code * fixing result print * default logger * cli default logger * filter warning from results * fix performance test * hardcoding path * disable upload * refactor(runner): uses `Warning` instead of `Print` for `pdcpUploadErrMsg` Signed-off-by: Dwi Siswanto <git@dw1.io> * Revert "disable upload" This reverts commit 114fbe6663361bf41cf8b2645fd2d57083d53682. * Revert "hardcoding path" This reverts commit cf12ca800e0a0e974bd9fd4826a24e51547f7c00. --------- Signed-off-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Mzack9999 <mzack9999@protonmail.com> Co-authored-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Dwi Siswanto <25837540+dwisiswant0@users.noreply.github.com>
2025-07-09 14:47:26 -05:00
}