mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-17 16:05:26 +00:00
Started work on interact.sh support
This commit is contained in:
parent
27f15a9c93
commit
4c594627a9
@ -85,6 +85,12 @@ based on templates offering massive extensibility and ease of use.`)
|
||||
set.IntVar(&options.PageTimeout, "page-timeout", 20, "Seconds to wait for each page in headless")
|
||||
set.BoolVarP(&options.NewTemplates, "new-templates", "nt", false, "Only run newly added templates")
|
||||
set.StringVarP(&options.DiskExportDirectory, "disk-export", "de", "", "Directory on disk to export reports in markdown to")
|
||||
set.BoolVar(&options.Interactsh, "interactsh", false, "Use interactsh server for blind interaction polling")
|
||||
set.StringVar(&options.InteractshURL, "interactsh-url", "https://interact.sh", "Interactsh Server URL")
|
||||
set.IntVar(&options.InteractionsCacheSize, "interactions-cache-size", 5000, "Number of requests to keep in interactions cache")
|
||||
set.IntVar(&options.InteractionsEviction, "interactions-eviction", 60, "Number of seconds to wait before evicting requests from cache")
|
||||
set.IntVar(&options.InteractionsPollDuration, "interactions-poll-duration", 5, "Number of seconds before each interaction poll request")
|
||||
set.IntVar(&options.InteractionsColldownPeriod, "interactions-cooldown-period", 5, "Extra time for interaction polling before exiting")
|
||||
_ = set.Parse()
|
||||
|
||||
if cfgFile != "" {
|
||||
|
||||
@ -16,6 +16,7 @@ require (
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8 // indirect
|
||||
github.com/json-iterator/go v1.1.10
|
||||
github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/karlseguin/ccache v2.0.3+incompatible
|
||||
github.com/karrick/godirwalk v1.16.1
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||
github.com/mattn/go-runewidth v0.0.10 // indirect
|
||||
@ -29,6 +30,7 @@ require (
|
||||
github.com/projectdiscovery/goflags v0.0.4
|
||||
github.com/projectdiscovery/gologger v1.1.4
|
||||
github.com/projectdiscovery/hmap v0.0.1
|
||||
github.com/projectdiscovery/interactsh v0.0.1
|
||||
github.com/projectdiscovery/rawhttp v0.0.6
|
||||
github.com/projectdiscovery/retryabledns v1.0.10
|
||||
github.com/projectdiscovery/retryablehttp-go v1.0.1
|
||||
|
||||
23
v2/go.sum
23
v2/go.sum
@ -68,6 +68,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
|
||||
github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
@ -133,8 +134,11 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
@ -154,6 +158,12 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/karlseguin/ccache v2.0.3+incompatible h1:j68C9tWOROiOLWTS/kCGg9IcJG+ACqn5+0+t8Oh83UU=
|
||||
github.com/karlseguin/ccache v2.0.3+incompatible/go.mod h1:CM9tNPzT6EdRh14+jiW8mEF9mkNZuuE51qmgGYUB93w=
|
||||
github.com/karlseguin/ccache/v2 v2.0.7 h1:y5Pfi4eiyYCOD6LS/Kj+o6Nb4M5Ngpw9qFQs+v44ZYM=
|
||||
github.com/karlseguin/ccache/v2 v2.0.7/go.mod h1:2BDThcfQMf/c0jnZowt16eW405XIqZPavt+HoYEtcxQ=
|
||||
github.com/karlseguin/expect v1.0.2-0.20190806010014-778a5f0c6003 h1:vJ0Snvo+SLMY72r5J4sEfkuE7AFbixEP2qRbEcum/wA=
|
||||
github.com/karlseguin/expect v1.0.2-0.20190806010014-778a5f0c6003/go.mod h1:zNBxMY8P21owkeogJELCLeHIt+voOSduHYTFUbwRAV8=
|
||||
github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
|
||||
github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
@ -164,6 +174,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
@ -203,10 +214,13 @@ github.com/projectdiscovery/fastdialer v0.0.8 h1:mEMc8bfXV5hc1PUEkJiUnR5imYQe6+8
|
||||
github.com/projectdiscovery/fastdialer v0.0.8/go.mod h1:AuaV0dzrNeBLHqjNnzpFSnTXnHGIZAlGQE+WUMmSIW4=
|
||||
github.com/projectdiscovery/goflags v0.0.4 h1:fWKLMAr3KmPlZxE1b54pfei+vGIUJn9q6aM7woZIbCY=
|
||||
github.com/projectdiscovery/goflags v0.0.4/go.mod h1:Ae1mJ5MIIqjys0lFe3GiMZ10Z8VLaxkYJ1ySA4Zv8HA=
|
||||
github.com/projectdiscovery/gologger v1.1.3/go.mod h1:jdXflz3TLB8bcVNzb0v26TztI9KPz8Lr4BVdUhNUs6E=
|
||||
github.com/projectdiscovery/gologger v1.1.4 h1:qWxGUq7ukHWT849uGPkagPKF3yBPYAsTtMKunQ8O2VI=
|
||||
github.com/projectdiscovery/gologger v1.1.4/go.mod h1:Bhb6Bdx2PV1nMaFLoXNBmHIU85iROS9y1tBuv7T5pMY=
|
||||
github.com/projectdiscovery/hmap v0.0.1 h1:VAONbJw5jP+syI5smhsfkrq9XPGn4aiYy5pR6KR1wog=
|
||||
github.com/projectdiscovery/hmap v0.0.1/go.mod h1:VDEfgzkKQdq7iGTKz8Ooul0NuYHQ8qiDs6r8bPD1Sb0=
|
||||
github.com/projectdiscovery/interactsh v0.0.1 h1:yte2Jf4Trv2CQctj/ccVbNQBQ7lPCrfaOkCS+yhdhVg=
|
||||
github.com/projectdiscovery/interactsh v0.0.1/go.mod h1:UXWCRqB0HqkgK5TsUJNA4Hqu1A/MW0DOABcGYG3vpB0=
|
||||
github.com/projectdiscovery/rawhttp v0.0.6 h1:HbgPB1eKXQVV5F9sq0Uxflm95spWFyZYD8dgFpeOC9M=
|
||||
github.com/projectdiscovery/rawhttp v0.0.6/go.mod h1:PQERZAhAv7yxI/hR6hdDPgK1WTU56l204BweXrBec+0=
|
||||
github.com/projectdiscovery/retryabledns v1.0.7/go.mod h1:/UzJn4I+cPdQl6pKiiQfvVAT636YZvJQYZhYhGB0dUQ=
|
||||
@ -214,6 +228,8 @@ github.com/projectdiscovery/retryabledns v1.0.10 h1:xJZ2aKoqrNg/OZEw1+4+QIOH40V/
|
||||
github.com/projectdiscovery/retryabledns v1.0.10/go.mod h1:4sMC8HZyF01HXukRleSQYwz4870bwgb4+hTSXTMrkf4=
|
||||
github.com/projectdiscovery/retryablehttp-go v1.0.1 h1:V7wUvsZNq1Rcz7+IlcyoyQlNwshuwptuBVYWw9lx8RE=
|
||||
github.com/projectdiscovery/retryablehttp-go v1.0.1/go.mod h1:SrN6iLZilNG1X4neq1D+SBxoqfAF4nyzvmevkTkWsek=
|
||||
github.com/prologic/smtpd v0.0.0-20210126001904-0893ad18168e h1:ZT3wZ92sp/EHEE/HcFCWCsYS3ROLjHb6EqSX8qYrgXw=
|
||||
github.com/prologic/smtpd v0.0.0-20210126001904-0893ad18168e/go.mod h1:GkLsdH1RZj6RDKeI9A05NGZYmEZQ/PbQcZPnZoSZuYI=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/remeh/sizedwaitgroup v1.0.0 h1:VNGGFwNo/R5+MJBf6yrsr110p0m4/OX4S3DCy7Kyl5E=
|
||||
github.com/remeh/sizedwaitgroup v1.0.0/go.mod h1:3j2R4OIe/SeS6YDhICBy22RWjJC5eNCJ1V+9+NVNYlo=
|
||||
@ -233,6 +249,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
@ -244,6 +261,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ=
|
||||
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM=
|
||||
github.com/xanzy/go-gitlab v0.44.0 h1:cEiGhqu7EpFGuei2a2etAwB+x6403E5CvpLn35y+GPs=
|
||||
github.com/xanzy/go-gitlab v0.44.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||
github.com/ysmood/goob v0.3.0 h1:XZ51cZJ4W3WCoCiUktixzMIQF86W7G5VFL4QQ/Q2uS0=
|
||||
@ -276,6 +295,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210218145215-b8e89b74b9df h1:y7QZzfUiTwWam+xBn29Ulb8CBwVN5UdzmMDavl9Whlw=
|
||||
@ -387,6 +407,7 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201113233024-12cec1faf1ba/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -533,6 +554,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/corvus-ch/zbase32.v1 v1.0.0 h1:K4u1NprbDNvKPczKfHLbwdOWHTZ0zfv2ow71H1nRnFU=
|
||||
gopkg.in/corvus-ch/zbase32.v1 v1.0.0/go.mod h1:T3oKkPOm4AV/bNXCNFUxRmlE9RUyBz/DSo0nK9U+c0Y=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/logrusorgru/aurora"
|
||||
"github.com/projectdiscovery/gologger"
|
||||
@ -18,6 +19,7 @@ import (
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/projectfile"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/clusterer"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/interactsh"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/headless/engine"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/reporting"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/reporting/exporters/disk"
|
||||
@ -34,6 +36,7 @@ import (
|
||||
type Runner struct {
|
||||
hostMap *hybrid.HybridMap
|
||||
output output.Writer
|
||||
interactsh *interactsh.Client
|
||||
inputCount int64
|
||||
templatesConfig *nucleiConfig
|
||||
options *types.Options
|
||||
@ -196,6 +199,22 @@ func New(options *types.Options) (*Runner, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if options.Interactsh {
|
||||
interactshClient, err := interactsh.New(&interactsh.Options{
|
||||
ServerURL: options.InteractshURL,
|
||||
CacheSize: int64(options.InteractionsCacheSize),
|
||||
Eviction: time.Duration(options.InteractionsEviction) * time.Second,
|
||||
ColldownPeriod: time.Duration(options.InteractionsColldownPeriod) * time.Second,
|
||||
PollDuration: time.Duration(options.InteractionsPollDuration) * time.Second,
|
||||
Output: runner.output,
|
||||
Progress: runner.progress,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
runner.interactsh = interactshClient
|
||||
}
|
||||
|
||||
// Enable Polling
|
||||
if options.BurpCollaboratorBiid != "" {
|
||||
collaborator.DefaultCollaborator.Collab.AddBIID(options.BurpCollaboratorBiid)
|
||||
@ -289,6 +308,7 @@ func (r *Runner) RunEnumeration() {
|
||||
IssuesClient: r.issuesClient,
|
||||
Browser: r.browser,
|
||||
ProjectFile: r.projectFile,
|
||||
Interactsh: r.interactsh,
|
||||
}
|
||||
clusterID := fmt.Sprintf("cluster-%s", xid.New().String())
|
||||
|
||||
@ -350,6 +370,10 @@ func (r *Runner) RunEnumeration() {
|
||||
}(t)
|
||||
}
|
||||
wgtemplates.Wait()
|
||||
|
||||
if r.interactsh != nil {
|
||||
r.interactsh.Close()
|
||||
}
|
||||
r.progress.Stop()
|
||||
|
||||
if r.issuesClient != nil {
|
||||
|
||||
@ -62,6 +62,7 @@ func (r *Runner) parseTemplateFile(file string) (*templates.Template, error) {
|
||||
Catalog: r.catalog,
|
||||
IssuesClient: r.issuesClient,
|
||||
RateLimiter: r.ratelimiter,
|
||||
Interactsh: r.interactsh,
|
||||
ProjectFile: r.projectFile,
|
||||
Browser: r.browser,
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/logrusorgru/aurora"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/projectdiscovery/interactsh/pkg/server"
|
||||
"github.com/projectdiscovery/nuclei/v2/internal/colorizer"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/operators"
|
||||
)
|
||||
@ -79,6 +80,8 @@ type ResultEvent struct {
|
||||
IP string `json:"ip,omitempty"`
|
||||
// Timestamp is the time the result was found at.
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
// Interaction is the full details of interactsh interaction.
|
||||
Interaction *server.Interaction `json:"interaction,omitempty"`
|
||||
}
|
||||
|
||||
// NewStandardWriter creates a new output writer based on user configurations
|
||||
|
||||
145
v2/pkg/protocols/common/interactsh/interactsh.go
Normal file
145
v2/pkg/protocols/common/interactsh/interactsh.go
Normal file
@ -0,0 +1,145 @@
|
||||
package interactsh
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/karlseguin/ccache"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/projectdiscovery/interactsh/pkg/client"
|
||||
"github.com/projectdiscovery/interactsh/pkg/server"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/operators"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/progress"
|
||||
"github.com/valyala/fasttemplate"
|
||||
)
|
||||
|
||||
// Client is a wrapped client for interactsh server.
|
||||
type Client struct {
|
||||
// interactsh is a client for interactsh server.
|
||||
interactsh *client.Client
|
||||
// requests is a stored cache for interactsh-url->request-event data.
|
||||
requests *ccache.Cache
|
||||
|
||||
dotHostname string
|
||||
eviction time.Duration
|
||||
pollDuration time.Duration
|
||||
cooldownDuration time.Duration
|
||||
}
|
||||
|
||||
var interactshURLMarker = "{{interactsh-url}}"
|
||||
|
||||
// Options contains configuration options for interactsh nuclei integration.
|
||||
type Options struct {
|
||||
// ServerURL is the URL of the interactsh server.
|
||||
ServerURL string
|
||||
// CacheSize is the numbers of requests to keep track of at a time.
|
||||
// Older items are discarded in LRU manner in favor of new requests.
|
||||
CacheSize int64
|
||||
// Eviction is the period of time after which to automatically discard
|
||||
// interaction requests.
|
||||
Eviction time.Duration
|
||||
// CooldownPeriod is additional time to wait for interactions after closing
|
||||
// of the poller.
|
||||
ColldownPeriod time.Duration
|
||||
// PollDuration is the time to wait before each poll to the server for interactions.
|
||||
PollDuration time.Duration
|
||||
// Output is the output writer for nuclei
|
||||
Output output.Writer
|
||||
// Progress is the nuclei progress bar implementation.
|
||||
Progress progress.Progress
|
||||
}
|
||||
|
||||
// New returns a new interactsh server client
|
||||
func New(options *Options) (*Client, error) {
|
||||
parsed, err := url.Parse(options.ServerURL)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not parse server url")
|
||||
}
|
||||
|
||||
interactsh, err := client.New(&client.Options{
|
||||
ServerURL: options.ServerURL,
|
||||
PersistentSession: false,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not create client")
|
||||
}
|
||||
configure := ccache.Configure()
|
||||
configure = configure.MaxSize(options.CacheSize)
|
||||
cache := ccache.New(configure)
|
||||
|
||||
interactClient := &Client{
|
||||
interactsh: interactsh,
|
||||
eviction: options.Eviction,
|
||||
dotHostname: "." + parsed.Host,
|
||||
requests: cache,
|
||||
pollDuration: options.PollDuration,
|
||||
cooldownDuration: options.ColldownPeriod,
|
||||
}
|
||||
interactClient.interactsh.StartPolling(interactClient.pollDuration, func(interaction *server.Interaction) {
|
||||
item := interactClient.requests.Get(interaction.UniqueID)
|
||||
if item == nil {
|
||||
return
|
||||
}
|
||||
data, ok := item.Value().(*internalRequestEvent)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
interactClient.requests.Delete(interaction.UniqueID)
|
||||
|
||||
data.event.OperatorsResult = &operators.Result{
|
||||
Matches: map[string]struct{}{strings.ToLower(interaction.Protocol): {}},
|
||||
}
|
||||
data.event.Results = data.makeResultFunc(data.event)
|
||||
for _, result := range data.event.Results {
|
||||
result.Interaction = interaction
|
||||
_ = options.Output.Write(result)
|
||||
options.Progress.IncrementMatched()
|
||||
}
|
||||
})
|
||||
return interactClient, nil
|
||||
}
|
||||
|
||||
// URL returns a new URL that can be interacted with
|
||||
func (c *Client) URL() string {
|
||||
return c.interactsh.URL()
|
||||
}
|
||||
|
||||
// Close closes the interactsh clients after waiting for cooldown period.
|
||||
func (c *Client) Close() {
|
||||
if c.cooldownDuration > 0 {
|
||||
time.Sleep(c.cooldownDuration)
|
||||
}
|
||||
c.interactsh.StopPolling()
|
||||
c.interactsh.Close()
|
||||
}
|
||||
|
||||
// ReplaceMarkers replaces the {{interactsh-url}} placeholders to actual
|
||||
// URLs pointing to interactsh-server.
|
||||
//
|
||||
// It accepts data to replace as well as the URL to replace placeholders
|
||||
// with generated uniquely for each request.
|
||||
func (c *Client) ReplaceMarkers(data, interactshURL string) string {
|
||||
if !strings.Contains(data, interactshURLMarker) {
|
||||
return data
|
||||
}
|
||||
replaced := fasttemplate.ExecuteStringStd(data, "{{", "}}", map[string]interface{}{
|
||||
"interactsh-url": interactshURL,
|
||||
})
|
||||
return replaced
|
||||
}
|
||||
|
||||
// MakeResultEventFunc is a result making function for nuclei
|
||||
type MakeResultEventFunc func(wrapped *output.InternalWrappedEvent) []*output.ResultEvent
|
||||
|
||||
type internalRequestEvent struct {
|
||||
makeResultFunc MakeResultEventFunc
|
||||
event *output.InternalWrappedEvent
|
||||
}
|
||||
|
||||
// RequestEvent is the event for a network request sent by nuclei.
|
||||
func (c *Client) RequestEvent(interactshURL string, event *output.InternalWrappedEvent, makeResult MakeResultEventFunc) {
|
||||
id := strings.TrimSuffix(interactshURL, c.dotHostname)
|
||||
c.requests.Set(id, &internalRequestEvent{makeResultFunc: makeResult, event: event}, c.eviction)
|
||||
}
|
||||
@ -37,7 +37,7 @@ type generatedRequest struct {
|
||||
|
||||
// Make creates a http request for the provided input.
|
||||
// It returns io.EOF as error when all the requests have been exhausted.
|
||||
func (r *requestGenerator) Make(baseURL string, dynamicValues map[string]interface{}) (*generatedRequest, error) {
|
||||
func (r *requestGenerator) Make(baseURL string, dynamicValues map[string]interface{}, interactURL string) (*generatedRequest, error) {
|
||||
// We get the next payload for the request.
|
||||
data, payloads, ok := r.nextValue()
|
||||
if !ok {
|
||||
@ -60,14 +60,18 @@ func (r *requestGenerator) Make(baseURL string, dynamicValues map[string]interfa
|
||||
parsed.Path = strings.TrimSuffix(parsed.Path, "/")
|
||||
}
|
||||
parsedString := parsed.String()
|
||||
|
||||
if r.options.Interactsh != nil {
|
||||
parsedString = r.options.Interactsh.ReplaceMarkers(parsedString, interactURL)
|
||||
}
|
||||
values["BaseURL"] = parsedString
|
||||
|
||||
// If data contains \n it's a raw request, process it like raw. Else
|
||||
// continue with the template based request flow.
|
||||
if isRawRequest {
|
||||
return r.makeHTTPRequestFromRaw(ctx, parsedString, data, values, payloads)
|
||||
return r.makeHTTPRequestFromRaw(ctx, parsedString, data, values, payloads, interactURL)
|
||||
}
|
||||
return r.makeHTTPRequestFromModel(ctx, data, values)
|
||||
return r.makeHTTPRequestFromModel(ctx, data, values, interactURL)
|
||||
}
|
||||
|
||||
// Total returns the total number of requests for the generator
|
||||
@ -96,7 +100,7 @@ func baseURLWithTemplatePrefs(data string, parsed *url.URL) (string, *url.URL) {
|
||||
}
|
||||
|
||||
// MakeHTTPRequestFromModel creates a *http.Request from a request template
|
||||
func (r *requestGenerator) makeHTTPRequestFromModel(ctx context.Context, data string, values map[string]interface{}) (*generatedRequest, error) {
|
||||
func (r *requestGenerator) makeHTTPRequestFromModel(ctx context.Context, data string, values map[string]interface{}, interactURL string) (*generatedRequest, error) {
|
||||
final := replacer.Replace(data, values)
|
||||
|
||||
// Build a request on the specified URL
|
||||
@ -105,7 +109,7 @@ func (r *requestGenerator) makeHTTPRequestFromModel(ctx context.Context, data st
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request, err := r.fillRequest(req, values)
|
||||
request, err := r.fillRequest(req, values, interactURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -113,7 +117,10 @@ func (r *requestGenerator) makeHTTPRequestFromModel(ctx context.Context, data st
|
||||
}
|
||||
|
||||
// makeHTTPRequestFromRaw creates a *http.Request from a raw request
|
||||
func (r *requestGenerator) makeHTTPRequestFromRaw(ctx context.Context, baseURL, data string, values, payloads map[string]interface{}) (*generatedRequest, error) {
|
||||
func (r *requestGenerator) makeHTTPRequestFromRaw(ctx context.Context, baseURL, data string, values, payloads map[string]interface{}, interactURL string) (*generatedRequest, error) {
|
||||
if r.options.Interactsh != nil {
|
||||
data = r.options.Interactsh.ReplaceMarkers(data, interactURL)
|
||||
}
|
||||
return r.handleRawWithPayloads(ctx, data, baseURL, values, payloads)
|
||||
}
|
||||
|
||||
@ -159,7 +166,7 @@ func (r *requestGenerator) handleRawWithPayloads(ctx context.Context, rawRequest
|
||||
}
|
||||
req.Header[key] = []string{value}
|
||||
}
|
||||
request, err := r.fillRequest(req, values)
|
||||
request, err := r.fillRequest(req, values, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -168,9 +175,12 @@ func (r *requestGenerator) handleRawWithPayloads(ctx context.Context, rawRequest
|
||||
}
|
||||
|
||||
// fillRequest fills various headers in the request with values
|
||||
func (r *requestGenerator) fillRequest(req *http.Request, values map[string]interface{}) (*retryablehttp.Request, error) {
|
||||
func (r *requestGenerator) fillRequest(req *http.Request, values map[string]interface{}, interactURL string) (*retryablehttp.Request, error) {
|
||||
// Set the header values requested
|
||||
for header, value := range r.request.Headers {
|
||||
if interactURL != "" && r.options.Interactsh != nil {
|
||||
value = r.options.Interactsh.ReplaceMarkers(value, interactURL)
|
||||
}
|
||||
req.Header[header] = []string{replacer.Replace(value, values)}
|
||||
}
|
||||
|
||||
@ -181,7 +191,11 @@ func (r *requestGenerator) fillRequest(req *http.Request, values map[string]inte
|
||||
|
||||
// Check if the user requested a request body
|
||||
if r.request.Body != "" {
|
||||
req.Body = ioutil.NopCloser(strings.NewReader(r.request.Body))
|
||||
body := r.request.Body
|
||||
if interactURL != "" && r.options.Interactsh != nil {
|
||||
body = r.options.Interactsh.ReplaceMarkers(body, interactURL)
|
||||
}
|
||||
req.Body = ioutil.NopCloser(strings.NewReader(body))
|
||||
}
|
||||
setHeader(req, "User-Agent", uarand.GetRandom())
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ func TestMakeRequestFromModal(t *testing.T) {
|
||||
require.Nil(t, err, "could not compile http request")
|
||||
|
||||
generator := request.newGenerator()
|
||||
req, err := generator.Make("https://example.com", map[string]interface{}{})
|
||||
req, err := generator.Make("https://example.com", map[string]interface{}{}, "")
|
||||
require.Nil(t, err, "could not make http request")
|
||||
|
||||
bodyBytes, _ := req.request.BodyBytes()
|
||||
@ -69,12 +69,12 @@ func TestMakeRequestFromModalTrimSuffixSlash(t *testing.T) {
|
||||
require.Nil(t, err, "could not compile http request")
|
||||
|
||||
generator := request.newGenerator()
|
||||
req, err := generator.Make("https://example.com/test.php", map[string]interface{}{})
|
||||
req, err := generator.Make("https://example.com/test.php", map[string]interface{}{}, "")
|
||||
require.Nil(t, err, "could not make http request")
|
||||
require.Equal(t, "https://example.com/test.php?query=example", req.request.URL.String(), "could not get correct request path")
|
||||
|
||||
generator = request.newGenerator()
|
||||
req, err = generator.Make("https://example.com/test/", map[string]interface{}{})
|
||||
req, err = generator.Make("https://example.com/test/", map[string]interface{}{}, "")
|
||||
require.Nil(t, err, "could not make http request")
|
||||
require.Equal(t, "https://example.com/test/?query=example", req.request.URL.String(), "could not get correct request path")
|
||||
}
|
||||
@ -107,12 +107,12 @@ Accept-Encoding: gzip`},
|
||||
require.Nil(t, err, "could not compile http request")
|
||||
|
||||
generator := request.newGenerator()
|
||||
req, err := generator.Make("https://example.com", map[string]interface{}{})
|
||||
req, err := generator.Make("https://example.com", map[string]interface{}{}, "")
|
||||
require.Nil(t, err, "could not make http request")
|
||||
authorization := req.request.Header.Get("Authorization")
|
||||
require.Equal(t, "Basic admin:admin", authorization, "could not get correct authorization headers from raw")
|
||||
|
||||
req, err = generator.Make("https://example.com", map[string]interface{}{})
|
||||
req, err = generator.Make("https://example.com", map[string]interface{}{}, "")
|
||||
require.Nil(t, err, "could not make http request")
|
||||
authorization = req.request.Header.Get("Authorization")
|
||||
require.Equal(t, "Basic admin:guest", authorization, "could not get correct authorization headers from raw")
|
||||
@ -146,12 +146,12 @@ Accept-Encoding: gzip`},
|
||||
require.Nil(t, err, "could not compile http request")
|
||||
|
||||
generator := request.newGenerator()
|
||||
req, err := generator.Make("https://example.com", map[string]interface{}{})
|
||||
req, err := generator.Make("https://example.com", map[string]interface{}{}, "")
|
||||
require.Nil(t, err, "could not make http request")
|
||||
authorization := req.request.Header.Get("Authorization")
|
||||
require.Equal(t, "Basic YWRtaW46YWRtaW4=", authorization, "could not get correct authorization headers from raw")
|
||||
|
||||
req, err = generator.Make("https://example.com", map[string]interface{}{})
|
||||
req, err = generator.Make("https://example.com", map[string]interface{}{}, "")
|
||||
require.Nil(t, err, "could not make http request")
|
||||
authorization = req.request.Header.Get("Authorization")
|
||||
require.Equal(t, "Basic YWRtaW46Z3Vlc3Q=", authorization, "could not get correct authorization headers from raw")
|
||||
|
||||
@ -33,7 +33,7 @@ func (r *Request) executeRaceRequest(reqURL string, previous output.InternalEven
|
||||
// Requests within race condition should be dumped once and the output prefilled to allow DSL language to work
|
||||
// This will introduce a delay and will populate in hacky way the field "request" of outputEvent
|
||||
generator := r.newGenerator()
|
||||
requestForDump, err := generator.Make(reqURL, nil)
|
||||
requestForDump, err := generator.Make(reqURL, nil, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -51,7 +51,7 @@ func (r *Request) executeRaceRequest(reqURL string, previous output.InternalEven
|
||||
// Pre-Generate requests
|
||||
for i := 0; i < r.RaceNumberRequests; i++ {
|
||||
generator := r.newGenerator()
|
||||
request, err := generator.Make(reqURL, nil)
|
||||
request, err := generator.Make(reqURL, nil, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -90,7 +90,7 @@ func (r *Request) executeParallelHTTP(reqURL string, dynamicValues, previous out
|
||||
var requestErr error
|
||||
mutex := &sync.Mutex{}
|
||||
for {
|
||||
request, err := generator.Make(reqURL, dynamicValues)
|
||||
request, err := generator.Make(reqURL, dynamicValues, "")
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
@ -148,7 +148,7 @@ func (r *Request) executeTurboHTTP(reqURL string, dynamicValues, previous output
|
||||
var requestErr error
|
||||
mutex := &sync.Mutex{}
|
||||
for {
|
||||
request, err := generator.Make(reqURL, dynamicValues)
|
||||
request, err := generator.Make(reqURL, dynamicValues, "")
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
@ -197,7 +197,12 @@ func (r *Request) ExecuteWithResults(reqURL string, dynamicValues, previous outp
|
||||
requestCount := 1
|
||||
var requestErr error
|
||||
for {
|
||||
request, err := generator.Make(reqURL, dynamicValues)
|
||||
var interactURL string
|
||||
|
||||
if r.options.Interactsh != nil {
|
||||
interactURL = r.options.Interactsh.URL()
|
||||
}
|
||||
request, err := generator.Make(reqURL, dynamicValues, interactURL)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
@ -214,6 +219,9 @@ func (r *Request) ExecuteWithResults(reqURL string, dynamicValues, previous outp
|
||||
gotOutput = true
|
||||
dynamicValues = generators.MergeMaps(dynamicValues, event.OperatorsResult.DynamicValues)
|
||||
}
|
||||
if r.options.Interactsh != nil {
|
||||
r.options.Interactsh.RequestEvent(interactURL, event, r.MakeResultEvent)
|
||||
}
|
||||
callback(event)
|
||||
}, requestCount)
|
||||
if err != nil {
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
package http
|
||||
|
||||
import "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
|
||||
import (
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
|
||||
)
|
||||
|
||||
// requestGenerator generates requests sequentially based on various
|
||||
// configurations for a http request template.
|
||||
@ -11,12 +14,13 @@ import "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
|
||||
type requestGenerator struct {
|
||||
currentIndex int
|
||||
request *Request
|
||||
options *protocols.ExecuterOptions
|
||||
payloadIterator *generators.Iterator
|
||||
}
|
||||
|
||||
// newGenerator creates a new request generator instance
|
||||
func (r *Request) newGenerator() *requestGenerator {
|
||||
generator := &requestGenerator{request: r}
|
||||
generator := &requestGenerator{request: r, options: r.options}
|
||||
|
||||
if len(r.Payloads) > 0 {
|
||||
generator.payloadIterator = r.generator.NewIterator()
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/progress"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/projectfile"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/interactsh"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/headless/engine"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/reporting"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
||||
@ -50,6 +51,8 @@ type ExecuterOptions struct {
|
||||
ProjectFile *projectfile.ProjectFile
|
||||
// Browser is a browser engine for running headless templates
|
||||
Browser *engine.Browser
|
||||
// Interactsh is a client for interactsh oob polling server
|
||||
Interactsh *interactsh.Client
|
||||
|
||||
Operators []*operators.Operators // only used by offlinehttp module
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ type Options struct {
|
||||
BurpCollaboratorBiid string
|
||||
// ProjectPath allows nuclei to use a user defined project folder
|
||||
ProjectPath string
|
||||
// InteractshURL is the URL for the interactsh server.
|
||||
InteractshURL string
|
||||
// Target is a single URL/Domain to scan using a template
|
||||
Target string
|
||||
// Targets specifies the targets to scan using templates.
|
||||
@ -63,6 +65,16 @@ type Options struct {
|
||||
RateLimit int
|
||||
// PageTimeout is the maximum time to wait for a page in seconds
|
||||
PageTimeout int
|
||||
// InteractionsCacheSize is the number of interaction-url->req to keep in cache at a time.
|
||||
InteractionsCacheSize int
|
||||
// InteractionsPollDuration is the number of seconds to wait before each interaction poll
|
||||
InteractionsPollDuration int
|
||||
// Eviction is the number of seconds after which to automatically discard
|
||||
// interaction requests.
|
||||
InteractionsEviction int
|
||||
// InteractionsColldownPeriod is additional seconds to wait for interactions after closing
|
||||
// of the poller.
|
||||
InteractionsColldownPeriod int
|
||||
// OfflineHTTP is a flag that specific offline processing of http response
|
||||
// using same matchers/extractors from http protocol without the need
|
||||
// to send a new request, reading responses from a file.
|
||||
@ -111,4 +123,6 @@ type Options struct {
|
||||
Project bool
|
||||
// NewTemplates only runs newly added templates from the repository
|
||||
NewTemplates bool
|
||||
// Interactsh enables use of interactsh server for interaction polling
|
||||
Interactsh bool
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user