Merge branch 'dev' into maint-memory

dev
mzack 2024-03-05 01:26:06 +01:00
commit 52beea3bcd
79 changed files with 1488 additions and 562 deletions

View File

@ -42,4 +42,7 @@ jsupdate:
ts:
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "tsgen" pkg/js/devtools/tsgen/cmd/tsgen/main.go
./tsgen -dir pkg/js/libs -out pkg/js/generated/ts
memogen:
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "memogen" cmd/memogen/memogen.go
./memogen -src pkg/js/libs -tpl cmd/memogen/function.tpl

View File

@ -128,6 +128,7 @@ requests:
path:
- '{{BaseURL}}/.git/config'
method: GET
self-contained: false
```
@ -987,6 +988,7 @@ matchers-condition: and
path:
- '{{BaseURL}}/.git/config'
method: GET
self-contained: false
```
Part Definitions:
@ -1372,6 +1374,19 @@ Fuzzing describes schema to fuzz http requests
<div class="dd">
<code>self-contained</code> <i>bool</i>
</div>
<div class="dt">
SelfContained specifies if the request is self-contained.
</div>
<hr />
<div class="dd">
<code>signature</code> <i><a href="#signaturetypeholder">SignatureTypeHolder</a></i>
</div>

28
cmd/memogen/function.tpl Normal file
View File

@ -0,0 +1,28 @@
// Warning - This is generated code
package {{.SourcePackage}}
import (
"github.com/projectdiscovery/utils/memoize"
{{range .Imports}}
{{.Name}} {{.Path}}
{{end}}
)
{{range .Functions}}
{{ .SignatureWithPrefix "memoized" }} {
hash := "{{ .Name }}" {{range .Params}} + ":" + fmt.Sprint({{.Name}}) {{end}}
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return {{.Name}}({{.ParamsNames}})
})
if err != nil {
return {{.ResultFirstFieldDefaultValue}}, err
}
if value, ok := v.({{.ResultFirstFieldType}}); ok {
return value, nil
}
return {{.ResultFirstFieldDefaultValue}}, errors.New("could not convert cached result")
}
{{end}}

77
cmd/memogen/memogen.go Normal file
View File

@ -0,0 +1,77 @@
// this small cli tool is specific for those functions with arbitrary parameters and with result-error tuple as return values
// func(x,y) => result, error
// it works by creating a new memoized version of the functions in the same path as memo.original.file.go
// some parts are specific for nuclei and hardcoded within the template
package main
import (
"flag"
"io/fs"
"log"
"os"
"path/filepath"
"github.com/projectdiscovery/utils/memoize"
stringsutil "github.com/projectdiscovery/utils/strings"
)
var (
srcPath = flag.String("src", "", "nuclei source path")
tplPath = flag.String("tpl", "function.tpl", "template path")
tplSrc []byte
)
func main() {
flag.Parse()
var err error
tplSrc, err = os.ReadFile(*tplPath)
if err != nil {
log.Fatal(err)
}
err = filepath.Walk(*srcPath, walk)
if err != nil {
log.Fatal(err)
}
}
func walk(path string, info fs.FileInfo, err error) error {
if info.IsDir() {
return nil
}
if err != nil {
return err
}
ext := filepath.Ext(path)
base := filepath.Base(path)
if !stringsutil.EqualFoldAny(ext, ".go") {
return nil
}
basePath := filepath.Dir(path)
outPath := filepath.Join(basePath, "memo."+base)
// filename := filepath.Base(path)
data, err := os.ReadFile(path)
if err != nil {
return err
}
if !stringsutil.ContainsAnyI(string(data), "@memo") {
return nil
}
log.Println("processing:", path)
out, err := memoize.Src(string(tplSrc), path, data, "")
if err != nil {
return err
}
if err := os.WriteFile(outPath, out, os.ModePerm); err != nil {
return err
}
return nil
}

View File

@ -1,3 +1,8 @@
# global allow/deny list. this will affect both exporters
# as well as issue trackers. you can filter trackers with
# a tracker level filter on top of an exporter by setting
# allow-list/deny-list per tracker.
#
#allow-list:
# severity: high, critical
#deny-list:
@ -17,6 +22,15 @@
# project-name: test-project
# # issue-label is the label of the created issue type
# issue-label: bug
# # allow-list sets a tracker level filter to only create issues for templates with
# # these severity labels or tags (does not affect exporters. set those globally)
# allow-list:
# severity: high, critical
# tags: network
# # deny-list sets a tracker level filter to never create issues for templates with
# # these severity labels or tags (does not affect exporters. set those globally)
# deny-list:
# severity: low
# # duplicate-issue-check flag to enable duplicate tracking issue check.
# duplicate-issue-check: false
#
@ -32,6 +46,15 @@
# project-name: "1234"
# # issue-label is the label of the created issue type
# issue-label: bug
# # allow-list sets a tracker level filter to only create issues for templates with
# # these severity labels or tags (does not affect exporters. set those globally)
# allow-list:
# severity: high, critical
# tags: network
# # deny-list sets a tracker level filter to never create issues for templates with
# # these severity labels or tags (does not affect exporters. set those globally)
# deny-list:
# severity: low
#
# Gitea contains configuration options for a gitea issue tracker
#gitea:
@ -47,6 +70,15 @@
# issue-label: bug
# # severity-as-label (optional) adds the severity as a label of the created issue
# severity-as-label: true
# # allow-list sets a tracker level filter to only create issues for templates with
# # these severity labels or tags (does not affect exporters. set those globally)
# allow-list:
# severity: high, critical
# tags: network
# # deny-list sets a tracker level filter to never create issues for templates with
# # these severity labels or tags (does not affect exporters. set those globally)
# deny-list:
# severity: low
# # duplicate-issue-check (optional) flag to enable duplicate tracking issue check
# duplicate-issue-check: false
#
@ -71,6 +103,15 @@
# # SeverityAsLabel (optional) sends the severity as the label of the created issue
# # User custom fields for Jira Cloud instead
# severity-as-label: true
# # allow-list sets a tracker level filter to only create issues for templates with
# # these severity labels or tags (does not affect exporters. set those globally)
# allow-list:
# severity: high, critical
# tags: network
# # deny-list sets a tracker level filter to never create issues for templates with
# # these severity labels or tags (does not affect exporters. set those globally)
# deny-list:
# severity: low
# # Whatever your final status is that you want to use as a closed ticket - Closed, Done, Remediated, etc
# # When checking for duplicates, the JQL query will filter out status's that match this.
# # If it finds a match _and_ the ticket does have this status, a new one will be created.

16
go.mod
View File

@ -23,8 +23,8 @@ require (
github.com/projectdiscovery/fastdialer v0.0.60
github.com/projectdiscovery/hmap v0.0.40
github.com/projectdiscovery/interactsh v1.1.8
github.com/projectdiscovery/rawhttp v0.1.35
github.com/projectdiscovery/retryabledns v1.0.57
github.com/projectdiscovery/rawhttp v0.1.39
github.com/projectdiscovery/retryabledns v1.0.58
github.com/projectdiscovery/retryablehttp-go v1.0.49
github.com/projectdiscovery/yamldoc-go v1.0.4
github.com/remeh/sizedwaitgroup v1.0.0
@ -79,11 +79,11 @@ require (
github.com/projectdiscovery/dsl v0.0.44
github.com/projectdiscovery/fasttemplate v0.0.2
github.com/projectdiscovery/go-smb2 v0.0.0-20240129202741-052cc450c6cb
github.com/projectdiscovery/goflags v0.1.40
github.com/projectdiscovery/goflags v0.1.42
github.com/projectdiscovery/gologger v1.1.12
github.com/projectdiscovery/gostruct v0.0.2
github.com/projectdiscovery/gozero v0.0.1
github.com/projectdiscovery/httpx v1.3.9
github.com/projectdiscovery/httpx v1.5.0
github.com/projectdiscovery/mapcidr v1.1.16
github.com/projectdiscovery/n3iwf v0.0.0-20230523120440-b8cd232ff1f5
github.com/projectdiscovery/ratelimit v0.0.27
@ -91,9 +91,9 @@ require (
github.com/projectdiscovery/sarif v0.0.1
github.com/projectdiscovery/tlsx v1.1.6
github.com/projectdiscovery/uncover v1.0.7
github.com/projectdiscovery/useragent v0.0.39
github.com/projectdiscovery/useragent v0.0.40
github.com/projectdiscovery/utils v0.0.83-0.20240305000020-ff30de2464cd
github.com/projectdiscovery/wappalyzergo v0.0.111
github.com/projectdiscovery/wappalyzergo v0.0.112
github.com/redis/go-redis/v9 v9.1.0
github.com/sashabaranov/go-openai v1.15.3
github.com/stretchr/testify v1.8.4
@ -124,12 +124,12 @@ require (
github.com/bits-and-blooms/bloom/v3 v3.5.0 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cheggaaa/pb/v3 v3.1.4 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/cloudflare/cfssl v1.6.4 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/continuity v0.4.2 // indirect
github.com/corpix/uarand v0.2.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davidmz/go-pageant v1.0.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
@ -184,7 +184,7 @@ require (
github.com/pierrec/lz4/v4 v4.1.2 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/projectdiscovery/asnmap v1.0.6 // indirect
github.com/projectdiscovery/asnmap v1.1.0 // indirect
github.com/projectdiscovery/cdncheck v1.0.9 // indirect
github.com/projectdiscovery/freeport v0.0.5 // indirect
github.com/projectdiscovery/machineid v0.0.0-20240226150047-2e2c51e35983 // indirect

35
go.sum
View File

@ -78,6 +78,8 @@ github.com/Mzack9999/ldapserver v1.0.2-0.20211229000134-b44a0d6ad0dd h1:RTWs+wEY
github.com/Mzack9999/ldapserver v1.0.2-0.20211229000134-b44a0d6ad0dd/go.mod h1:AqtPw7WNT0O69k+AbPKWVGYeW94TqgMW/g+Ppc8AZr4=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
@ -211,6 +213,8 @@ github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
@ -246,8 +250,6 @@ github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/corpix/uarand v0.2.0 h1:U98xXwud/AVuCpkpgfPF7J5TQgr7R5tqT8VZP5KWbzE=
github.com/corpix/uarand v0.2.0/go.mod h1:/3Z1QIqWkDIhf6XWn/08/uMHoQ8JUoTIKc2iPchBOmM=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@ -802,8 +804,8 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/praetorian-inc/fingerprintx v1.1.9 h1:zWbG/Fdan0s/dvXkeaHb/CdFTz/yEEzrAF4iCzok3r8=
github.com/praetorian-inc/fingerprintx v1.1.9/go.mod h1:k6EJIHe/Da4DH5e4JuoZHe+qSGq/KPUmXGaK+xW74OI=
github.com/projectdiscovery/asnmap v1.0.6 h1:NZj1hybBf4KF/hMCgJ6E2GXCe60tg5fIRkexEIU+0og=
github.com/projectdiscovery/asnmap v1.0.6/go.mod h1:cXQjWMgxkl+8A4861Nms9u+ASxQLTb47imJD+AyX+dU=
github.com/projectdiscovery/asnmap v1.1.0 h1:ynvbLB5cNpyQ2+k9IP0Rpla+0JmCJpd3mw6KLAW13m0=
github.com/projectdiscovery/asnmap v1.1.0/go.mod h1:QNjBnGLxUBEZAgaYk/Av5cjKKWFY3i/FOfoIWCUApoY=
github.com/projectdiscovery/blackrock v0.0.1 h1:lHQqhaaEFjgf5WkuItbpeCZv2DUIE45k0VbGJyft6LQ=
github.com/projectdiscovery/blackrock v0.0.1/go.mod h1:ANUtjDfaVrqB453bzToU+YB4cUbvBRpLvEwoWIwlTss=
github.com/projectdiscovery/cdncheck v1.0.9 h1:BS15gzj9gb5AVSKqTDzPamfSgStu7nJQOocUvrssFlg=
@ -820,8 +822,8 @@ github.com/projectdiscovery/freeport v0.0.5 h1:jnd3Oqsl4S8n0KuFkE5Hm8WGDP24ITBvm
github.com/projectdiscovery/freeport v0.0.5/go.mod h1:PY0bxSJ34HVy67LHIeF3uIutiCSDwOqKD8ruBkdiCwE=
github.com/projectdiscovery/go-smb2 v0.0.0-20240129202741-052cc450c6cb h1:rutG906Drtbpz4DwU5mhGIeOhRcktDH4cGQitGUMAsg=
github.com/projectdiscovery/go-smb2 v0.0.0-20240129202741-052cc450c6cb/go.mod h1:FLjF1DmZ+POoGEiIQdWuYVwS++C/GwpX8YaCsTSm1RY=
github.com/projectdiscovery/goflags v0.1.40 h1:yQCB0m0YxkonbkF7hRlRSGAeWEUJdJh5MLqW2gQFdps=
github.com/projectdiscovery/goflags v0.1.40/go.mod h1:lNrjzQPzSt06waiLmZuBfcusNdLHVvueCgGcSovE6d4=
github.com/projectdiscovery/goflags v0.1.42 h1:C3CleYUODv5Jdn4+FTCUpzm3eOXHl+GiLHbXSw5iNsQ=
github.com/projectdiscovery/goflags v0.1.42/go.mod h1:UuS8nOpeYbVebPVWeTvcpILESC8daIwRVJ14UEt7L7c=
github.com/projectdiscovery/gologger v1.1.12 h1:uX/QkQdip4PubJjjG0+uk5DtyAi1ANPJUvpmimXqv4A=
github.com/projectdiscovery/gologger v1.1.12/go.mod h1:DI8nywPLERS5mo8QEA9E7gd5HZ3Je14SjJBH3F5/kLw=
github.com/projectdiscovery/gostruct v0.0.2 h1:s8gP8ApugGM4go1pA+sVlPDXaWqNP5BBDDSv7VEdG1M=
@ -830,8 +832,8 @@ github.com/projectdiscovery/gozero v0.0.1 h1:f08ZnYlbDZV/TNGDvIXV9s/oB/sAI+HWaSb
github.com/projectdiscovery/gozero v0.0.1/go.mod h1:/dHwbly+1lhOX9UreVure4lEe7K4hIHeu/c/wZGNTDo=
github.com/projectdiscovery/hmap v0.0.40 h1:WGAIXXMY2vbV0ep7Q8s27Up/ejs8Wo1hh5AEhynLfmw=
github.com/projectdiscovery/hmap v0.0.40/go.mod h1:5JkQW9t/UNK95YEY6irOXHqrS/xVBUtrYEhtq61ttII=
github.com/projectdiscovery/httpx v1.3.9 h1:jDdoGH+5VVU/jI6dnai1DKNw9USPyCcw+tDh4RCVQ2g=
github.com/projectdiscovery/httpx v1.3.9/go.mod h1:a/a5X6e2NLnS/+b3buFadGUpZSolnVkMA7KZdpCdg58=
github.com/projectdiscovery/httpx v1.5.0 h1:YJziMpdF2G5Iy7sDd1mNSpB5LyohYWZpqk+Oq2TeUQQ=
github.com/projectdiscovery/httpx v1.5.0/go.mod h1:cB6PODFnhLWL9yBKauqXheesBqVbnwnyvF+J/i4y/VQ=
github.com/projectdiscovery/interactsh v1.1.8 h1:mDD+f/oo2tV4Z1WyUync0tgYeJyuiS89Un64Gm6Pvgk=
github.com/projectdiscovery/interactsh v1.1.8/go.mod h1:E20ywFb7bL01GcOOk+6VZF48XZ8AZvYvBpULoBUSTbg=
github.com/projectdiscovery/machineid v0.0.0-20240226150047-2e2c51e35983 h1:ZScLodGSezQVwsQDtBSMFp72WDq0nNN+KE/5DHKY5QE=
@ -844,12 +846,12 @@ github.com/projectdiscovery/networkpolicy v0.0.7 h1:AwHqBRXBqDQgnWzBMuoJtHBNEYBw
github.com/projectdiscovery/networkpolicy v0.0.7/go.mod h1:CK0CnFoLF1Nou6mY7P4WODSAxhPN8g8g7XpapgEP8tI=
github.com/projectdiscovery/ratelimit v0.0.27 h1:McTgnl8CtaEPmPtb9JG7EfgaQ1Rhu0pHa0Kf5Kld6Xs=
github.com/projectdiscovery/ratelimit v0.0.27/go.mod h1:5suG3x1d5+UV4xe2RBE/QCvQkz8CaxPvdwztjab3GzM=
github.com/projectdiscovery/rawhttp v0.1.35 h1:9Hkbu1WLN5coj6+HBaqi26PjMNFnw1XrMvJUS/G40OM=
github.com/projectdiscovery/rawhttp v0.1.35/go.mod h1:9mS0N3BfOBYwQWgyI+bXBaFVMFBtJVTcZF0FENea7mA=
github.com/projectdiscovery/rawhttp v0.1.39 h1:UYtDx5J9wqn7OFte66viag7cL757z1HU94jCya3V70s=
github.com/projectdiscovery/rawhttp v0.1.39/go.mod h1:gn0b2aa2DoxVx7GDzAfoBZPjisDmsXv6h/znGjOwChw=
github.com/projectdiscovery/rdap v0.9.1-0.20221108103045-9865884d1917 h1:m03X4gBVSorSzvmm0bFa7gDV4QNSOWPL/fgZ4kTXBxk=
github.com/projectdiscovery/rdap v0.9.1-0.20221108103045-9865884d1917/go.mod h1:JxXtZC9e195awe7EynrcnBJmFoad/BNDzW9mzFkK8Sg=
github.com/projectdiscovery/retryabledns v1.0.57 h1:+DOL9xYSIx74FRrOIKKHVp5R9ci53xHQN3jnncWVds4=
github.com/projectdiscovery/retryabledns v1.0.57/go.mod h1:qIigOcmO9d0Ce/z6mHzLl0Aiz2WJcNk2gUGhRcCQ1k4=
github.com/projectdiscovery/retryabledns v1.0.58 h1:ut1FSB9+GZ6zQIlKJFLqIz2RZs81EmkbsHTuIrWfYLE=
github.com/projectdiscovery/retryabledns v1.0.58/go.mod h1:RobmKoNBgngAVE4H9REQtaLP1pa4TCyypHy1MWHT1mY=
github.com/projectdiscovery/retryablehttp-go v1.0.49 h1:mvlvl2kTN+ctpDIRlusVWui7eyFlElBoKTr8crS7yvY=
github.com/projectdiscovery/retryablehttp-go v1.0.49/go.mod h1:VaJ7Au+1LP8C2u0qmx4NN1IdAxxkhoXpIcc9LAQzFo4=
github.com/projectdiscovery/sarif v0.0.1 h1:C2Tyj0SGOKbCLgHrx83vaE6YkzXEVrMXYRGLkKCr/us=
@ -860,12 +862,12 @@ github.com/projectdiscovery/tlsx v1.1.6 h1:iw2zwKbd2+kRQ8J1G4dLmS0CLyemd/tKz1Uzc
github.com/projectdiscovery/tlsx v1.1.6/go.mod h1:s7SRRFdrwIZBK/RXXZi4CR/CubqFSvp8h5Bk1srEZIo=
github.com/projectdiscovery/uncover v1.0.7 h1:ut+2lTuvmftmveqF5RTjMWAgyLj8ltPQC7siFy9sj0A=
github.com/projectdiscovery/uncover v1.0.7/go.mod h1:HFXgm1sRPuoN0D4oATljPIdmbo/EEh1wVuxQqo/dwFE=
github.com/projectdiscovery/useragent v0.0.39 h1:s2jyXdtjVo0MfYYkifx7irrOIoA0JhzhZaBkpcoWgV4=
github.com/projectdiscovery/useragent v0.0.39/go.mod h1:wO6GQImJ2IQ5K+GDggS/Rhg6IV9Z2Du6NbqC/um0g0w=
github.com/projectdiscovery/useragent v0.0.40 h1:1LUhReSGPkhqsM5n40OOC9dIoNqMGs1dyGFJcOmg2Fo=
github.com/projectdiscovery/useragent v0.0.40/go.mod h1:EvK1x3s948Gtqb/XOahXcauyejCL/rSgy5d1IAvsKT4=
github.com/projectdiscovery/utils v0.0.83-0.20240305000020-ff30de2464cd h1:7AvCjcfZFkYy1Cg7aoA2iqVCuG/n+OHBFWB2ELGNAiI=
github.com/projectdiscovery/utils v0.0.83-0.20240305000020-ff30de2464cd/go.mod h1:67zb3eUa96XlTpWDqnJhe7xVoDbyAwHb7ChkdooiQxQ=
github.com/projectdiscovery/wappalyzergo v0.0.111 h1:A1fLEycJ1zwvIVh3jCL1n5OaKn7KP+pHAsFqQYMXPZM=
github.com/projectdiscovery/wappalyzergo v0.0.111/go.mod h1:hc/o+fgM8KtdpFesjfBTmHTwsR+yBd+4kYZW/DGy/x8=
github.com/projectdiscovery/wappalyzergo v0.0.112 h1:QPpp5jmj1lqLd5mFdFKQ9VvcYhQNqyU9Mr+IB0US2zA=
github.com/projectdiscovery/wappalyzergo v0.0.112/go.mod h1:hc/o+fgM8KtdpFesjfBTmHTwsR+yBd+4kYZW/DGy/x8=
github.com/projectdiscovery/yamldoc-go v1.0.4 h1:eZoESapnMw6WAHiVgRwNqvbJEfNHEH148uthhFbG5jE=
github.com/projectdiscovery/yamldoc-go v1.0.4/go.mod h1:8PIPRcUD55UbtQdcfFR1hpIGRWG0P7alClXNGt1TBik=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@ -961,6 +963,7 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=

BIN
memogen Executable file

Binary file not shown.

View File

@ -914,6 +914,9 @@
"description": "Method is the HTTP Request Method"
},
"http.Request": {
"required": [
"self-contained"
],
"properties": {
"matchers": {
"items": {
@ -1043,6 +1046,9 @@
"title": "fuzzin rules for http fuzzing",
"description": "Fuzzing describes rule schema to fuzz http requests"
},
"self-contained": {
"type": "boolean"
},
"signature": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/http.SignatureTypeHolder",

View File

@ -15,12 +15,12 @@ func init() {
module.Set(
gojs.Objects{
// Functions
"IsOracle": lib_oracle.IsOracle,
// Var and consts
// Objects / Classes
"IsOracleResponse": gojs.GetClassConstructor[lib_oracle.IsOracleResponse](&lib_oracle.IsOracleResponse{}),
"OracleClient": gojs.GetClassConstructor[lib_oracle.OracleClient](&lib_oracle.OracleClient{}),
},
).Register()
}

View File

@ -15,12 +15,12 @@ func init() {
module.Set(
gojs.Objects{
// Functions
"IsPOP3": lib_pop3.IsPOP3,
// Var and consts
// Objects / Classes
"IsPOP3Response": gojs.GetClassConstructor[lib_pop3.IsPOP3Response](&lib_pop3.IsPOP3Response{}),
"Pop3Client": gojs.GetClassConstructor[lib_pop3.Pop3Client](&lib_pop3.Pop3Client{}),
},
).Register()
}

View File

@ -15,13 +15,14 @@ func init() {
module.Set(
gojs.Objects{
// Functions
"CheckRDPAuth": lib_rdp.CheckRDPAuth,
"IsRDP": lib_rdp.IsRDP,
// Var and consts
// Objects / Classes
"CheckRDPAuthResponse": gojs.GetClassConstructor[lib_rdp.CheckRDPAuthResponse](&lib_rdp.CheckRDPAuthResponse{}),
"IsRDPResponse": gojs.GetClassConstructor[lib_rdp.IsRDPResponse](&lib_rdp.IsRDPResponse{}),
"RDPClient": gojs.GetClassConstructor[lib_rdp.RDPClient](&lib_rdp.RDPClient{}),
},
).Register()
}

View File

@ -15,12 +15,12 @@ func init() {
module.Set(
gojs.Objects{
// Functions
"IsRsync": lib_rsync.IsRsync,
// Var and consts
// Objects / Classes
"IsRsyncResponse": gojs.GetClassConstructor[lib_rsync.IsRsyncResponse](&lib_rsync.IsRsyncResponse{}),
"RsyncClient": gojs.GetClassConstructor[lib_rsync.RsyncClient](&lib_rsync.RsyncClient{}),
},
).Register()
}

View File

@ -15,13 +15,14 @@ func init() {
module.Set(
gojs.Objects{
// Functions
"NewSMTPClient": lib_smtp.NewSMTPClient,
// Var and consts
// Objects / Classes
"IsSMTPResponse": gojs.GetClassConstructor[lib_smtp.IsSMTPResponse](&lib_smtp.IsSMTPResponse{}),
"SMTPClient": gojs.GetClassConstructor[lib_smtp.SMTPClient](&lib_smtp.SMTPClient{}),
"SMTPMessage": gojs.GetClassConstructor[lib_smtp.SMTPMessage](&lib_smtp.SMTPMessage{}),
"Client": lib_smtp.NewSMTPClient,
"SMTPMessage": gojs.GetClassConstructor[lib_smtp.SMTPMessage](&lib_smtp.SMTPMessage{}),
"SMTPResponse": gojs.GetClassConstructor[lib_smtp.SMTPResponse](&lib_smtp.SMTPResponse{}),
},
).Register()
}

View File

@ -15,12 +15,12 @@ func init() {
module.Set(
gojs.Objects{
// Functions
"IsTelnet": lib_telnet.IsTelnet,
// Var and consts
// Objects / Classes
"IsTelnetResponse": gojs.GetClassConstructor[lib_telnet.IsTelnetResponse](&lib_telnet.IsTelnetResponse{}),
"TelnetClient": gojs.GetClassConstructor[lib_telnet.TelnetClient](&lib_telnet.TelnetClient{}),
},
).Register()
}

View File

@ -15,12 +15,12 @@ func init() {
module.Set(
gojs.Objects{
// Functions
"IsVNC": lib_vnc.IsVNC,
// Var and consts
// Objects / Classes
"IsVNCResponse": gojs.GetClassConstructor[lib_vnc.IsVNCResponse](&lib_vnc.IsVNCResponse{}),
"VNCClient": gojs.GetClassConstructor[lib_vnc.VNCClient](&lib_vnc.VNCClient{}),
},
).Register()
}

View File

@ -96,6 +96,7 @@ export class IKEMessage {
* const ikev2 = require('nuclei/ikev2');
* const nonce = new ikev2.IKENonce();
* nonce.NonceData = [1, 2, 3];
* ```
*/
export interface IKENonce {

View File

@ -236,6 +236,8 @@ export interface Config {
*/
export interface EncTicketPart {
RenewTill?: Date,
CRealm?: string,
AuthTime?: Date,
@ -244,12 +246,6 @@ export interface EncTicketPart {
EndTime?: Date,
RenewTill?: Date,
Key?: EncryptionKey,
CName?: PrincipalName,
Transited?: TransitedEncoding,
CAddr?: HostAddress,
@ -257,6 +253,10 @@ export interface EncTicketPart {
AuthorizationData?: AuthorizationDataEntry,
Flags?: BitString,
Key?: EncryptionKey,
CName?: PrincipalName,
}
@ -306,9 +306,9 @@ export interface EnumerateUserResponse {
*/
export interface HostAddress {
Address?: Uint8Array,
AddrType?: number,
Address?: Uint8Array,
}
@ -318,65 +318,67 @@ export interface HostAddress {
*/
export interface LibDefaults {
DefaultTGSEnctypes?: string[],
/**
* time in nanoseconds
*/
DefaultTktEnctypes?: string[],
Clockskew?: number,
K5LoginDirectory?: string,
RealmTryDomains?: number,
Canonicalize?: boolean,
K5LoginAuthoritative?: boolean,
NoAddresses?: boolean,
KDCTimeSync?: number,
SafeChecksumType?: number,
DefaultClientKeytabName?: string,
DNSLookupKDC?: boolean,
IgnoreAcceptorHostname?: boolean,
Proxiable?: boolean,
/**
* time in nanoseconds
*/
TicketLifetime?: number,
DefaultKeytabName?: string,
DefaultTktEnctypeIDs?: number[],
Forwardable?: boolean,
PermittedEnctypeIDs?: number[],
K5LoginAuthoritative?: boolean,
AllowWeakCrypto?: boolean,
DefaultClientKeytabName?: string,
DefaultTktEnctypes?: string[],
ExtraAddresses?: Uint8Array,
K5LoginDirectory?: string,
PreferredPreauthTypes?: number[],
UDPPreferenceLimit?: number,
VerifyAPReqNofail?: boolean,
/**
* time in nanoseconds
*/
Clockskew?: number,
RDNS?: boolean,
DefaultKeytabName?: string,
DefaultRealm?: string,
DefaultTGSEnctypeIDs?: number[],
DNSCanonicalizeHostname?: boolean,
KDCTimeSync?: number,
PermittedEnctypes?: string[],
DefaultRealm?: string,
VerifyAPReqNofail?: boolean,
DNSLookupRealm?: boolean,
UDPPreferenceLimit?: number,
Canonicalize?: boolean,
CCacheType?: number,
DefaultTGSEnctypes?: string[],
Proxiable?: boolean,
DNSLookupKDC?: boolean,
RealmTryDomains?: number,
/**
* time in nanoseconds
@ -384,15 +386,13 @@ export interface LibDefaults {
RenewLifetime?: number,
CCacheType?: number,
DefaultTktEnctypeIDs?: number[],
DefaultTGSEnctypeIDs?: number[],
IgnoreAcceptorHostname?: boolean,
DNSLookupRealm?: boolean,
NoAddresses?: boolean,
ExtraAddresses?: Uint8Array,
AllowWeakCrypto?: boolean,
PermittedEnctypeIDs?: number[],
KDCDefaultOptions?: BitString,
}
@ -416,6 +416,10 @@ export interface PrincipalName {
*/
export interface Realm {
Realm?: string,
AdminServer?: string[],
DefaultDomain?: string,
KDC?: string[],
@ -423,10 +427,6 @@ export interface Realm {
KPasswdServer?: string[],
MasterKDC?: string[],
Realm?: string,
AdminServer?: string[],
}
@ -450,10 +450,10 @@ export interface TGS {
*/
export interface Ticket {
TktVNO?: number,
Realm?: string,
TktVNO?: number,
SName?: PrincipalName,
EncPart?: EncryptedData,

View File

@ -473,6 +473,7 @@ export class Client {
* const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
* const users = client.GetADUsers();
* log(to_json(users));
* ```
*/
export interface ADObject {

View File

@ -6,7 +6,7 @@
* @example
* ```javascript
* const mssql = require('nuclei/mssql');
* const client = new mssql.Client();
* const client = new mssql.MSSQLClient;
* ```
*/
export class MSSQLClient {
@ -22,7 +22,7 @@ export class MSSQLClient {
* @example
* ```javascript
* const mssql = require('nuclei/mssql');
* const client = new mssql.Client();
* const client = new mssql.MSSQLClient;
* const connected = client.Connect('acme.com', 1433, 'username', 'password');
* ```
*/
@ -39,7 +39,7 @@ export class MSSQLClient {
* @example
* ```javascript
* const mssql = require('nuclei/mssql');
* const client = new mssql.Client();
* const client = new mssql.MSSQLClient;
* const connected = client.ConnectWithDB('acme.com', 1433, 'username', 'password', 'master');
* ```
*/

View File

@ -23,7 +23,7 @@ export function BuildDSN(opts: MySQLOptions): string | null {
* @example
* ```javascript
* const mysql = require('nuclei/mysql');
* const client = new mysql.Client();
* const client = new mysql.MySQLClient;
* ```
*/
export class MySQLClient {
@ -54,7 +54,7 @@ export class MySQLClient {
* @example
* ```javascript
* const mysql = require('nuclei/mysql');
* const client = new mysql.Client();
* const client = new mysql.MySQLClient;
* const connected = client.Connect('acme.com', 3306, 'username', 'password');
* ```
*/
@ -84,7 +84,7 @@ export class MySQLClient {
* @example
* ```javascript
* const mysql = require('nuclei/mysql');
* const client = new mysql.Client();
* const client = new mysql.MySQLClient;
* const connected = client.ConnectWithDSN('username:password@tcp(acme.com:3306)/');
* ```
*/
@ -209,9 +209,9 @@ export interface MySQLOptions {
*/
export interface SQLResult {
Count?: number,
Columns?: string[],
Count?: number,
}

View File

@ -115,14 +115,32 @@ export class NetConn {
/**
* Recv receives data from the connection with a timeout.
* RecvFull receives data from the connection with a timeout.
* If N is 0, it will read all data sent by the server with 8MB limit.
* it tries to read until N bytes or timeout is reached.
* @example
* ```javascript
* const net = require('nuclei/net');
* const conn = net.Open('tcp', 'acme.com:80');
* const data = conn.RecvFull(1024);
* ```
*/
public RecvFull(N: number): Uint8Array | null {
return null;
}
/**
* Recv is similar to RecvFull but does not guarantee full read instead
* it creates a buffer of N bytes and returns whatever is returned by the connection
* for reading headers or initial bytes from the server this is usually used.
* for reading a fixed number of already known bytes (ex: body based on content-length) use RecvFull.
* @example
* ```javascript
* const net = require('nuclei/net');
* const conn = net.Open('tcp', 'acme.com:80');
* const data = conn.Recv(1024);
* log(`Received ${data.length} bytes from the server`)
* ```
*/
public Recv(N: number): Uint8Array | null {
@ -131,26 +149,26 @@ export class NetConn {
/**
* RecvPartial is similar to Recv but it does not perform full read instead
* it creates a buffer of N bytes and returns whatever is returned by the connection
* this is usually used when fingerprinting services to get initial bytes from the server.
* RecvFullString receives data from the connection with a timeout
* output is returned as a string.
* If N is 0, it will read all data sent by the server with 8MB limit.
* @example
* ```javascript
* const net = require('nuclei/net');
* const conn = net.Open('tcp', 'acme.com:80');
* const data = conn.RecvPartial(1024);
* log(`Received ${data.length} bytes from the server`)
* const data = conn.RecvFullString(1024);
* ```
*/
public RecvPartial(N: number): Uint8Array | null {
public RecvFullString(N: number): string | null {
return null;
}
/**
* RecvString receives data from the connection with a timeout
* output is returned as a string.
* If N is 0, it will read all data sent by the server with 8MB limit.
* RecvString is similar to RecvFullString but does not guarantee full read, instead
* it creates a buffer of N bytes and returns whatever is returned by the connection
* for reading headers or initial bytes from the server this is usually used.
* for reading a fixed number of already known bytes (ex: body based on content-length) use RecvFullString.
* @example
* ```javascript
* const net = require('nuclei/net');
@ -164,9 +182,27 @@ export class NetConn {
/**
* RecvHex receives data from the connection with a timeout
* RecvFullHex receives data from the connection with a timeout
* in hex format.
* If N is 0,it will read all data sent by the server with 8MB limit.
* until N bytes or timeout is reached.
* @example
* ```javascript
* const net = require('nuclei/net');
* const conn = net.Open('tcp', 'acme.com:80');
* const data = conn.RecvFullHex(1024);
* ```
*/
public RecvFullHex(N: number): string | null {
return null;
}
/**
* RecvHex is similar to RecvFullHex but does not guarantee full read instead
* it creates a buffer of N bytes and returns whatever is returned by the connection
* for reading headers or initial bytes from the server this is usually used.
* for reading a fixed number of already known bytes (ex: body based on content-length) use RecvFull.
* @example
* ```javascript
* const net = require('nuclei/net');

View File

@ -1,32 +1,16 @@
/**
* OracleClient is a minimal Oracle client for nuclei scripts.
* IsOracle checks if a host is running an Oracle server
* @example
* ```javascript
* const oracle = require('nuclei/oracle');
* const client = new oracle.Client();
* const isOracle = oracle.IsOracle('acme.com', 1521);
* log(toJSON(isOracle));
* ```
*/
export class OracleClient {
// Constructor of OracleClient
constructor() {}
/**
* IsOracle checks if a host is running an Oracle server
* @example
* ```javascript
* const oracle = require('nuclei/oracle');
* const isOracle = oracle.IsOracle('acme.com', 1521);
* log(toJSON(isOracle));
* ```
*/
public IsOracle(host: string, port: number): IsOracleResponse | null {
return null;
}
export function IsOracle(host: string, port: number): IsOracleResponse | null {
return null;
}

View File

@ -1,32 +1,16 @@
/**
* Pop3Client is a minimal POP3 client for nuclei scripts.
* IsPOP3 checks if a host is running a POP3 server.
* @example
* ```javascript
* const pop3 = require('nuclei/pop3');
* const client = new pop3.Client();
* const isPOP3 = pop3.IsPOP3('acme.com', 110);
* log(toJSON(isPOP3));
* ```
*/
export class Pop3Client {
// Constructor of Pop3Client
constructor() {}
/**
* IsPOP3 checks if a host is running a POP3 server.
* @example
* ```javascript
* const pop3 = require('nuclei/pop3');
* const isPOP3 = pop3.IsPOP3('acme.com', 110);
* log(toJSON(isPOP3));
* ```
*/
public IsPOP3(host: string, port: number): IsPOP3Response | null {
return null;
}
export function IsPOP3(host: string, port: number): IsPOP3Response | null {
return null;
}

View File

@ -6,7 +6,7 @@
* @example
* ```javascript
* const postgres = require('nuclei/postgres');
* const client = new postgres.Client();
* const client = new postgres.PGClient;
* ```
*/
export class PGClient {
@ -37,7 +37,7 @@ export class PGClient {
* @example
* ```javascript
* const postgres = require('nuclei/postgres');
* const client = new postgres.Client();
* const client = new postgres.PGClient;
* const connected = client.Connect('acme.com', 5432, 'username', 'password');
* ```
*/
@ -53,7 +53,7 @@ export class PGClient {
* @example
* ```javascript
* const postgres = require('nuclei/postgres');
* const client = new postgres.Client();
* const client = new postgres.PGClient;
* const result = client.ExecuteQuery('acme.com', 5432, 'username', 'password', 'dbname', 'select * from users');
* log(to_json(result));
* ```
@ -71,7 +71,7 @@ export class PGClient {
* @example
* ```javascript
* const postgres = require('nuclei/postgres');
* const client = new postgres.Client();
* const client = new postgres.PGClient;
* const connected = client.ConnectWithDB('acme.com', 5432, 'username', 'password', 'dbname');
* ```
*/

View File

@ -1,51 +1,36 @@
/**
* RDPClient is a minimal RDP client for nuclei scripts.
* CheckRDPAuth checks if the given host and port are running rdp server
* with authentication and returns their metadata.
* If connection is successful, it returns true.
* @example
* ```javascript
* const rdp = require('nuclei/rdp');
* const client = new rdp.Client();
* const checkRDPAuth = rdp.CheckRDPAuth('acme.com', 3389);
* log(toJSON(checkRDPAuth));
* ```
*/
export class RDPClient {
export function CheckRDPAuth(host: string, port: number): CheckRDPAuthResponse | null {
return null;
}
// Constructor of RDPClient
constructor() {}
/**
* IsRDP checks if the given host and port are running rdp server.
* If connection is successful, it returns true.
* If connection is unsuccessful, it returns false and error.
* The Name of the OS is also returned if the connection is successful.
* @example
* ```javascript
* const rdp = require('nuclei/rdp');
* const isRDP = rdp.IsRDP('acme.com', 3389);
* log(toJSON(isRDP));
* ```
*/
public IsRDP(host: string, port: number): IsRDPResponse | null {
return null;
}
/**
* CheckRDPAuth checks if the given host and port are running rdp server
* with authentication and returns their metadata.
* If connection is successful, it returns true.
* @example
* ```javascript
* const rdp = require('nuclei/rdp');
* const checkRDPAuth = rdp.CheckRDPAuth('acme.com', 3389);
* log(toJSON(checkRDPAuth));
* ```
*/
public CheckRDPAuth(host: string, port: number): CheckRDPAuthResponse | null {
return null;
}
/**
* IsRDP checks if the given host and port are running rdp server.
* If connection is successful, it returns true.
* If connection is unsuccessful, it returns false and error.
* The Name of the OS is also returned if the connection is successful.
* @example
* ```javascript
* const rdp = require('nuclei/rdp');
* const isRDP = rdp.IsRDP('acme.com', 3389);
* log(toJSON(isRDP));
* ```
*/
export function IsRDP(host: string, port: number): IsRDPResponse | null {
return null;
}
@ -93,12 +78,6 @@ export interface IsRDPResponse {
*/
export interface ServiceRDP {
NetBIOSComputerName?: string,
NetBIOSDomainName?: string,
DNSComputerName?: string,
DNSDomainName?: string,
ForestName?: string,
@ -108,5 +87,11 @@ export interface ServiceRDP {
OSVersion?: string,
TargetName?: string,
NetBIOSComputerName?: string,
NetBIOSDomainName?: string,
DNSComputerName?: string,
}

View File

@ -1,32 +1,16 @@
/**
* RsyncClient is a minimal Rsync client for nuclei scripts.
* IsRsync checks if a host is running a Rsync server.
* @example
* ```javascript
* const rsync = require('nuclei/rsync');
* const client = new rsync.Client();
* const isRsync = rsync.IsRsync('acme.com', 873);
* log(toJSON(isRsync));
* ```
*/
export class RsyncClient {
// Constructor of RsyncClient
constructor() {}
/**
* IsRsync checks if a host is running a Rsync server.
* @example
* ```javascript
* const rsync = require('nuclei/rsync');
* const isRsync = rsync.IsRsync('acme.com', 873);
* log(toJSON(isRsync));
* ```
*/
public IsRsync(host: string, port: number): IsRsyncResponse | null {
return null;
}
export function IsRsync(host: string, port: number): IsRsyncResponse | null {
return null;
}

View File

@ -7,7 +7,7 @@
* @example
* ```javascript
* const smb = require('nuclei/smb');
* const client = new smb.Client();
* const client = new smb.SMBClient();
* ```
*/
export class SMBClient {
@ -23,7 +23,7 @@ export class SMBClient {
* @example
* ```javascript
* const smb = require('nuclei/smb');
* const client = new smb.Client();
* const client = new smb.SMBClient();
* const info = client.ConnectSMBInfoMode('acme.com', 445);
* log(to_json(info));
* ```
@ -41,7 +41,7 @@ export class SMBClient {
* @example
* ```javascript
* const smb = require('nuclei/smb');
* const client = new smb.Client();
* const client = new smb.SMBClient();
* const metadata = client.ListSMBv2Metadata('acme.com', 445);
* log(to_json(metadata));
* ```
@ -59,7 +59,7 @@ export class SMBClient {
* @example
* ```javascript
* const smb = require('nuclei/smb');
* const client = new smb.Client();
* const client = new smb.SMBClient();
* const shares = client.ListShares('acme.com', 445, 'username', 'password');
* for (const share of shares) {
* log(share);
@ -113,6 +113,8 @@ export interface HeaderLog {
*/
export interface NegotiationLog {
SecurityMode?: number,
DialectRevision?: number,
ServerGuid?: Uint8Array,
@ -125,8 +127,6 @@ export interface NegotiationLog {
AuthenticationTypes?: string[],
SecurityMode?: number,
HeaderLog?: HeaderLog,
}
@ -137,6 +137,8 @@ export interface NegotiationLog {
*/
export interface SMBCapabilities {
DFSSupport?: boolean,
Leasing?: boolean,
LargeMTU?: boolean,
@ -148,8 +150,6 @@ export interface SMBCapabilities {
DirLeasing?: boolean,
Encryption?: boolean,
DFSSupport?: boolean,
}
@ -159,6 +159,8 @@ export interface SMBCapabilities {
*/
export interface SMBLog {
NativeOs?: string,
NTLM?: string,
GroupName?: string,
@ -167,15 +169,13 @@ export interface SMBLog {
SupportV1?: boolean,
NativeOs?: string,
Version?: SMBVersions,
Capabilities?: SMBCapabilities,
NegotiationLog?: NegotiationLog,
SessionSetupLog?: SessionSetupLog,
Version?: SMBVersions,
}
@ -201,10 +201,6 @@ export interface SMBVersions {
*/
export interface ServiceSMB {
DNSDomainName?: string,
ForestName?: string,
SigningEnabled?: boolean,
SigningRequired?: boolean,
@ -216,6 +212,10 @@ export interface ServiceSMB {
NetBIOSDomainName?: string,
DNSComputerName?: string,
DNSDomainName?: string,
ForestName?: string,
}
@ -225,12 +225,12 @@ export interface ServiceSMB {
*/
export interface SessionSetupLog {
SetupFlags?: number,
TargetName?: string,
NegotiateFlags?: number,
SetupFlags?: number,
HeaderLog?: HeaderLog,
}

View File

@ -1,28 +1,31 @@
/**
* SMTPClient is a minimal SMTP client for nuclei scripts.
* Client is a minimal SMTP client for nuclei scripts.
* @example
* ```javascript
* const smtp = require('nuclei/smtp');
* const client = new smtp.Client();
* const client = new smtp.Client('acme.com', 25);
* ```
*/
export class SMTPClient {
export class Client {
// Constructor of Client
constructor(public host: string, public port: string ) {}
// Constructor of SMTPClient
constructor() {}
/**
* IsSMTP checks if a host is running a SMTP server.
* @example
* ```javascript
* const smtp = require('nuclei/smtp');
* const isSMTP = smtp.IsSMTP('acme.com', 25);
* log(toJSON(isSMTP));
* const client = new smtp.Client('acme.com', 25);
* const isSMTP = client.IsSMTP();
* log(isSMTP)
* ```
*/
public IsSMTP(host: string, port: number): IsSMTPResponse | null {
public IsSMTP(): SMTPResponse | null {
return null;
}
@ -37,10 +40,11 @@ export class SMTPClient {
* message.To('xyz2@projectdiscoveyr.io');
* message.Subject('hello');
* message.Body('hello');
* const isRelay = smtp.IsOpenRelay('acme.com', 25, message);
* const client = new smtp.Client('acme.com', 25);
* const isRelay = client.IsOpenRelay(message);
* ```
*/
public IsOpenRelay(host: string, port: number, msg: SMTPMessage): boolean | null {
public IsOpenRelay(msg: SMTPMessage): boolean | null {
return null;
}
@ -55,10 +59,12 @@ export class SMTPClient {
* message.To('xyz2@projectdiscoveyr.io');
* message.Subject('hello');
* message.Body('hello');
* const isSent = smtp.SendMail('acme.com', 25, message);
* const client = new smtp.Client('acme.com', 25);
* const isSent = client.SendMail(message);
* log(isSent)
* ```
*/
public SendMail(host: string, port: string, msg: SMTPMessage): boolean | null {
public SendMail(msg: SMTPMessage): boolean | null {
return null;
}
@ -174,15 +180,16 @@ export class SMTPMessage {
/**
* IsSMTPResponse is the response from the IsSMTP function.
* SMTPResponse is the response from the IsSMTP function.
* @example
* ```javascript
* const smtp = require('nuclei/smtp');
* const isSMTP = smtp.IsSMTP('acme.com', 25);
* log(toJSON(isSMTP));
* const client = new smtp.Client('acme.com', 25);
* const isSMTP = client.IsSMTP();
* log(isSMTP)
* ```
*/
export interface IsSMTPResponse {
export interface SMTPResponse {
IsSMTP?: boolean,

View File

@ -6,7 +6,7 @@
* @example
* ```javascript
* const ssh = require('nuclei/ssh');
* const client = new ssh.Client();
* const client = new ssh.SSHClient();
* ```
*/
export class SSHClient {
@ -19,7 +19,7 @@ export class SSHClient {
* @example
* ```javascript
* const ssh = require('nuclei/ssh');
* const client = new ssh.Client();
* const client = new ssh.SSHClient();
* client.SetTimeout(10);
* ```
*/
@ -36,7 +36,7 @@ export class SSHClient {
* @example
* ```javascript
* const ssh = require('nuclei/ssh');
* const client = new ssh.Client();
* const client = new ssh.SSHClient();
* const connected = client.Connect('acme.com', 22, 'username', 'password');
* ```
*/
@ -53,7 +53,7 @@ export class SSHClient {
* @example
* ```javascript
* const ssh = require('nuclei/ssh');
* const client = new ssh.Client();
* const client = new ssh.SSHClient();
* const privateKey = `-----BEGIN RSA PRIVATE KEY----- ...`;
* const connected = client.ConnectWithKey('acme.com', 22, 'username', privateKey);
* ```
@ -73,7 +73,7 @@ export class SSHClient {
* @example
* ```javascript
* const ssh = require('nuclei/ssh');
* const client = new ssh.Client();
* const client = new ssh.SSHClient();
* const info = client.ConnectSSHInfoMode('acme.com', 22);
* log(to_json(info));
* ```
@ -92,7 +92,7 @@ export class SSHClient {
* @example
* ```javascript
* const ssh = require('nuclei/ssh');
* const client = new ssh.Client();
* const client = new ssh.SSHClient();
* client.Connect('acme.com', 22, 'username', 'password');
* const output = client.Run('id');
* log(output);
@ -110,7 +110,7 @@ export class SSHClient {
* @example
* ```javascript
* const ssh = require('nuclei/ssh');
* const client = new ssh.Client();
* const client = new ssh.SSHClient();
* client.Connect('acme.com', 22, 'username', 'password');
* const closed = client.Close();
* ```
@ -179,8 +179,6 @@ export interface HandshakeLog {
UserAuth?: string[],
AlgorithmSelection?: Algorithms,
ServerID?: EndpointId,
ClientID?: EndpointId,
@ -188,6 +186,8 @@ export interface HandshakeLog {
ServerKex?: KexInitMsg,
ClientKex?: KexInitMsg,
AlgorithmSelection?: Algorithms,
}
@ -197,28 +197,28 @@ export interface HandshakeLog {
*/
export interface KexInitMsg {
CompressionClientServer?: string[],
FirstKexFollows?: boolean,
CiphersServerClient?: string[],
MACsClientServer?: string[],
MACsServerClient?: string[],
LanguagesClientServer?: string[],
LanguagesServerClient?: string[],
Reserved?: number,
KexAlgos?: string[],
CiphersClientServer?: string[],
CiphersServerClient?: string[],
Reserved?: number,
MACsServerClient?: string[],
CompressionClientServer?: string[],
CompressionServerClient?: string[],
LanguagesServerClient?: string[],
FirstKexFollows?: boolean,
/**
* fixed size array of length: [16]
*/

View File

@ -1,32 +1,16 @@
/**
* TelnetClient is a minimal Telnet client for nuclei scripts.
* IsTelnet checks if a host is running a Telnet server.
* @example
* ```javascript
* const telnet = require('nuclei/telnet');
* const client = new telnet.Client();
* const isTelnet = telnet.IsTelnet('acme.com', 23);
* log(toJSON(isTelnet));
* ```
*/
export class TelnetClient {
// Constructor of TelnetClient
constructor() {}
/**
* IsTelnet checks if a host is running a Telnet server.
* @example
* ```javascript
* const telnet = require('nuclei/telnet');
* const isTelnet = telnet.IsTelnet('acme.com', 23);
* log(toJSON(isTelnet));
* ```
*/
public IsTelnet(host: string, port: number): IsTelnetResponse | null {
return null;
}
export function IsTelnet(host: string, port: number): IsTelnetResponse | null {
return null;
}

View File

@ -1,34 +1,18 @@
/**
* VNCClient is a minimal VNC client for nuclei scripts.
* IsVNC checks if a host is running a VNC server.
* It returns a boolean indicating if the host is running a VNC server
* and the banner of the VNC server.
* @example
* ```javascript
* const vnc = require('nuclei/vnc');
* const client = new vnc.Client();
* const isVNC = vnc.IsVNC('acme.com', 5900);
* log(toJSON(isVNC));
* ```
*/
export class VNCClient {
// Constructor of VNCClient
constructor() {}
/**
* IsVNC checks if a host is running a VNC server.
* It returns a boolean indicating if the host is running a VNC server
* and the banner of the VNC server.
* @example
* ```javascript
* const vnc = require('nuclei/vnc');
* const isVNC = vnc.IsVNC('acme.com', 5900);
* log(toJSON(isVNC));
* ```
*/
public IsVNC(host: string, port: number): IsVNCResponse | null {
return null;
}
export function IsVNC(host: string, port: number): IsVNCResponse | null {
return null;
}

View File

@ -88,7 +88,7 @@ type (
}
)
// Constructor for KerberosClient
// Constructor for Kerberos Client
// Constructor: constructor(public domain: string, public controller?: string)
// When controller is empty or not given krb5 will perform a DNS lookup for the default KDC server
// and retrieve its address from the DNS server

View File

@ -82,6 +82,7 @@ type (
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
// const users = client.GetADUsers();
// log(to_json(users));
// ```
ADObject struct {
DistinguishedName string
SAMAccountName string

43
pkg/js/libs/mssql/memo.mssql.go Executable file
View File

@ -0,0 +1,43 @@
// Warning - This is generated code
package mssql
import (
"errors"
"fmt"
_ "github.com/denisenkom/go-mssqldb"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedconnect(host string, port int, username string, password string, dbName string) (bool, error) {
hash := "connect" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(username) + ":" + fmt.Sprint(password) + ":" + fmt.Sprint(dbName)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return connect(host, port, username, password, dbName)
})
if err != nil {
return false, err
}
if value, ok := v.(bool); ok {
return value, nil
}
return false, errors.New("could not convert cached result")
}
func memoizedisMssql(host string, port int) (bool, error) {
hash := "isMssql" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isMssql(host, port)
})
if err != nil {
return false, err
}
if value, ok := v.(bool); ok {
return value, nil
}
return false, errors.New("could not convert cached result")
}

View File

@ -20,7 +20,7 @@ type (
// @example
// ```javascript
// const mssql = require('nuclei/mssql');
// const client = new mssql.Client();
// const client = new mssql.MSSQLClient;
// ```
MSSQLClient struct{}
)
@ -32,11 +32,11 @@ type (
// @example
// ```javascript
// const mssql = require('nuclei/mssql');
// const client = new mssql.Client();
// const client = new mssql.MSSQLClient;
// const connected = client.Connect('acme.com', 1433, 'username', 'password');
// ```
func (c *MSSQLClient) Connect(host string, port int, username, password string) (bool, error) {
return connect(host, port, username, password, "master")
return memoizedconnect(host, port, username, password, "master")
}
// ConnectWithDB connects to MS SQL database using given credentials and database name.
@ -46,14 +46,15 @@ func (c *MSSQLClient) Connect(host string, port int, username, password string)
// @example
// ```javascript
// const mssql = require('nuclei/mssql');
// const client = new mssql.Client();
// const client = new mssql.MSSQLClient;
// const connected = client.ConnectWithDB('acme.com', 1433, 'username', 'password', 'master');
// ```
func (c *MSSQLClient) ConnectWithDB(host string, port int, username, password, dbName string) (bool, error) {
return connect(host, port, username, password, dbName)
return memoizedconnect(host, port, username, password, dbName)
}
func connect(host string, port int, username, password, dbName string) (bool, error) {
// @memo
func connect(host string, port int, username string, password string, dbName string) (bool, error) {
if host == "" || port <= 0 {
return false, fmt.Errorf("invalid host or port")
}
@ -104,6 +105,11 @@ func connect(host string, port int, username, password, dbName string) (bool, er
// const isMssql = mssql.IsMssql('acme.com', 1433);
// ```
func (c *MSSQLClient) IsMssql(host string, port int) (bool, error) {
return memoizedisMssql(host, port)
}
// @memo
func isMssql(host string, port int) (bool, error) {
if !protocolstate.IsHostAllowed(host) {
// host is not valid according to network policy
return false, protocolstate.ErrHostDenied.Msgf(host)

41
pkg/js/libs/mysql/memo.mysql.go Executable file
View File

@ -0,0 +1,41 @@
// Warning - This is generated code
package mysql
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedisMySQL(host string, port int) (bool, error) {
hash := "isMySQL" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isMySQL(host, port)
})
if err != nil {
return false, err
}
if value, ok := v.(bool); ok {
return value, nil
}
return false, errors.New("could not convert cached result")
}
func memoizedfingerprintMySQL(host string, port int) (MySQLInfo, error) {
hash := "fingerprintMySQL" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return fingerprintMySQL(host, port)
})
if err != nil {
return MySQLInfo{}, err
}
if value, ok := v.(MySQLInfo); ok {
return value, nil
}
return MySQLInfo{}, errors.New("could not convert cached result")
}

View File

@ -0,0 +1,25 @@
// Warning - This is generated code
package mysql
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedconnectWithDSN(dsn string) (bool, error) {
hash := "connectWithDSN" + ":" + fmt.Sprint(dsn)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return connectWithDSN(dsn)
})
if err != nil {
return false, err
}
if value, ok := v.(bool); ok {
return value, nil
}
return false, errors.New("could not convert cached result")
}

View File

@ -22,7 +22,7 @@ type (
// @example
// ```javascript
// const mysql = require('nuclei/mysql');
// const client = new mysql.Client();
// const client = new mysql.MySQLClient;
// ```
MySQLClient struct{}
)
@ -36,6 +36,11 @@ type (
// const isMySQL = mysql.IsMySQL('acme.com', 3306);
// ```
func (c *MySQLClient) IsMySQL(host string, port int) (bool, error) {
return memoizedisMySQL(host, port)
}
// @memo
func isMySQL(host string, port int) (bool, error) {
if !protocolstate.IsHostAllowed(host) {
// host is not valid according to network policy
return false, protocolstate.ErrHostDenied.Msgf(host)
@ -64,7 +69,7 @@ func (c *MySQLClient) IsMySQL(host string, port int) (bool, error) {
// @example
// ```javascript
// const mysql = require('nuclei/mysql');
// const client = new mysql.Client();
// const client = new mysql.MySQLClient;
// const connected = client.Connect('acme.com', 3306, 'username', 'password');
// ```
func (c *MySQLClient) Connect(host string, port int, username, password string) (bool, error) {
@ -110,6 +115,11 @@ type (
// log(to_json(info));
// ```
func (c *MySQLClient) FingerprintMySQL(host string, port int) (MySQLInfo, error) {
return memoizedfingerprintMySQL(host, port)
}
// @memo
func fingerprintMySQL(host string, port int) (MySQLInfo, error) {
info := MySQLInfo{}
if !protocolstate.IsHostAllowed(host) {
// host is not valid according to network policy
@ -149,11 +159,11 @@ func (c *MySQLClient) FingerprintMySQL(host string, port int) (MySQLInfo, error)
// @example
// ```javascript
// const mysql = require('nuclei/mysql');
// const client = new mysql.Client();
// const client = new mysql.MySQLClient;
// const connected = client.ConnectWithDSN('username:password@tcp(acme.com:3306)/');
// ```
func (c *MySQLClient) ConnectWithDSN(dsn string) (bool, error) {
return connectWithDSN(dsn)
return memoizedconnectWithDSN(dsn)
}
// ExecuteQueryWithOpts connects to Mysql database using given credentials

View File

@ -65,6 +65,7 @@ func BuildDSN(opts MySQLOptions) (string, error) {
return dsn.String(), nil
}
// @memo
func connectWithDSN(dsn string) (bool, error) {
db, err := sql.Open("mysql", dsn)
if err != nil {

View File

@ -172,16 +172,16 @@ func (c *NetConn) Send(data string) error {
return nil
}
// Recv receives data from the connection with a timeout.
// RecvFull receives data from the connection with a timeout.
// If N is 0, it will read all data sent by the server with 8MB limit.
// it tries to read until N bytes or timeout is reached.
// @example
// ```javascript
// const net = require('nuclei/net');
// const conn = net.Open('tcp', 'acme.com:80');
// const data = conn.Recv(1024);
// const data = conn.RecvFull(1024);
// ```
func (c *NetConn) Recv(N int) ([]byte, error) {
func (c *NetConn) RecvFull(N int) ([]byte, error) {
c.setDeadLine()
defer c.unsetDeadLine()
if N == 0 {
@ -195,17 +195,18 @@ func (c *NetConn) Recv(N int) ([]byte, error) {
return bin, nil
}
// RecvPartial is similar to Recv but it does not perform full read instead
// Recv is similar to RecvFull but does not guarantee full read instead
// it creates a buffer of N bytes and returns whatever is returned by the connection
// this is usually used when fingerprinting services to get initial bytes from the server.
// for reading headers or initial bytes from the server this is usually used.
// for reading a fixed number of already known bytes (ex: body based on content-length) use RecvFull.
// @example
// ```javascript
// const net = require('nuclei/net');
// const conn = net.Open('tcp', 'acme.com:80');
// const data = conn.RecvPartial(1024);
// const data = conn.Recv(1024);
// log(`Received ${data.length} bytes from the server`)
// ```
func (c *NetConn) RecvPartial(N int) ([]byte, error) {
func (c *NetConn) Recv(N int) ([]byte, error) {
c.setDeadLine()
defer c.unsetDeadLine()
if N == 0 {
@ -219,13 +220,31 @@ func (c *NetConn) RecvPartial(N int) ([]byte, error) {
return b[:n], nil
}
// RecvString receives data from the connection with a timeout
// RecvFullString receives data from the connection with a timeout
// output is returned as a string.
// If N is 0, it will read all data sent by the server with 8MB limit.
// @example
// ```javascript
// const net = require('nuclei/net');
// const conn = net.Open('tcp', 'acme.com:80');
// const data = conn.RecvFullString(1024);
// ```
func (c *NetConn) RecvFullString(N int) (string, error) {
bin, err := c.RecvFull(N)
if err != nil {
return "", err
}
return string(bin), nil
}
// RecvString is similar to RecvFullString but does not guarantee full read, instead
// it creates a buffer of N bytes and returns whatever is returned by the connection
// for reading headers or initial bytes from the server this is usually used.
// for reading a fixed number of already known bytes (ex: body based on content-length) use RecvFullString.
// @example
// ```javascript
// const net = require('nuclei/net');
// const conn = net.Open('tcp', 'acme.com:80');
// const data = conn.RecvString(1024);
// ```
func (c *NetConn) RecvString(N int) (string, error) {
@ -236,9 +255,28 @@ func (c *NetConn) RecvString(N int) (string, error) {
return string(bin), nil
}
// RecvHex receives data from the connection with a timeout
// RecvFullHex receives data from the connection with a timeout
// in hex format.
// If N is 0,it will read all data sent by the server with 8MB limit.
// until N bytes or timeout is reached.
// @example
// ```javascript
// const net = require('nuclei/net');
// const conn = net.Open('tcp', 'acme.com:80');
// const data = conn.RecvFullHex(1024);
// ```
func (c *NetConn) RecvFullHex(N int) (string, error) {
bin, err := c.RecvFull(N)
if err != nil {
return "", err
}
return hex.Dump(bin), nil
}
// RecvHex is similar to RecvFullHex but does not guarantee full read instead
// it creates a buffer of N bytes and returns whatever is returned by the connection
// for reading headers or initial bytes from the server this is usually used.
// for reading a fixed number of already known bytes (ex: body based on content-length) use RecvFull.
// @example
// ```javascript
// const net = require('nuclei/net');

View File

@ -0,0 +1,25 @@
// Warning - This is generated code
package oracle
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedisOracle(host string, port int) (IsOracleResponse, error) {
hash := "isOracle" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isOracle(host, port)
})
if err != nil {
return IsOracleResponse{}, err
}
if value, ok := v.(IsOracleResponse); ok {
return value, nil
}
return IsOracleResponse{}, errors.New("could not convert cached result")
}

View File

@ -11,16 +11,6 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
type (
// OracleClient is a minimal Oracle client for nuclei scripts.
// @example
// ```javascript
// const oracle = require('nuclei/oracle');
// const client = new oracle.Client();
// ```
OracleClient struct{}
)
type (
// IsOracleResponse is the response from the IsOracle function.
// this is returned by IsOracle function.
@ -42,7 +32,12 @@ type (
// const isOracle = oracle.IsOracle('acme.com', 1521);
// log(toJSON(isOracle));
// ```
func (c *OracleClient) IsOracle(host string, port int) (IsOracleResponse, error) {
func IsOracle(host string, port int) (IsOracleResponse, error) {
return memoizedisOracle(host, port)
}
// @memo
func isOracle(host string, port int) (IsOracleResponse, error) {
resp := IsOracleResponse{}
timeout := 5 * time.Second

25
pkg/js/libs/pop3/memo.pop3.go Executable file
View File

@ -0,0 +1,25 @@
// Warning - This is generated code
package pop3
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedisPoP3(host string, port int) (IsPOP3Response, error) {
hash := "isPoP3" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isPoP3(host, port)
})
if err != nil {
return IsPOP3Response{}, err
}
if value, ok := v.(IsPOP3Response); ok {
return value, nil
}
return IsPOP3Response{}, errors.New("could not convert cached result")
}

View File

@ -11,16 +11,6 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
type (
// Pop3Client is a minimal POP3 client for nuclei scripts.
// @example
// ```javascript
// const pop3 = require('nuclei/pop3');
// const client = new pop3.Client();
// ```
Pop3Client struct{}
)
type (
// IsPOP3Response is the response from the IsPOP3 function.
// this is returned by IsPOP3 function.
@ -43,7 +33,12 @@ type (
// const isPOP3 = pop3.IsPOP3('acme.com', 110);
// log(toJSON(isPOP3));
// ```
func (c *Pop3Client) IsPOP3(host string, port int) (IsPOP3Response, error) {
func IsPOP3(host string, port int) (IsPOP3Response, error) {
return memoizedisPoP3(host, port)
}
// @memo
func isPoP3(host string, port int) (IsPOP3Response, error) {
resp := IsPOP3Response{}
timeout := 5 * time.Second

View File

@ -0,0 +1,61 @@
// Warning - This is generated code
package postgres
import (
"errors"
"fmt"
_ "github.com/lib/pq"
utils "github.com/projectdiscovery/nuclei/v3/pkg/js/utils"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedisPostgres(host string, port int) (bool, error) {
hash := "isPostgres" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isPostgres(host, port)
})
if err != nil {
return false, err
}
if value, ok := v.(bool); ok {
return value, nil
}
return false, errors.New("could not convert cached result")
}
func memoizedexecuteQuery(host string, port int, username string, password string, dbName string, query string) (*utils.SQLResult, error) {
hash := "executeQuery" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(username) + ":" + fmt.Sprint(password) + ":" + fmt.Sprint(dbName) + ":" + fmt.Sprint(query)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return executeQuery(host, port, username, password, dbName, query)
})
if err != nil {
return nil, err
}
if value, ok := v.(*utils.SQLResult); ok {
return value, nil
}
return nil, errors.New("could not convert cached result")
}
func memoizedconnect(host string, port int, username string, password string, dbName string) (bool, error) {
hash := "connect" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(username) + ":" + fmt.Sprint(password) + ":" + fmt.Sprint(dbName)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return connect(host, port, username, password, dbName)
})
if err != nil {
return false, err
}
if value, ok := v.(bool); ok {
return value, nil
}
return false, errors.New("could not convert cached result")
}

View File

@ -22,7 +22,7 @@ type (
// @example
// ```javascript
// const postgres = require('nuclei/postgres');
// const client = new postgres.Client();
// const client = new postgres.PGClient;
// ```
PGClient struct{}
)
@ -36,6 +36,11 @@ type (
// const isPostgres = postgres.IsPostgres('acme.com', 5432);
// ```
func (c *PGClient) IsPostgres(host string, port int) (bool, error) {
return memoizedisPostgres(host, port)
}
// @memo
func isPostgres(host string, port int) (bool, error) {
timeout := 10 * time.Second
conn, err := protocolstate.Dialer.Dial(context.TODO(), "tcp", fmt.Sprintf("%s:%d", host, port))
@ -64,11 +69,11 @@ func (c *PGClient) IsPostgres(host string, port int) (bool, error) {
// @example
// ```javascript
// const postgres = require('nuclei/postgres');
// const client = new postgres.Client();
// const client = new postgres.PGClient;
// const connected = client.Connect('acme.com', 5432, 'username', 'password');
// ```
func (c *PGClient) Connect(host string, port int, username, password string) (bool, error) {
return connect(host, port, username, password, "postgres")
return memoizedconnect(host, port, username, password, "postgres")
}
// ExecuteQuery connects to Postgres database using given credentials and database name.
@ -77,11 +82,16 @@ func (c *PGClient) Connect(host string, port int, username, password string) (bo
// @example
// ```javascript
// const postgres = require('nuclei/postgres');
// const client = new postgres.Client();
// const client = new postgres.PGClient;
// const result = client.ExecuteQuery('acme.com', 5432, 'username', 'password', 'dbname', 'select * from users');
// log(to_json(result));
// ```
func (c *PGClient) ExecuteQuery(host string, port int, username, password, dbName, query string) (*utils.SQLResult, error) {
return memoizedexecuteQuery(host, port, username, password, dbName, query)
}
// @memo
func executeQuery(host string, port int, username string, password string, dbName string, query string) (*utils.SQLResult, error) {
if !protocolstate.IsHostAllowed(host) {
// host is not valid according to network policy
return nil, protocolstate.ErrHostDenied.Msgf(host)
@ -113,14 +123,15 @@ func (c *PGClient) ExecuteQuery(host string, port int, username, password, dbNam
// @example
// ```javascript
// const postgres = require('nuclei/postgres');
// const client = new postgres.Client();
// const client = new postgres.PGClient;
// const connected = client.ConnectWithDB('acme.com', 5432, 'username', 'password', 'dbname');
// ```
func (c *PGClient) ConnectWithDB(host string, port int, username, password, dbName string) (bool, error) {
return connect(host, port, username, password, dbName)
return memoizedconnect(host, port, username, password, dbName)
}
func connect(host string, port int, username, password, dbName string) (bool, error) {
// @memo
func connect(host string, port int, username string, password string, dbName string) (bool, error) {
if host == "" || port <= 0 {
return false, fmt.Errorf("invalid host or port")
}
@ -138,6 +149,8 @@ func connect(host string, port int, username, password, dbName string) (bool, er
Password: password,
Database: dbName,
})
defer db.Close()
_, err := db.Exec("select 1")
if err != nil {
switch true {

41
pkg/js/libs/rdp/memo.rdp.go Executable file
View File

@ -0,0 +1,41 @@
// Warning - This is generated code
package rdp
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedisRDP(host string, port int) (IsRDPResponse, error) {
hash := "isRDP" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isRDP(host, port)
})
if err != nil {
return IsRDPResponse{}, err
}
if value, ok := v.(IsRDPResponse); ok {
return value, nil
}
return IsRDPResponse{}, errors.New("could not convert cached result")
}
func memoizedcheckRDPAuth(host string, port int) (CheckRDPAuthResponse, error) {
hash := "checkRDPAuth" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return checkRDPAuth(host, port)
})
if err != nil {
return CheckRDPAuthResponse{}, err
}
if value, ok := v.(CheckRDPAuthResponse); ok {
return value, nil
}
return CheckRDPAuthResponse{}, errors.New("could not convert cached result")
}

View File

@ -10,16 +10,6 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
type (
// RDPClient is a minimal RDP client for nuclei scripts.
// @example
// ```javascript
// const rdp = require('nuclei/rdp');
// const client = new rdp.Client();
// ```
RDPClient struct{}
)
type (
// IsRDPResponse is the response from the IsRDP function.
// this is returned by IsRDP function.
@ -45,7 +35,12 @@ type (
// const isRDP = rdp.IsRDP('acme.com', 3389);
// log(toJSON(isRDP));
// ```
func (c *RDPClient) IsRDP(host string, port int) (IsRDPResponse, error) {
func IsRDP(host string, port int) (IsRDPResponse, error) {
return memoizedisRDP(host, port)
}
// @memo
func isRDP(host string, port int) (IsRDPResponse, error) {
resp := IsRDPResponse{}
timeout := 5 * time.Second
@ -91,7 +86,12 @@ type (
// const checkRDPAuth = rdp.CheckRDPAuth('acme.com', 3389);
// log(toJSON(checkRDPAuth));
// ```
func (c *RDPClient) CheckRDPAuth(host string, port int) (CheckRDPAuthResponse, error) {
func CheckRDPAuth(host string, port int) (CheckRDPAuthResponse, error) {
return memoizedcheckRDPAuth(host, port)
}
// @memo
func checkRDPAuth(host string, port int) (CheckRDPAuthResponse, error) {
resp := CheckRDPAuthResponse{}
timeout := 5 * time.Second

73
pkg/js/libs/redis/memo.redis.go Executable file
View File

@ -0,0 +1,73 @@
// Warning - This is generated code
package redis
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedgetServerInfo(host string, port int) (string, error) {
hash := "getServerInfo" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return getServerInfo(host, port)
})
if err != nil {
return "", err
}
if value, ok := v.(string); ok {
return value, nil
}
return "", errors.New("could not convert cached result")
}
func memoizedconnect(host string, port int, password string) (bool, error) {
hash := "connect" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(password)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return connect(host, port, password)
})
if err != nil {
return false, err
}
if value, ok := v.(bool); ok {
return value, nil
}
return false, errors.New("could not convert cached result")
}
func memoizedgetServerInfoAuth(host string, port int, password string) (string, error) {
hash := "getServerInfoAuth" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(password)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return getServerInfoAuth(host, port, password)
})
if err != nil {
return "", err
}
if value, ok := v.(string); ok {
return value, nil
}
return "", errors.New("could not convert cached result")
}
func memoizedisAuthenticated(host string, port int) (bool, error) {
hash := "isAuthenticated" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isAuthenticated(host, port)
})
if err != nil {
return false, err
}
if value, ok := v.(bool); ok {
return value, nil
}
return false, errors.New("could not convert cached result")
}

View File

@ -19,6 +19,11 @@ import (
// const info = redis.GetServerInfo('acme.com', 6379);
// ```
func GetServerInfo(host string, port int) (string, error) {
return memoizedgetServerInfo(host, port)
}
// @memo
func getServerInfo(host string, port int) (string, error) {
if !protocolstate.IsHostAllowed(host) {
// host is not valid according to network policy
return "", protocolstate.ErrHostDenied.Msgf(host)
@ -29,6 +34,7 @@ func GetServerInfo(host string, port int) (string, error) {
Password: "", // no password set
DB: 0, // use default DB
})
defer client.Close()
// Ping the Redis server
_, err := client.Ping(context.TODO()).Result()
@ -52,6 +58,11 @@ func GetServerInfo(host string, port int) (string, error) {
// const connected = redis.Connect('acme.com', 6379, 'password');
// ```
func Connect(host string, port int, password string) (bool, error) {
return memoizedconnect(host, port, password)
}
// @memo
func connect(host string, port int, password string) (bool, error) {
if !protocolstate.IsHostAllowed(host) {
// host is not valid according to network policy
return false, protocolstate.ErrHostDenied.Msgf(host)
@ -62,6 +73,8 @@ func Connect(host string, port int, password string) (bool, error) {
Password: password, // no password set
DB: 0, // use default DB
})
defer client.Close()
_, err := client.Ping(context.TODO()).Result()
if err != nil {
return false, err
@ -82,6 +95,11 @@ func Connect(host string, port int, password string) (bool, error) {
// const info = redis.GetServerInfoAuth('acme.com', 6379, 'password');
// ```
func GetServerInfoAuth(host string, port int, password string) (string, error) {
return memoizedgetServerInfoAuth(host, port, password)
}
// @memo
func getServerInfoAuth(host string, port int, password string) (string, error) {
if !protocolstate.IsHostAllowed(host) {
// host is not valid according to network policy
return "", protocolstate.ErrHostDenied.Msgf(host)
@ -92,6 +110,7 @@ func GetServerInfoAuth(host string, port int, password string) (string, error) {
Password: password, // no password set
DB: 0, // use default DB
})
defer client.Close()
// Ping the Redis server
_, err := client.Ping(context.TODO()).Result()
@ -115,6 +134,11 @@ func GetServerInfoAuth(host string, port int, password string) (string, error) {
// const isAuthenticated = redis.IsAuthenticated('acme.com', 6379);
// ```
func IsAuthenticated(host string, port int) (bool, error) {
return memoizedisAuthenticated(host, port)
}
// @memo
func isAuthenticated(host string, port int) (bool, error) {
plugin := pluginsredis.REDISPlugin{}
timeout := 5 * time.Second
conn, err := protocolstate.Dialer.Dial(context.TODO(), "tcp", fmt.Sprintf("%s:%d", host, port))
@ -147,6 +171,7 @@ func RunLuaScript(host string, port int, password string, script string) (interf
Password: password,
DB: 0, // use default DB
})
defer client.Close()
// Ping the Redis server
_, err := client.Ping(context.TODO()).Result()

25
pkg/js/libs/rsync/memo.rsync.go Executable file
View File

@ -0,0 +1,25 @@
// Warning - This is generated code
package rsync
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedisRsync(host string, port int) (IsRsyncResponse, error) {
hash := "isRsync" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isRsync(host, port)
})
if err != nil {
return IsRsyncResponse{}, err
}
if value, ok := v.(IsRsyncResponse); ok {
return value, nil
}
return IsRsyncResponse{}, errors.New("could not convert cached result")
}

View File

@ -11,16 +11,6 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
type (
// RsyncClient is a minimal Rsync client for nuclei scripts.
// @example
// ```javascript
// const rsync = require('nuclei/rsync');
// const client = new rsync.Client();
// ```
RsyncClient struct{}
)
type (
// IsRsyncResponse is the response from the IsRsync function.
// this is returned by IsRsync function.
@ -43,7 +33,12 @@ type (
// const isRsync = rsync.IsRsync('acme.com', 873);
// log(toJSON(isRsync));
// ```
func (c *RsyncClient) IsRsync(host string, port int) (IsRsyncResponse, error) {
func IsRsync(host string, port int) (IsRsyncResponse, error) {
return memoizedisRsync(host, port)
}
// @memo
func isRsync(host string, port int) (IsRsyncResponse, error) {
resp := IsRsyncResponse{}
timeout := 5 * time.Second

43
pkg/js/libs/smb/memo.smb.go Executable file
View File

@ -0,0 +1,43 @@
// Warning - This is generated code
package smb
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
"github.com/zmap/zgrab2/lib/smb/smb"
)
func memoizedconnectSMBInfoMode(host string, port int) (*smb.SMBLog, error) {
hash := "connectSMBInfoMode" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return connectSMBInfoMode(host, port)
})
if err != nil {
return nil, err
}
if value, ok := v.(*smb.SMBLog); ok {
return value, nil
}
return nil, errors.New("could not convert cached result")
}
func memoizedlistShares(host string, port int, user string, password string) ([]string, error) {
hash := "listShares" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(user) + ":" + fmt.Sprint(password)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return listShares(host, port, user, password)
})
if err != nil {
return []string{}, err
}
if value, ok := v.([]string); ok {
return value, nil
}
return []string{}, errors.New("could not convert cached result")
}

View File

@ -0,0 +1,29 @@
// Warning - This is generated code
package smb
import (
"errors"
"fmt"
"time"
"github.com/praetorian-inc/fingerprintx/pkg/plugins"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedcollectSMBv2Metadata(host string, port int, timeout time.Duration) (*plugins.ServiceSMB, error) {
hash := "collectSMBv2Metadata" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(timeout)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return collectSMBv2Metadata(host, port, timeout)
})
if err != nil {
return nil, err
}
if value, ok := v.(*plugins.ServiceSMB); ok {
return value, nil
}
return nil, errors.New("could not convert cached result")
}

View File

@ -0,0 +1,25 @@
// Warning - This is generated code
package smb
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizeddetectSMBGhost(host string, port int) (bool, error) {
hash := "detectSMBGhost" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return detectSMBGhost(host, port)
})
if err != nil {
return false, err
}
if value, ok := v.(bool); ok {
return value, nil
}
return false, errors.New("could not convert cached result")
}

View File

@ -18,7 +18,7 @@ type (
// @example
// ```javascript
// const smb = require('nuclei/smb');
// const client = new smb.Client();
// const client = new smb.SMBClient();
// ```
SMBClient struct{}
)
@ -30,11 +30,16 @@ type (
// @example
// ```javascript
// const smb = require('nuclei/smb');
// const client = new smb.Client();
// const client = new smb.SMBClient();
// const info = client.ConnectSMBInfoMode('acme.com', 445);
// log(to_json(info));
// ```
func (c *SMBClient) ConnectSMBInfoMode(host string, port int) (*smb.SMBLog, error) {
return memoizedconnectSMBInfoMode(host, port)
}
// @memo
func connectSMBInfoMode(host string, port int) (*smb.SMBLog, error) {
if !protocolstate.IsHostAllowed(host) {
// host is not valid according to network policy
return nil, protocolstate.ErrHostDenied.Msgf(host)
@ -44,7 +49,7 @@ func (c *SMBClient) ConnectSMBInfoMode(host string, port int) (*smb.SMBLog, erro
return nil, err
}
// try to get SMBv2/v3 info
result, err := c.getSMBInfo(conn, true, false)
result, err := getSMBInfo(conn, true, false)
_ = conn.Close() // close regardless of error
if err == nil {
return result, nil
@ -56,7 +61,7 @@ func (c *SMBClient) ConnectSMBInfoMode(host string, port int) (*smb.SMBLog, erro
return nil, err
}
defer conn.Close()
result, err = c.getSMBInfo(conn, true, true)
result, err = getSMBInfo(conn, true, true)
if err != nil {
return result, nil
}
@ -70,7 +75,7 @@ func (c *SMBClient) ConnectSMBInfoMode(host string, port int) (*smb.SMBLog, erro
// @example
// ```javascript
// const smb = require('nuclei/smb');
// const client = new smb.Client();
// const client = new smb.SMBClient();
// const metadata = client.ListSMBv2Metadata('acme.com', 445);
// log(to_json(metadata));
// ```
@ -79,7 +84,7 @@ func (c *SMBClient) ListSMBv2Metadata(host string, port int) (*plugins.ServiceSM
// host is not valid according to network policy
return nil, protocolstate.ErrHostDenied.Msgf(host)
}
return collectSMBv2Metadata(host, port, 5*time.Second)
return memoizedcollectSMBv2Metadata(host, port, 5*time.Second)
}
// ListShares tries to connect to provided host and port
@ -89,7 +94,7 @@ func (c *SMBClient) ListSMBv2Metadata(host string, port int) (*plugins.ServiceSM
// @example
// ```javascript
// const smb = require('nuclei/smb');
// const client = new smb.Client();
// const client = new smb.SMBClient();
// const shares = client.ListShares('acme.com', 445, 'username', 'password');
//
// for (const share of shares) {
@ -98,6 +103,11 @@ func (c *SMBClient) ListSMBv2Metadata(host string, port int) (*plugins.ServiceSM
//
// ```
func (c *SMBClient) ListShares(host string, port int, user, password string) ([]string, error) {
return memoizedlistShares(host, port, user, password)
}
// @memo
func listShares(host string, port int, user string, password string) ([]string, error) {
if !protocolstate.IsHostAllowed(host) {
// host is not valid according to network policy
return nil, protocolstate.ErrHostDenied.Msgf(host)

View File

@ -15,6 +15,7 @@ import (
// ==== private helper functions/methods ====
// collectSMBv2Metadata collects metadata for SMBv2 services.
// @memo
func collectSMBv2Metadata(host string, port int, timeout time.Duration) (*plugins.ServiceSMB, error) {
if timeout == 0 {
timeout = 5 * time.Second
@ -33,7 +34,7 @@ func collectSMBv2Metadata(host string, port int, timeout time.Duration) (*plugin
}
// getSMBInfo
func (c *SMBClient) getSMBInfo(conn net.Conn, setupSession, v1 bool) (*zgrabsmb.SMBLog, error) {
func getSMBInfo(conn net.Conn, setupSession, v1 bool) (*zgrabsmb.SMBLog, error) {
_ = conn.SetDeadline(time.Now().Add(10 * time.Second))
defer func() {
_ = conn.SetDeadline(time.Time{})

View File

@ -26,6 +26,11 @@ const (
// const isSMBGhost = smb.DetectSMBGhost('acme.com', 445);
// ```
func (c *SMBClient) DetectSMBGhost(host string, port int) (bool, error) {
return memoizeddetectSMBGhost(host, port)
}
// @memo
func detectSMBGhost(host string, port int) (bool, error) {
if !protocolstate.IsHostAllowed(host) {
// host is not valid according to network policy
return false, protocolstate.ErrHostDenied.Msgf(host)

View File

@ -8,55 +8,92 @@ import (
"strconv"
"time"
"github.com/dop251/goja"
"github.com/praetorian-inc/fingerprintx/pkg/plugins"
"github.com/projectdiscovery/nuclei/v3/pkg/js/utils"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
pluginsmtp "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/smtp"
)
type (
// SMTPClient is a minimal SMTP client for nuclei scripts.
// SMTPResponse is the response from the IsSMTP function.
// @example
// ```javascript
// const smtp = require('nuclei/smtp');
// const client = new smtp.Client();
// const client = new smtp.Client('acme.com', 25);
// const isSMTP = client.IsSMTP();
// log(isSMTP)
// ```
SMTPClient struct{}
)
type (
// IsSMTPResponse is the response from the IsSMTP function.
// @example
// ```javascript
// const smtp = require('nuclei/smtp');
// const isSMTP = smtp.IsSMTP('acme.com', 25);
// log(toJSON(isSMTP));
// ```
IsSMTPResponse struct {
SMTPResponse struct {
IsSMTP bool
Banner string
}
)
type (
// Client is a minimal SMTP client for nuclei scripts.
// @example
// ```javascript
// const smtp = require('nuclei/smtp');
// const client = new smtp.Client('acme.com', 25);
// ```
Client struct {
nj *utils.NucleiJS
host string
port string
}
)
// Constructor for SMTP Client
// Constructor: constructor(public host: string, public port: string)
func NewSMTPClient(call goja.ConstructorCall, runtime *goja.Runtime) *goja.Object {
// setup nucleijs utils
c := &Client{nj: utils.NewNucleiJS(runtime)}
c.nj.ObjectSig = "Client(host, port)" // will be included in error messages
host, _ := c.nj.GetArg(call.Arguments, 0).(string) // host
port, _ := c.nj.GetArg(call.Arguments, 1).(string) // port
// validate arguments
c.nj.Require(host != "", "host cannot be empty")
c.nj.Require(port != "", "port cannot be empty")
// validate port
portInt, err := strconv.Atoi(port)
c.nj.Require(err == nil && portInt > 0 && portInt < 65536, "port must be a valid number")
c.host = host
c.port = port
// check if this is allowed address
c.nj.Require(protocolstate.IsHostAllowed(host+":"+port), protocolstate.ErrHostDenied.Msgf(host+":"+port).Error())
// Link Constructor to Client and return
return utils.LinkConstructor(call, runtime, c)
}
// IsSMTP checks if a host is running a SMTP server.
// @example
// ```javascript
// const smtp = require('nuclei/smtp');
// const isSMTP = smtp.IsSMTP('acme.com', 25);
// log(toJSON(isSMTP));
// const client = new smtp.Client('acme.com', 25);
// const isSMTP = client.IsSMTP();
// log(isSMTP)
// ```
func (c *SMTPClient) IsSMTP(host string, port int) (IsSMTPResponse, error) {
resp := IsSMTPResponse{}
func (c *Client) IsSMTP() (SMTPResponse, error) {
resp := SMTPResponse{}
c.nj.Require(c.host != "", "host cannot be empty")
c.nj.Require(c.port != "", "port cannot be empty")
timeout := 5 * time.Second
conn, err := protocolstate.Dialer.Dial(context.TODO(), "tcp", net.JoinHostPort(host, strconv.Itoa(port)))
conn, err := protocolstate.Dialer.Dial(context.TODO(), "tcp", net.JoinHostPort(c.host, c.port))
if err != nil {
return resp, err
}
defer conn.Close()
smtpPlugin := pluginsmtp.SMTPPlugin{}
service, err := smtpPlugin.Run(conn, timeout, plugins.Target{Host: host})
service, err := smtpPlugin.Run(conn, timeout, plugins.Target{Host: c.host})
if err != nil {
return resp, err
}
@ -77,20 +114,20 @@ func (c *SMTPClient) IsSMTP(host string, port int) (IsSMTPResponse, error) {
// message.To('xyz2@projectdiscoveyr.io');
// message.Subject('hello');
// message.Body('hello');
// const isRelay = smtp.IsOpenRelay('acme.com', 25, message);
// const client = new smtp.Client('acme.com', 25);
// const isRelay = client.IsOpenRelay(message);
// ```
func (c *SMTPClient) IsOpenRelay(host string, port int, msg *SMTPMessage) (bool, error) {
if !protocolstate.IsHostAllowed(host) {
return false, protocolstate.ErrHostDenied.Msgf(host)
}
func (c *Client) IsOpenRelay(msg *SMTPMessage) (bool, error) {
c.nj.Require(c.host != "", "host cannot be empty")
c.nj.Require(c.port != "", "port cannot be empty")
addr := net.JoinHostPort(host, strconv.Itoa(port))
addr := net.JoinHostPort(c.host, c.port)
conn, err := protocolstate.Dialer.Dial(context.TODO(), "tcp", addr)
if err != nil {
return false, err
}
defer conn.Close()
client, err := smtp.NewClient(conn, host)
client, err := smtp.NewClient(conn, c.host)
if err != nil {
return false, err
}
@ -135,22 +172,23 @@ func (c *SMTPClient) IsOpenRelay(host string, port int, msg *SMTPMessage) (bool,
// message.To('xyz2@projectdiscoveyr.io');
// message.Subject('hello');
// message.Body('hello');
// const isSent = smtp.SendMail('acme.com', 25, message);
// const client = new smtp.Client('acme.com', 25);
// const isSent = client.SendMail(message);
// log(isSent)
// ```
func (c *SMTPClient) SendMail(host string, port string, msg *SMTPMessage) (bool, error) {
if !protocolstate.IsHostAllowed(host) {
return false, protocolstate.ErrHostDenied.Msgf(host)
}
func (c *Client) SendMail(msg *SMTPMessage) (bool, error) {
c.nj.Require(c.host != "", "host cannot be empty")
c.nj.Require(c.port != "", "port cannot be empty")
var auth smtp.Auth
if msg.user != "" && msg.pass != "" {
auth = smtp.PlainAuth("", msg.user, msg.pass, host)
auth = smtp.PlainAuth("", msg.user, msg.pass, c.host)
}
// send mail
addr := net.JoinHostPort(host, port)
addr := net.JoinHostPort(c.host, c.port)
if err := smtp.SendMail(addr, auth, msg.from, msg.to, []byte(msg.String())); err != nil {
return false, err
c.nj.Throw("failed to send mail with message(%s) got %v", msg.String(), err)
}
return true, nil
}

27
pkg/js/libs/ssh/memo.ssh.go Executable file
View File

@ -0,0 +1,27 @@
// Warning - This is generated code
package ssh
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
"github.com/zmap/zgrab2/lib/ssh"
)
func memoizedconnectSSHInfoMode(opts *connectOptions) (*ssh.HandshakeLog, error) {
hash := "connectSSHInfoMode" + ":" + fmt.Sprint(opts)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return connectSSHInfoMode(opts)
})
if err != nil {
return nil, err
}
if value, ok := v.(*ssh.HandshakeLog); ok {
return value, nil
}
return nil, errors.New("could not convert cached result")
}

View File

@ -16,7 +16,7 @@ type (
// @example
// ```javascript
// const ssh = require('nuclei/ssh');
// const client = new ssh.Client();
// const client = new ssh.SSHClient();
// ```
SSHClient struct {
connection *ssh.Client
@ -28,7 +28,7 @@ type (
// @example
// ```javascript
// const ssh = require('nuclei/ssh');
// const client = new ssh.Client();
// const client = new ssh.SSHClient();
// client.SetTimeout(10);
// ```
func (c *SSHClient) SetTimeout(sec int) {
@ -42,7 +42,7 @@ func (c *SSHClient) SetTimeout(sec int) {
// @example
// ```javascript
// const ssh = require('nuclei/ssh');
// const client = new ssh.Client();
// const client = new ssh.SSHClient();
// const connected = client.Connect('acme.com', 22, 'username', 'password');
// ```
func (c *SSHClient) Connect(host string, port int, username, password string) (bool, error) {
@ -67,7 +67,7 @@ func (c *SSHClient) Connect(host string, port int, username, password string) (b
// @example
// ```javascript
// const ssh = require('nuclei/ssh');
// const client = new ssh.Client();
// const client = new ssh.SSHClient();
// const privateKey = `-----BEGIN RSA PRIVATE KEY----- ...`;
// const connected = client.ConnectWithKey('acme.com', 22, 'username', privateKey);
// ```
@ -96,12 +96,12 @@ func (c *SSHClient) ConnectWithKey(host string, port int, username, key string)
// @example
// ```javascript
// const ssh = require('nuclei/ssh');
// const client = new ssh.Client();
// const client = new ssh.SSHClient();
// const info = client.ConnectSSHInfoMode('acme.com', 22);
// log(to_json(info));
// ```
func (c *SSHClient) ConnectSSHInfoMode(host string, port int) (*ssh.HandshakeLog, error) {
return connectSSHInfoMode(&connectOptions{
return memoizedconnectSSHInfoMode(&connectOptions{
Host: host,
Port: port,
})
@ -115,7 +115,7 @@ func (c *SSHClient) ConnectSSHInfoMode(host string, port int) (*ssh.HandshakeLog
// @example
// ```javascript
// const ssh = require('nuclei/ssh');
// const client = new ssh.Client();
// const client = new ssh.SSHClient();
// client.Connect('acme.com', 22, 'username', 'password');
// const output = client.Run('id');
// log(output);
@ -144,7 +144,7 @@ func (c *SSHClient) Run(cmd string) (string, error) {
// @example
// ```javascript
// const ssh = require('nuclei/ssh');
// const client = new ssh.Client();
// const client = new ssh.SSHClient();
// client.Connect('acme.com', 22, 'username', 'password');
// const closed = client.Close();
// ```
@ -182,6 +182,7 @@ func (c *connectOptions) validate() error {
return nil
}
// @memo
func connectSSHInfoMode(opts *connectOptions) (*ssh.HandshakeLog, error) {
if err := opts.validate(); err != nil {
return nil, err

View File

@ -0,0 +1,25 @@
// Warning - This is generated code
package telnet
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedisTelnet(host string, port int) (IsTelnetResponse, error) {
hash := "isTelnet" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isTelnet(host, port)
})
if err != nil {
return IsTelnetResponse{}, err
}
if value, ok := v.(IsTelnetResponse); ok {
return value, nil
}
return IsTelnetResponse{}, errors.New("could not convert cached result")
}

View File

@ -11,16 +11,6 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
type (
// TelnetClient is a minimal Telnet client for nuclei scripts.
// @example
// ```javascript
// const telnet = require('nuclei/telnet');
// const client = new telnet.Client();
// ```
TelnetClient struct{}
)
type (
// IsTelnetResponse is the response from the IsTelnet function.
// this is returned by IsTelnet function.
@ -43,7 +33,12 @@ type (
// const isTelnet = telnet.IsTelnet('acme.com', 23);
// log(toJSON(isTelnet));
// ```
func (c *TelnetClient) IsTelnet(host string, port int) (IsTelnetResponse, error) {
func IsTelnet(host string, port int) (IsTelnetResponse, error) {
return memoizedisTelnet(host, port)
}
// @memo
func isTelnet(host string, port int) (IsTelnetResponse, error) {
resp := IsTelnetResponse{}
timeout := 5 * time.Second

25
pkg/js/libs/vnc/memo.vnc.go Executable file
View File

@ -0,0 +1,25 @@
// Warning - This is generated code
package vnc
import (
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
func memoizedisVNC(host string, port int) (IsVNCResponse, error) {
hash := "isVNC" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return isVNC(host, port)
})
if err != nil {
return IsVNCResponse{}, err
}
if value, ok := v.(IsVNCResponse); ok {
return value, nil
}
return IsVNCResponse{}, errors.New("could not convert cached result")
}

View File

@ -11,16 +11,6 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
type (
// VNCClient is a minimal VNC client for nuclei scripts.
// @example
// ```javascript
// const vnc = require('nuclei/vnc');
// const client = new vnc.Client();
// ```
VNCClient struct{}
)
type (
// IsVNCResponse is the response from the IsVNC function.
// @example
@ -44,7 +34,12 @@ type (
// const isVNC = vnc.IsVNC('acme.com', 5900);
// log(toJSON(isVNC));
// ```
func (c *VNCClient) IsVNC(host string, port int) (IsVNCResponse, error) {
func IsVNC(host string, port int) (IsVNCResponse, error) {
return memoizedisVNC(host, port)
}
// @memo
func isVNC(host string, port int) (IsVNCResponse, error) {
resp := IsVNCResponse{}
timeout := 5 * time.Second

View File

@ -0,0 +1,15 @@
package protocolstate
import (
"github.com/projectdiscovery/utils/memoize"
)
var Memoizer *memoize.Memoizer
func init() {
var err error
Memoizer, err = memoize.New(memoize.WithMaxSize(1500))
if err != nil {
panic(err)
}
}

View File

@ -137,7 +137,7 @@ type Request struct {
// description: |
// SelfContained specifies if the request is self-contained.
SelfContained bool `yaml:"-" json:"-"`
SelfContained bool `yaml:"self-contained" json:"self-contained"`
// description: |
// Signature is the request signature method

View File

@ -447,7 +447,7 @@ func (request *Request) executeRequestParallel(ctxParent context.Context, hostPo
}
}
func (request *Request) executeRequestWithPayloads(hostPort string, input *contextargs.Context, hostname string, payload map[string]interface{}, previous output.InternalEvent, callback protocols.OutputEventCallback, requestOptions *protocols.ExecutorOptions) error {
func (request *Request) executeRequestWithPayloads(hostPort string, input *contextargs.Context, _ string, payload map[string]interface{}, previous output.InternalEvent, callback protocols.OutputEventCallback, requestOptions *protocols.ExecutorOptions) error {
payloadValues := generators.MergeMaps(payload, previous)
argsCopy, err := request.getArgsCopy(input, payloadValues, requestOptions, false)
if err != nil {
@ -580,7 +580,7 @@ func (request *Request) getArgsCopy(input *contextargs.Context, payloadValues ma
}
// evaluateArgs evaluates arguments using available payload values and returns a copy of args
func (request *Request) evaluateArgs(payloadValues map[string]interface{}, requestOptions *protocols.ExecutorOptions, ignoreErrors bool) (map[string]interface{}, error) {
func (request *Request) evaluateArgs(payloadValues map[string]interface{}, _ *protocols.ExecutorOptions, ignoreErrors bool) (map[string]interface{}, error) {
argsCopy := make(map[string]interface{})
mainLoop:
for k, v := range request.Args {

View File

@ -7,6 +7,7 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/exporters/markdown"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/exporters/sarif"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/exporters/splunk"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/filters"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/gitea"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/github"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/gitlab"
@ -17,9 +18,9 @@ import (
// Options is a configuration file for nuclei reporting module
type Options struct {
// AllowList contains a list of allowed events for reporting module
AllowList *Filter `yaml:"allow-list"`
AllowList *filters.Filter `yaml:"allow-list"`
// DenyList contains a list of denied events for reporting module
DenyList *Filter `yaml:"deny-list"`
DenyList *filters.Filter `yaml:"deny-list"`
// GitHub contains configuration options for GitHub Issue Tracker
GitHub *github.Options `yaml:"github"`
// GitLab contains configuration options for GitLab Issue Tracker

View File

@ -12,7 +12,6 @@ import (
"errors"
"github.com/projectdiscovery/nuclei/v3/pkg/model/types/severity"
"github.com/projectdiscovery/nuclei/v3/pkg/model/types/stringslice"
"github.com/projectdiscovery/nuclei/v3/pkg/output"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/dedupe"
@ -20,62 +19,26 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/exporters/markdown"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/exporters/sarif"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/exporters/splunk"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/filters"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/gitea"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/github"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/gitlab"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/jira"
errorutil "github.com/projectdiscovery/utils/errors"
fileutil "github.com/projectdiscovery/utils/file"
sliceutil "github.com/projectdiscovery/utils/slice"
)
// Filter filters the received event and decides whether to perform
// reporting for it or not.
type Filter struct {
Severities severity.Severities `yaml:"severity"`
Tags stringslice.StringSlice `yaml:"tags"`
}
var (
ErrReportingClientCreation = errors.New("could not create reporting client")
ErrExportClientCreation = errors.New("could not create exporting client")
)
// GetMatch returns true if a filter matches result event
func (filter *Filter) GetMatch(event *output.ResultEvent) bool {
return isSeverityMatch(event, filter) && isTagMatch(event, filter) // TODO revisit this
}
func isTagMatch(event *output.ResultEvent, filter *Filter) bool {
filterTags := filter.Tags
if filterTags.IsEmpty() {
return true
}
tags := event.Info.Tags.ToSlice()
for _, filterTag := range filterTags.ToSlice() {
if sliceutil.Contains(tags, filterTag) {
return true
}
}
return false
}
func isSeverityMatch(event *output.ResultEvent, filter *Filter) bool {
resultEventSeverity := event.Info.SeverityHolder.Severity // TODO review
if len(filter.Severities) == 0 {
return true
}
return sliceutil.Contains(filter.Severities, resultEventSeverity)
}
// Tracker is an interface implemented by an issue tracker
type Tracker interface {
// CreateIssue creates an issue in the tracker
CreateIssue(event *output.ResultEvent) error
// ShouldFilter determines if the event should be filtered out
ShouldFilter(event *output.ResultEvent) bool
}
// Exporter is an interface implemented by an issue exporter
@ -197,10 +160,11 @@ func CreateConfigIfNotExists() error {
values := stringslice.StringSlice{Value: []string{}}
options := &Options{
AllowList: &Filter{Tags: values},
DenyList: &Filter{Tags: values},
AllowList: &filters.Filter{Tags: values},
DenyList: &filters.Filter{Tags: values},
GitHub: &github.Options{},
GitLab: &gitlab.Options{},
Gitea: &gitea.Options{},
Jira: &jira.Options{},
MarkdownExporter: &markdown.Options{},
SarifExporter: &sarif.Options{},
@ -239,6 +203,7 @@ func (c *ReportingClient) Close() {
// CreateIssue creates an issue in the tracker
func (c *ReportingClient) CreateIssue(event *output.ResultEvent) error {
// process global allow/deny list
if c.options.AllowList != nil && !c.options.AllowList.GetMatch(event) {
return nil
}
@ -249,6 +214,10 @@ func (c *ReportingClient) CreateIssue(event *output.ResultEvent) error {
unique, err := c.dedupe.Index(event)
if unique {
for _, tracker := range c.trackers {
// process tracker specific allow/deny list
if tracker.ShouldFilter(event) {
continue
}
if trackerErr := tracker.CreateIssue(event); trackerErr != nil {
err = multierr.Append(err, trackerErr)
}

View File

@ -0,0 +1,47 @@
package filters
import (
"github.com/projectdiscovery/nuclei/v3/pkg/model/types/severity"
"github.com/projectdiscovery/nuclei/v3/pkg/model/types/stringslice"
"github.com/projectdiscovery/nuclei/v3/pkg/output"
sliceutil "github.com/projectdiscovery/utils/slice"
)
// Filter filters the received event and decides whether to perform
// reporting for it or not.
type Filter struct {
Severities severity.Severities `yaml:"severity"`
Tags stringslice.StringSlice `yaml:"tags"`
}
// GetMatch returns true if a filter matches result event
func (filter *Filter) GetMatch(event *output.ResultEvent) bool {
return isSeverityMatch(event, filter) && isTagMatch(event, filter) // TODO revisit this
}
func isTagMatch(event *output.ResultEvent, filter *Filter) bool {
filterTags := filter.Tags
if filterTags.IsEmpty() {
return true
}
tags := event.Info.Tags.ToSlice()
for _, filterTag := range filterTags.ToSlice() {
if sliceutil.Contains(tags, filterTag) {
return true
}
}
return false
}
func isSeverityMatch(event *output.ResultEvent, filter *Filter) bool {
resultEventSeverity := event.Info.SeverityHolder.Severity // TODO review
if len(filter.Severities) == 0 {
return true
}
return sliceutil.Contains(filter.Severities, resultEventSeverity)
}

View File

@ -10,6 +10,7 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/output"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/exporters/markdown/util"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/format"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/filters"
"github.com/projectdiscovery/retryablehttp-go"
)
@ -34,6 +35,10 @@ type Options struct {
// SeverityAsLabel (optional) adds the severity as the label of the created
// issue.
SeverityAsLabel bool `yaml:"severity-as-label"`
// AllowList contains a list of allowed events for this tracker
AllowList *filters.Filter `yaml:"allow-list"`
// DenyList contains a list of denied events for this tracker
DenyList *filters.Filter `yaml:"deny-list"`
// DuplicateIssueCheck is a bool to enable duplicate tracking issue check and update the newest
DuplicateIssueCheck bool `yaml:"duplicate-issue-check" default:"false"`
@ -116,6 +121,19 @@ func (i *Integration) CreateIssue(event *output.ResultEvent) error {
return err
}
// ShouldFilter determines if an issue should be logged to this tracker
func (i *Integration) ShouldFilter(event *output.ResultEvent) bool {
if i.options.AllowList != nil && i.options.AllowList.GetMatch(event) {
return true
}
if i.options.DenyList != nil && i.options.DenyList.GetMatch(event) {
return true
}
return false
}
func (i *Integration) findIssueByTitle(title string) (*gitea.Issue, error) {
issueList, _, err := i.client.ListRepoIssues(i.options.ProjectOwner, i.options.ProjectName, gitea.ListIssueOption{

View File

@ -13,6 +13,7 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/output"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/exporters/markdown/util"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/format"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/filters"
"github.com/projectdiscovery/nuclei/v3/pkg/types"
"github.com/projectdiscovery/retryablehttp-go"
"golang.org/x/oauth2"
@ -41,6 +42,10 @@ type Options struct {
// SeverityAsLabel (optional) sends the severity as the label of the created
// issue.
SeverityAsLabel bool `yaml:"severity-as-label"`
// AllowList contains a list of allowed events for this tracker
AllowList *filters.Filter `yaml:"allow-list"`
// DenyList contains a list of denied events for this tracker
DenyList *filters.Filter `yaml:"deny-list"`
// DuplicateIssueCheck (optional) comments under existing finding issue
// instead of creating duplicates for subsequent runs.
DuplicateIssueCheck bool `yaml:"duplicate-issue-check"`
@ -129,6 +134,19 @@ func (i *Integration) CreateIssue(event *output.ResultEvent) (err error) {
}
}
// ShouldFilter determines if an issue should be logged to this tracker
func (i *Integration) ShouldFilter(event *output.ResultEvent) bool {
if i.options.AllowList != nil && i.options.AllowList.GetMatch(event) {
return true
}
if i.options.DenyList != nil && i.options.DenyList.GetMatch(event) {
return true
}
return false
}
func (i *Integration) findIssueByTitle(ctx context.Context, title string) (*github.Issue, error) {
req := &github.SearchOptions{
Sort: "updated",

View File

@ -8,6 +8,7 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/output"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/exporters/markdown/util"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/format"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/filters"
"github.com/projectdiscovery/retryablehttp-go"
)
@ -33,6 +34,10 @@ type Options struct {
// SeverityAsLabel (optional) sends the severity as the label of the created
// issue.
SeverityAsLabel bool `yaml:"severity-as-label"`
// AllowList contains a list of allowed events for this tracker
AllowList *filters.Filter `yaml:"allow-list"`
// DenyList contains a list of denied events for this tracker
DenyList *filters.Filter `yaml:"deny-list"`
// DuplicateIssueCheck is a bool to enable duplicate tracking issue check and update the newest
DuplicateIssueCheck bool `yaml:"duplicate-issue-check" default:"false"`
@ -112,3 +117,16 @@ func (i *Integration) CreateIssue(event *output.ResultEvent) error {
return err
}
// ShouldFilter determines if an issue should be logged to this tracker
func (i *Integration) ShouldFilter(event *output.ResultEvent) bool {
if i.options.AllowList != nil && i.options.AllowList.GetMatch(event) {
return true
}
if i.options.DenyList != nil && i.options.DenyList.GetMatch(event) {
return true
}
return false
}

View File

@ -12,6 +12,7 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/output"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/exporters/markdown/util"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/format"
"github.com/projectdiscovery/nuclei/v3/pkg/reporting/trackers/filters"
"github.com/projectdiscovery/retryablehttp-go"
)
@ -69,6 +70,10 @@ type Options struct {
// SeverityAsLabel (optional) sends the severity as the label of the created
// issue.
SeverityAsLabel bool `yaml:"severity-as-label" json:"severity_as_label"`
// AllowList contains a list of allowed events for this tracker
AllowList *filters.Filter `yaml:"allow-list"`
// DenyList contains a list of denied events for this tracker
DenyList *filters.Filter `yaml:"deny-list"`
// Severity (optional) is the severity of the issue.
Severity []string `yaml:"severity" json:"severity"`
HttpClient *retryablehttp.Client `yaml:"-" json:"-"`
@ -234,3 +239,16 @@ func (i *Integration) FindExistingIssue(event *output.ResultEvent) (string, erro
return chunk[0].ID, nil
}
}
// ShouldFilter determines if an issue should be logged to this tracker
func (i *Integration) ShouldFilter(event *output.ResultEvent) bool {
if i.options.AllowList != nil && i.options.AllowList.GetMatch(event) {
return true
}
if i.options.DenyList != nil && i.options.DenyList.GetMatch(event) {
return true
}
return false
}

View File

@ -371,6 +371,17 @@ func (template *Template) ImportFileRefs(options *protocols.ExecutorOptions) err
}
}
// for javascript protocol code references
for _, request := range template.RequestsJavascript {
// simple test to check if source is a file or a snippet
if len(strings.Split(request.Code, "\n")) == 1 && fileutil.FileExists(request.Code) {
if val, ok := loadFile(request.Code); ok {
template.ImportedFiles = append(template.ImportedFiles, request.Code)
request.Code = val
}
}
}
// flow code references
if template.Flow != "" {
if len(template.Flow) > 0 && filepath.Ext(template.Flow) == ".js" && fileutil.FileExists(template.Flow) {
@ -398,6 +409,20 @@ func (template *Template) ImportFileRefs(options *protocols.ExecutorOptions) err
}
}
}
// for javascript protocol code references
for _, req := range template.RequestsQueue {
if req.Type() == types.JavascriptProtocol {
request := req.(*javascript.Request)
// simple test to check if source is a file or a snippet
if len(strings.Split(request.Code, "\n")) == 1 && fileutil.FileExists(request.Code) {
if val, ok := loadFile(request.Code); ok {
template.ImportedFiles = append(template.ImportedFiles, request.Code)
request.Code = val
}
}
}
}
}
return multierr.Combine(errs...)

View File

@ -456,7 +456,7 @@ func init() {
Value: "HTTP response headers in name:value format",
},
}
HTTPRequestDoc.Fields = make([]encoder.Doc, 32)
HTTPRequestDoc.Fields = make([]encoder.Doc, 33)
HTTPRequestDoc.Fields[0].Name = "path"
HTTPRequestDoc.Fields[0].Type = "[]string"
HTTPRequestDoc.Fields[0].Note = ""
@ -562,89 +562,94 @@ func init() {
HTTPRequestDoc.Fields[15].Note = ""
HTTPRequestDoc.Fields[15].Description = "Fuzzing describes schema to fuzz http requests"
HTTPRequestDoc.Fields[15].Comments[encoder.LineComment] = " Fuzzing describes schema to fuzz http requests"
HTTPRequestDoc.Fields[16].Name = "signature"
HTTPRequestDoc.Fields[16].Type = "SignatureTypeHolder"
HTTPRequestDoc.Fields[16].Name = "self-contained"
HTTPRequestDoc.Fields[16].Type = "bool"
HTTPRequestDoc.Fields[16].Note = ""
HTTPRequestDoc.Fields[16].Description = "Signature is the request signature method"
HTTPRequestDoc.Fields[16].Comments[encoder.LineComment] = "Signature is the request signature method"
HTTPRequestDoc.Fields[16].Values = []string{
HTTPRequestDoc.Fields[16].Description = "SelfContained specifies if the request is self-contained."
HTTPRequestDoc.Fields[16].Comments[encoder.LineComment] = "SelfContained specifies if the request is self-contained."
HTTPRequestDoc.Fields[17].Name = "signature"
HTTPRequestDoc.Fields[17].Type = "SignatureTypeHolder"
HTTPRequestDoc.Fields[17].Note = ""
HTTPRequestDoc.Fields[17].Description = "Signature is the request signature method"
HTTPRequestDoc.Fields[17].Comments[encoder.LineComment] = "Signature is the request signature method"
HTTPRequestDoc.Fields[17].Values = []string{
"AWS",
}
HTTPRequestDoc.Fields[17].Name = "cookie-reuse"
HTTPRequestDoc.Fields[17].Type = "bool"
HTTPRequestDoc.Fields[17].Note = ""
HTTPRequestDoc.Fields[17].Description = "CookieReuse is an optional setting that enables cookie reuse for\nall requests defined in raw section."
HTTPRequestDoc.Fields[17].Comments[encoder.LineComment] = "CookieReuse is an optional setting that enables cookie reuse for"
HTTPRequestDoc.Fields[18].Name = "disable-cookie"
HTTPRequestDoc.Fields[18].Name = "cookie-reuse"
HTTPRequestDoc.Fields[18].Type = "bool"
HTTPRequestDoc.Fields[18].Note = ""
HTTPRequestDoc.Fields[18].Description = "DisableCookie is an optional setting that disables cookie reuse"
HTTPRequestDoc.Fields[18].Comments[encoder.LineComment] = "DisableCookie is an optional setting that disables cookie reuse"
HTTPRequestDoc.Fields[19].Name = "read-all"
HTTPRequestDoc.Fields[18].Description = "CookieReuse is an optional setting that enables cookie reuse for\nall requests defined in raw section."
HTTPRequestDoc.Fields[18].Comments[encoder.LineComment] = "CookieReuse is an optional setting that enables cookie reuse for"
HTTPRequestDoc.Fields[19].Name = "disable-cookie"
HTTPRequestDoc.Fields[19].Type = "bool"
HTTPRequestDoc.Fields[19].Note = ""
HTTPRequestDoc.Fields[19].Description = "Enables force reading of the entire raw unsafe request body ignoring\nany specified content length headers."
HTTPRequestDoc.Fields[19].Comments[encoder.LineComment] = "Enables force reading of the entire raw unsafe request body ignoring"
HTTPRequestDoc.Fields[20].Name = "redirects"
HTTPRequestDoc.Fields[19].Description = "DisableCookie is an optional setting that disables cookie reuse"
HTTPRequestDoc.Fields[19].Comments[encoder.LineComment] = "DisableCookie is an optional setting that disables cookie reuse"
HTTPRequestDoc.Fields[20].Name = "read-all"
HTTPRequestDoc.Fields[20].Type = "bool"
HTTPRequestDoc.Fields[20].Note = ""
HTTPRequestDoc.Fields[20].Description = "Redirects specifies whether redirects should be followed by the HTTP Client.\n\nThis can be used in conjunction with `max-redirects` to control the HTTP request redirects."
HTTPRequestDoc.Fields[20].Comments[encoder.LineComment] = "Redirects specifies whether redirects should be followed by the HTTP Client."
HTTPRequestDoc.Fields[21].Name = "host-redirects"
HTTPRequestDoc.Fields[20].Description = "Enables force reading of the entire raw unsafe request body ignoring\nany specified content length headers."
HTTPRequestDoc.Fields[20].Comments[encoder.LineComment] = "Enables force reading of the entire raw unsafe request body ignoring"
HTTPRequestDoc.Fields[21].Name = "redirects"
HTTPRequestDoc.Fields[21].Type = "bool"
HTTPRequestDoc.Fields[21].Note = ""
HTTPRequestDoc.Fields[21].Description = "Redirects specifies whether only redirects to the same host should be followed by the HTTP Client.\n\nThis can be used in conjunction with `max-redirects` to control the HTTP request redirects."
HTTPRequestDoc.Fields[21].Comments[encoder.LineComment] = "Redirects specifies whether only redirects to the same host should be followed by the HTTP Client."
HTTPRequestDoc.Fields[22].Name = "pipeline"
HTTPRequestDoc.Fields[21].Description = "Redirects specifies whether redirects should be followed by the HTTP Client.\n\nThis can be used in conjunction with `max-redirects` to control the HTTP request redirects."
HTTPRequestDoc.Fields[21].Comments[encoder.LineComment] = "Redirects specifies whether redirects should be followed by the HTTP Client."
HTTPRequestDoc.Fields[22].Name = "host-redirects"
HTTPRequestDoc.Fields[22].Type = "bool"
HTTPRequestDoc.Fields[22].Note = ""
HTTPRequestDoc.Fields[22].Description = "Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining\n\nAll requests must be idempotent (GET/POST). This can be used for race conditions/billions requests."
HTTPRequestDoc.Fields[22].Comments[encoder.LineComment] = "Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining"
HTTPRequestDoc.Fields[23].Name = "unsafe"
HTTPRequestDoc.Fields[22].Description = "Redirects specifies whether only redirects to the same host should be followed by the HTTP Client.\n\nThis can be used in conjunction with `max-redirects` to control the HTTP request redirects."
HTTPRequestDoc.Fields[22].Comments[encoder.LineComment] = "Redirects specifies whether only redirects to the same host should be followed by the HTTP Client."
HTTPRequestDoc.Fields[23].Name = "pipeline"
HTTPRequestDoc.Fields[23].Type = "bool"
HTTPRequestDoc.Fields[23].Note = ""
HTTPRequestDoc.Fields[23].Description = "Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests.\n\nThis uses the [rawhttp](https://github.com/projectdiscovery/rawhttp) engine to achieve complete\ncontrol over the request, with no normalization performed by the client."
HTTPRequestDoc.Fields[23].Comments[encoder.LineComment] = "Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests."
HTTPRequestDoc.Fields[24].Name = "race"
HTTPRequestDoc.Fields[23].Description = "Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining\n\nAll requests must be idempotent (GET/POST). This can be used for race conditions/billions requests."
HTTPRequestDoc.Fields[23].Comments[encoder.LineComment] = "Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining"
HTTPRequestDoc.Fields[24].Name = "unsafe"
HTTPRequestDoc.Fields[24].Type = "bool"
HTTPRequestDoc.Fields[24].Note = ""
HTTPRequestDoc.Fields[24].Description = "Race determines if all the request have to be attempted at the same time (Race Condition)\n\nThe actual number of requests that will be sent is determined by the `race_count` field."
HTTPRequestDoc.Fields[24].Comments[encoder.LineComment] = "Race determines if all the request have to be attempted at the same time (Race Condition)"
HTTPRequestDoc.Fields[25].Name = "req-condition"
HTTPRequestDoc.Fields[24].Description = "Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests.\n\nThis uses the [rawhttp](https://github.com/projectdiscovery/rawhttp) engine to achieve complete\ncontrol over the request, with no normalization performed by the client."
HTTPRequestDoc.Fields[24].Comments[encoder.LineComment] = "Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests."
HTTPRequestDoc.Fields[25].Name = "race"
HTTPRequestDoc.Fields[25].Type = "bool"
HTTPRequestDoc.Fields[25].Note = ""
HTTPRequestDoc.Fields[25].Description = "ReqCondition automatically assigns numbers to requests and preserves their history.\n\nThis allows matching on them later for multi-request conditions."
HTTPRequestDoc.Fields[25].Comments[encoder.LineComment] = "ReqCondition automatically assigns numbers to requests and preserves their history."
HTTPRequestDoc.Fields[26].Name = "stop-at-first-match"
HTTPRequestDoc.Fields[25].Description = "Race determines if all the request have to be attempted at the same time (Race Condition)\n\nThe actual number of requests that will be sent is determined by the `race_count` field."
HTTPRequestDoc.Fields[25].Comments[encoder.LineComment] = "Race determines if all the request have to be attempted at the same time (Race Condition)"
HTTPRequestDoc.Fields[26].Name = "req-condition"
HTTPRequestDoc.Fields[26].Type = "bool"
HTTPRequestDoc.Fields[26].Note = ""
HTTPRequestDoc.Fields[26].Description = "StopAtFirstMatch stops the execution of the requests and template as soon as a match is found."
HTTPRequestDoc.Fields[26].Comments[encoder.LineComment] = "StopAtFirstMatch stops the execution of the requests and template as soon as a match is found."
HTTPRequestDoc.Fields[27].Name = "skip-variables-check"
HTTPRequestDoc.Fields[26].Description = "ReqCondition automatically assigns numbers to requests and preserves their history.\n\nThis allows matching on them later for multi-request conditions."
HTTPRequestDoc.Fields[26].Comments[encoder.LineComment] = "ReqCondition automatically assigns numbers to requests and preserves their history."
HTTPRequestDoc.Fields[27].Name = "stop-at-first-match"
HTTPRequestDoc.Fields[27].Type = "bool"
HTTPRequestDoc.Fields[27].Note = ""
HTTPRequestDoc.Fields[27].Description = "SkipVariablesCheck skips the check for unresolved variables in request"
HTTPRequestDoc.Fields[27].Comments[encoder.LineComment] = "SkipVariablesCheck skips the check for unresolved variables in request"
HTTPRequestDoc.Fields[28].Name = "iterate-all"
HTTPRequestDoc.Fields[27].Description = "StopAtFirstMatch stops the execution of the requests and template as soon as a match is found."
HTTPRequestDoc.Fields[27].Comments[encoder.LineComment] = "StopAtFirstMatch stops the execution of the requests and template as soon as a match is found."
HTTPRequestDoc.Fields[28].Name = "skip-variables-check"
HTTPRequestDoc.Fields[28].Type = "bool"
HTTPRequestDoc.Fields[28].Note = ""
HTTPRequestDoc.Fields[28].Description = "IterateAll iterates all the values extracted from internal extractors"
HTTPRequestDoc.Fields[28].Comments[encoder.LineComment] = "IterateAll iterates all the values extracted from internal extractors"
HTTPRequestDoc.Fields[29].Name = "digest-username"
HTTPRequestDoc.Fields[29].Type = "string"
HTTPRequestDoc.Fields[28].Description = "SkipVariablesCheck skips the check for unresolved variables in request"
HTTPRequestDoc.Fields[28].Comments[encoder.LineComment] = "SkipVariablesCheck skips the check for unresolved variables in request"
HTTPRequestDoc.Fields[29].Name = "iterate-all"
HTTPRequestDoc.Fields[29].Type = "bool"
HTTPRequestDoc.Fields[29].Note = ""
HTTPRequestDoc.Fields[29].Description = "DigestAuthUsername specifies the username for digest authentication"
HTTPRequestDoc.Fields[29].Comments[encoder.LineComment] = "DigestAuthUsername specifies the username for digest authentication"
HTTPRequestDoc.Fields[30].Name = "digest-password"
HTTPRequestDoc.Fields[29].Description = "IterateAll iterates all the values extracted from internal extractors"
HTTPRequestDoc.Fields[29].Comments[encoder.LineComment] = "IterateAll iterates all the values extracted from internal extractors"
HTTPRequestDoc.Fields[30].Name = "digest-username"
HTTPRequestDoc.Fields[30].Type = "string"
HTTPRequestDoc.Fields[30].Note = ""
HTTPRequestDoc.Fields[30].Description = "DigestAuthPassword specifies the password for digest authentication"
HTTPRequestDoc.Fields[30].Comments[encoder.LineComment] = "DigestAuthPassword specifies the password for digest authentication"
HTTPRequestDoc.Fields[31].Name = "disable-path-automerge"
HTTPRequestDoc.Fields[31].Type = "bool"
HTTPRequestDoc.Fields[30].Description = "DigestAuthUsername specifies the username for digest authentication"
HTTPRequestDoc.Fields[30].Comments[encoder.LineComment] = "DigestAuthUsername specifies the username for digest authentication"
HTTPRequestDoc.Fields[31].Name = "digest-password"
HTTPRequestDoc.Fields[31].Type = "string"
HTTPRequestDoc.Fields[31].Note = ""
HTTPRequestDoc.Fields[31].Description = "DisablePathAutomerge disables merging target url path with raw request path"
HTTPRequestDoc.Fields[31].Comments[encoder.LineComment] = "DisablePathAutomerge disables merging target url path with raw request path"
HTTPRequestDoc.Fields[31].Description = "DigestAuthPassword specifies the password for digest authentication"
HTTPRequestDoc.Fields[31].Comments[encoder.LineComment] = "DigestAuthPassword specifies the password for digest authentication"
HTTPRequestDoc.Fields[32].Name = "disable-path-automerge"
HTTPRequestDoc.Fields[32].Type = "bool"
HTTPRequestDoc.Fields[32].Note = ""
HTTPRequestDoc.Fields[32].Description = "DisablePathAutomerge disables merging target url path with raw request path"
HTTPRequestDoc.Fields[32].Comments[encoder.LineComment] = "DisablePathAutomerge disables merging target url path with raw request path"
GENERATORSAttackTypeHolderDoc.Type = "generators.AttackTypeHolder"
GENERATORSAttackTypeHolderDoc.Comments[encoder.LineComment] = " AttackTypeHolder is used to hold internal type of the protocol"

View File

@ -80,6 +80,16 @@ func parseWorkflowTemplate(workflow *workflows.WorkflowTemplate, preprocessor Pr
gologger.Warning().Msgf("Could not parse workflow template %s: no executer found\n", path)
continue
}
if len(template.RequestsCode) > 0 {
if !options.Options.EnableCodeTemplates {
gologger.Warning().Msgf("`-code` flag not found, skipping code template from workflow: %v\n", path)
continue
} else if !template.Verified {
// unverfied code templates are not allowed in workflows
gologger.Warning().Msgf("skipping unverified code template from workflow: %v\n", path)
continue
}
}
workflowTemplates = append(workflowTemplates, template)
}