Skip to content

Commit

Permalink
Merge pull request #5745 from projectdiscovery/dev
Browse files Browse the repository at this point in the history
Nuclei v3.3.5
  • Loading branch information
ehsandeep authored Oct 19, 2024
2 parents 9c71f6e + 44f398c commit 8d0d288
Show file tree
Hide file tree
Showing 58 changed files with 1,121 additions and 236 deletions.
1 change: 1 addition & 0 deletions .github/auto_assign.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
addReviewers: true
reviewers:
- dogancanbakir
- dwisiswant0

numberOfReviewers: 1
skipKeywords:
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,9 @@ pkg/protocols/common/helpers/deserialization/testdata/ValueObject2.ser
vendor

# Headless `screenshot` action
*.png
*.png

# Profiling & tracing
*.prof
*.pprof
*.trace
43 changes: 33 additions & 10 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,26 +457,49 @@ func (template *Template) compileProtocolRequests(options protocols.ExecuterOpti
That's it, you've added a new protocol to Nuclei. The next good step would be to write integration tests which are described in `integration-tests` and `cmd/integration-tests` directories.


## Profiling Instructions
## Profiling and Tracing

To enable dumping of Memory profiling data, `-profile-mem` flag can be used along with path to a file. This writes a pprof formatted file which can be used for investigate resource usage with `pprof` tool.
To analyze Nuclei's performance and resource usage, you can generate memory profiles and trace files using the `-profile-mem` flag:

```console
$ nuclei -t nuclei-templates/ -u https://example.com -profile-mem mem.pprof
```bash
nuclei -t nuclei-templates/ -u https://example.com -profile-mem=nuclei-$(git describe --tags)
```

To view profile data in pprof, first install pprof. Then run the below command -
This command creates two files:

```console
$ go tool pprof mem.pprof
* `nuclei.prof`: Memory (heap) profile
* `nuclei.trace`: Execution trace

### Analyzing the Memory Profile

1. View the profile in the terminal:

```bash
go tool pprof nuclei.prof
```

2. Display top memory consumers:

```bash
go tool pprof -top nuclei.prof | grep "$(go list -m)" | head -10
```

To open a web UI on a port to visualize debug data, the below command can be used.
3. Visualize the profile in a web browser:

```console
$ go tool pprof -http=:8081 mem.pprof
```bash
go tool pprof -http=:$(shuf -i 1000-99999 -n 1) nuclei.prof
```

### Analyzing the Trace File

To examine the execution trace:

```bash
go tool trace nuclei.trace
```

These tools help identify performance bottlenecks and memory leaks, allowing for targeted optimizations of Nuclei's codebase.

## Project Structure

- [pkg/reporting](./pkg/reporting) - Reporting modules for nuclei.
Expand Down
372 changes: 252 additions & 120 deletions README.md

Large diffs are not rendered by default.

52 changes: 50 additions & 2 deletions SYNTAX-REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1651,6 +1651,19 @@ FuzzPreConditionOperator is the operator between multiple PreConditions for fuzz

<hr />

<div class="dd">

<code>global-matchers</code> <i>bool</i>

</div>
<div class="dt">

GlobalMatchers marks matchers as static and applies globally to all result events from other templates

</div>

<hr />




Expand Down Expand Up @@ -3210,6 +3223,19 @@ read-all: false

<hr />

<div class="dd">

<code>stop-at-first-match</code> <i>bool</i>

</div>
<div class="dt">

StopAtFirstMatch stops the execution of the requests and template as soon as a match is found.

</div>

<hr />




Expand Down Expand Up @@ -3764,11 +3790,33 @@ Appears in:
Part Definitions:


- <code>template-id</code> - ID of the template executed
- <code>template-info</code> - Info Block of the template executed
- <code>template-path</code> - Path of the template executed
- <code>host</code> - Host is the input to the template
- <code>port</code> - Port is the port of the host
- <code>matched</code> - Matched is the input which was matched upon
- <code>type</code> - Type is the type of request made
- <code>timestamp</code> - Timestamp is the time when the request was made
- <code>response</code> - JSON SSL protocol handshake details
- <code>cipher</code> - Cipher is the encryption algorithm used
- <code>domains</code> - Domains are the list of domain names in the certificate
- <code>fingerprint_hash</code> - Fingerprint hash is the unique identifier of the certificate
- <code>ip</code> - IP is the IP address of the server
- <code>issuer_cn</code> - Issuer CN is the common name of the certificate issuer
- <code>issuer_dn</code> - Issuer DN is the distinguished name of the certificate issuer
- <code>issuer_org</code> - Issuer organization is the organization of the certificate issuer
- <code>not_after</code> - Timestamp after which the remote cert expires
- <code>host</code> - Host is the input to the template
- <code>matched</code> - Matched is the input which was matched upon
- <code>not_before</code> - Timestamp before which the certificate is not valid
- <code>probe_status</code> - Probe status indicates if the probe was successful
- <code>serial</code> - Serial is the serial number of the certificate
- <code>sni</code> - SNI is the server name indication used in the handshake
- <code>subject_an</code> - Subject AN is the list of subject alternative names
- <code>subject_cn</code> - Subject CN is the common name of the certificate subject
- <code>subject_dn</code> - Subject DN is the distinguished name of the certificate subject
- <code>subject_org</code> - Subject organization is the organization of the certificate subject
- <code>tls_connection</code> - TLS connection is the type of TLS connection used
- <code>tls_version</code> - TLS version is the version of the TLS protocol used

<hr />

Expand Down
11 changes: 11 additions & 0 deletions cmd/nuclei/issue-tracker-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,14 @@
# duplicate-issue-check: false
# # open-state-id is the ID of the open state in Linear
# open-state-id: ""
#mongodb:
# # the connection string to the MongoDB database
# # (e.g., mongodb://root:example@localhost:27017/nuclei?ssl=false&authSource=admin)
# connection-string: ""
# # the name of the collection to store the issues
# collection-name: ""
# # excludes the Request and Response from the results (helps with filesize)
# omit-raw: false
# # determines the number of results to be kept in memory before writing it to the database or 0 to
# # persist all in memory and write all results at the end (default)
# batch-size: 0
41 changes: 31 additions & 10 deletions cmd/nuclei/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"path/filepath"
"runtime"
"runtime/pprof"
"runtime/trace"
"strings"
"time"

Expand Down Expand Up @@ -103,21 +104,40 @@ func main() {
return
}

// Profiling related code
// Profiling & tracing related code
if memProfile != "" {
f, err := os.Create(memProfile)
memProfile = strings.TrimSuffix(memProfile, filepath.Ext(memProfile)) + ".prof"
memProfileFile, err := os.Create(memProfile)
if err != nil {
gologger.Fatal().Msgf("profile: could not create memory profile %q: %v", memProfile, err)
gologger.Fatal().Msgf("profile: could not create memory profile %q file: %v", memProfile, err)
}
old := runtime.MemProfileRate

traceFilepath := strings.TrimSuffix(memProfile, filepath.Ext(memProfile)) + ".trace"
traceFile, err := os.Create(traceFilepath)
if err != nil {
gologger.Fatal().Msgf("profile: could not create trace %q file: %v", traceFilepath, err)
}

oldMemProfileRate := runtime.MemProfileRate
runtime.MemProfileRate = 4096
gologger.Print().Msgf("profile: memory profiling enabled (rate %d), %s", runtime.MemProfileRate, memProfile)

// Start tracing
if err := trace.Start(traceFile); err != nil {
gologger.Fatal().Msgf("profile: could not start trace: %v", err)
}

defer func() {
_ = pprof.Lookup("heap").WriteTo(f, 0)
f.Close()
runtime.MemProfileRate = old
gologger.Print().Msgf("profile: memory profiling disabled, %s", memProfile)
// Start CPU profiling
if err := pprof.WriteHeapProfile(memProfileFile); err != nil {
gologger.Fatal().Msgf("profile: could not start CPU profile: %v", err)
}
memProfileFile.Close()
traceFile.Close()
trace.Stop()
runtime.MemProfileRate = oldMemProfileRate

gologger.Info().Msgf("Memory profile saved at %q", memProfile)
gologger.Info().Msgf("Traced at %q", traceFilepath)
}()
}

Expand Down Expand Up @@ -402,9 +422,10 @@ on extensive configurability, massive extensibility and ease of use.`)
flagSet.CallbackVar(printVersion, "version", "show nuclei version"),
flagSet.BoolVarP(&options.HangMonitor, "hang-monitor", "hm", false, "enable nuclei hang monitoring"),
flagSet.BoolVarP(&options.Verbose, "verbose", "v", false, "show verbose output"),
flagSet.StringVar(&memProfile, "profile-mem", "", "optional nuclei memory profile dump file"),
flagSet.StringVar(&memProfile, "profile-mem", "", "generate memory (heap) profile & trace files"),
flagSet.BoolVar(&options.VerboseVerbose, "vv", false, "display templates loaded for scan"),
flagSet.BoolVarP(&options.ShowVarDump, "show-var-dump", "svd", false, "show variables dump for debugging"),
flagSet.IntVarP(&options.VarDumpLimit, "var-dump-limit", "vdl", 255, "limit the number of characters displayed in var dump"),
flagSet.BoolVarP(&options.EnablePprof, "enable-pprof", "ep", false, "enable pprof debugging server"),
flagSet.CallbackVarP(printTemplateVersion, "templates-version", "tv", "shows the version of the installed nuclei-templates"),
flagSet.BoolVarP(&options.HealthCheck, "health-check", "hc", false, "run diagnostic check up"),
Expand Down
8 changes: 4 additions & 4 deletions gh_retry.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ WORKFLOW="Build Test"
GREP_ERROR_PATTERN='Test "http/interactsh.yaml" failed'

#Set fonts for Help.
NORM=`tput sgr0`
BOLD=`tput bold`
REV=`tput smso`
NORM=$(tput sgr0)
BOLD=$(tput bold)
REV=$(tput smso)

HELP()
{
Expand Down Expand Up @@ -73,7 +73,7 @@ function print_bold() {
function retry_failed_jobs() {
print_bold "Checking failed workflows for branch $BRANCH before $BEFORE"

date=`date +%Y-%m-%d'T'%H:%M'Z' -d "$BEFORE"`
date=$(date +%Y-%m-%d'T'%H:%M'Z' -d "$BEFORE")

workflowIds=$(gh run list --limit "$LIMIT" --json headBranch,status,name,conclusion,databaseId,updatedAt | jq -c '.[] |
select ( .headBranch==$branch ) |
Expand Down
9 changes: 8 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/projectdiscovery/nuclei/v3

go 1.21
go 1.21.0

require (
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible
Expand Down Expand Up @@ -104,7 +104,9 @@ require (
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466
github.com/stretchr/testify v1.9.0
github.com/tarunKoyalwar/goleak v0.0.0-20240429141123-0efa90dbdcf9
github.com/yassinebenaid/godump v0.10.0
github.com/zmap/zgrab2 v0.1.8-0.20230806160807-97ba87c0e706
go.mongodb.org/mongo-driver v1.17.0
golang.org/x/term v0.24.0
gopkg.in/yaml.v3 v3.0.1
moul.io/http2curl v1.0.0
Expand Down Expand Up @@ -195,6 +197,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
Expand Down Expand Up @@ -228,9 +231,13 @@ require (
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
github.com/ysmood/fetchup v0.2.3 // indirect
github.com/ysmood/got v0.34.1 // indirect
github.com/yuin/goldmark v1.7.4 // indirect
Expand Down
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
Expand Down Expand Up @@ -1085,6 +1087,12 @@ github.com/xanzy/go-gitlab v0.107.0 h1:P2CT9Uy9yN9lJo3FLxpMZ4xj6uWcpnigXsjvqJ6nd
github.com/xanzy/go-gitlab v0.107.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
Expand All @@ -1096,8 +1104,12 @@ github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yassinebenaid/godump v0.10.0 h1:FolBA+Ix5uwUiXYBBYOsf1VkT5+0f4gtFNTkYTiIR08=
github.com/yassinebenaid/godump v0.10.0/go.mod h1:dc/0w8wmg6kVIvNGAzbKH1Oa54dXQx8SNKh4dPRyW44=
github.com/yl2chen/cidranger v1.0.2 h1:lbOWZVCG1tCRX4u24kuM1Tb4nHqWkDxwLdoS+SevawU=
github.com/yl2chen/cidranger v1.0.2/go.mod h1:9U1yz7WPYDwf0vpNWFaeRh0bjwz5RVgRy/9UEQfHl0g=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
github.com/ysmood/fetchup v0.2.3 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ=
github.com/ysmood/fetchup v0.2.3/go.mod h1:xhibcRKziSvol0H1/pj33dnKrYyI2ebIvz5cOOkYGns=
github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ=
Expand Down Expand Up @@ -1150,6 +1162,8 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0=
go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.mongodb.org/mongo-driver v1.17.0 h1:Hp4q2MCjvY19ViwimTs00wHi7G4yzxh4/2+nTx8r40k=
go.mongodb.org/mongo-driver v1.17.0/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
Expand Down
1 change: 1 addition & 0 deletions internal/runner/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func ParseOptions(options *types.Options) {

if options.ShowVarDump {
vardump.EnableVarDump = true
vardump.Limit = options.VarDumpLimit
}
if options.ShowActions {
gologger.Info().Msgf("Showing available headless actions: ")
Expand Down
2 changes: 2 additions & 0 deletions internal/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/automaticscan"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
"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/protocolinit"
Expand Down Expand Up @@ -475,6 +476,7 @@ func (r *Runner) RunEnumeration() error {
TemporaryDirectory: r.tmpDir,
Parser: r.parser,
FuzzParamsFrequency: fuzzFreqCache,
GlobalMatchers: globalmatchers.New(),
}

if config.DefaultConfig.IsDebugArgEnabled(config.DebugExportURLPattern) {
Expand Down
1 change: 1 addition & 0 deletions lib/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func (e *NucleiEngine) LoadAllTemplates() error {
return errorutil.New("Could not create loader client: %s\n", err)
}
e.store.Load()
e.templatesLoaded = true
return nil
}

Expand Down
2 changes: 2 additions & 0 deletions lib/sdk_private.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package nuclei
import (
"context"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/input"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -171,6 +172,7 @@ func (e *NucleiEngine) init(ctx context.Context) error {
ResumeCfg: types.NewResumeCfg(),
Browser: e.browserInstance,
Parser: e.parser,
InputHelper: input.NewHelper(),
}
if len(e.opts.SecretsFile) > 0 {
authTmplStore, err := runner.GetAuthTmplStore(*e.opts, e.catalog, e.executerOpts)
Expand Down
Loading

0 comments on commit 8d0d288

Please sign in to comment.