From 4c594627a9ce95ba26a3a9b8e26963f2d90443b3 Mon Sep 17 00:00:00 2001 From: Ice3man543 Date: Fri, 16 Apr 2021 16:56:41 +0530 Subject: [PATCH 01/11] Started work on interact.sh support --- v2/cmd/nuclei/main.go | 6 + v2/go.mod | 2 + v2/go.sum | 23 +++ v2/internal/runner/runner.go | 24 +++ v2/internal/runner/templates.go | 1 + v2/pkg/output/output.go | 3 + .../protocols/common/interactsh/interactsh.go | 145 ++++++++++++++++++ v2/pkg/protocols/http/build_request.go | 32 ++-- v2/pkg/protocols/http/build_request_test.go | 14 +- v2/pkg/protocols/http/request.go | 18 ++- v2/pkg/protocols/http/request_generator.go | 8 +- v2/pkg/protocols/protocols.go | 3 + v2/pkg/types/types.go | 14 ++ 13 files changed, 270 insertions(+), 23 deletions(-) create mode 100644 v2/pkg/protocols/common/interactsh/interactsh.go diff --git a/v2/cmd/nuclei/main.go b/v2/cmd/nuclei/main.go index a26d41c8a..019c78890 100644 --- a/v2/cmd/nuclei/main.go +++ b/v2/cmd/nuclei/main.go @@ -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 != "" { diff --git a/v2/go.mod b/v2/go.mod index 972c641ef..490eb9b02 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -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 diff --git a/v2/go.sum b/v2/go.sum index 44e195edf..383067ce1 100644 --- a/v2/go.sum +++ b/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= diff --git a/v2/internal/runner/runner.go b/v2/internal/runner/runner.go index 18d2ba117..49f2dc57d 100644 --- a/v2/internal/runner/runner.go +++ b/v2/internal/runner/runner.go @@ -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 { diff --git a/v2/internal/runner/templates.go b/v2/internal/runner/templates.go index 0624cf7bd..e24d34603 100644 --- a/v2/internal/runner/templates.go +++ b/v2/internal/runner/templates.go @@ -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, } diff --git a/v2/pkg/output/output.go b/v2/pkg/output/output.go index faf7fb793..2fac10fd7 100644 --- a/v2/pkg/output/output.go +++ b/v2/pkg/output/output.go @@ -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 diff --git a/v2/pkg/protocols/common/interactsh/interactsh.go b/v2/pkg/protocols/common/interactsh/interactsh.go new file mode 100644 index 000000000..10480ac48 --- /dev/null +++ b/v2/pkg/protocols/common/interactsh/interactsh.go @@ -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) +} diff --git a/v2/pkg/protocols/http/build_request.go b/v2/pkg/protocols/http/build_request.go index c372a6fea..ed5e27960 100644 --- a/v2/pkg/protocols/http/build_request.go +++ b/v2/pkg/protocols/http/build_request.go @@ -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()) diff --git a/v2/pkg/protocols/http/build_request_test.go b/v2/pkg/protocols/http/build_request_test.go index 6ad75f7a1..994b48570 100644 --- a/v2/pkg/protocols/http/build_request_test.go +++ b/v2/pkg/protocols/http/build_request_test.go @@ -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") diff --git a/v2/pkg/protocols/http/request.go b/v2/pkg/protocols/http/request.go index ba19243a9..0e9f5fb80 100644 --- a/v2/pkg/protocols/http/request.go +++ b/v2/pkg/protocols/http/request.go @@ -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 { diff --git a/v2/pkg/protocols/http/request_generator.go b/v2/pkg/protocols/http/request_generator.go index c3199165a..d474792b4 100644 --- a/v2/pkg/protocols/http/request_generator.go +++ b/v2/pkg/protocols/http/request_generator.go @@ -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() diff --git a/v2/pkg/protocols/protocols.go b/v2/pkg/protocols/protocols.go index d4e89a02d..9225c523f 100644 --- a/v2/pkg/protocols/protocols.go +++ b/v2/pkg/protocols/protocols.go @@ -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 } diff --git a/v2/pkg/types/types.go b/v2/pkg/types/types.go index 08f7bebdb..d5bd5f22b 100644 --- a/v2/pkg/types/types.go +++ b/v2/pkg/types/types.go @@ -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 } From 33bf306f28cbe22d4ef1f06c8708a0df8544ac94 Mon Sep 17 00:00:00 2001 From: Ice3man543 Date: Sun, 18 Apr 2021 16:10:10 +0530 Subject: [PATCH 02/11] Working interactsh integration --- v2/internal/runner/runner.go | 5 +- v2/pkg/operators/operators.go | 27 ++++++++ .../protocols/common/interactsh/interactsh.go | 61 +++++++++++++++---- v2/pkg/protocols/http/request.go | 29 ++++++--- v2/pkg/protocols/network/request.go | 31 ++++++++-- 5 files changed, 127 insertions(+), 26 deletions(-) diff --git a/v2/internal/runner/runner.go b/v2/internal/runner/runner.go index 49f2dc57d..839acc6f8 100644 --- a/v2/internal/runner/runner.go +++ b/v2/internal/runner/runner.go @@ -372,7 +372,10 @@ func (r *Runner) RunEnumeration() { wgtemplates.Wait() if r.interactsh != nil { - r.interactsh.Close() + matched := r.interactsh.Close() + if matched { + results.CAS(false, true) + } } r.progress.Stop() diff --git a/v2/pkg/operators/operators.go b/v2/pkg/operators/operators.go index 423ed40d5..228255d6e 100644 --- a/v2/pkg/operators/operators.go +++ b/v2/pkg/operators/operators.go @@ -65,6 +65,32 @@ type Result struct { PayloadValues map[string]interface{} } +// Merge merges a result structure into the other. +func (r *Result) Merge(result *Result) { + if !r.Matched && result.Matched { + r.Matched = result.Matched + } + if !r.Extracted && result.Extracted { + r.Extracted = result.Extracted + } + + for k, v := range result.Matches { + r.Matches[k] = v + } + for k, v := range result.Extracts { + r.Extracts[k] = v + } + for _, v := range result.OutputExtracts { + r.OutputExtracts = append(r.OutputExtracts, v) + } + for k, v := range result.DynamicValues { + r.DynamicValues[k] = v + } + for k, v := range result.PayloadValues { + r.PayloadValues[k] = v + } +} + // MatchFunc performs matching operation for a matcher on model and returns true or false. type MatchFunc func(data map[string]interface{}, matcher *matchers.Matcher) bool @@ -81,6 +107,7 @@ func (r *Operators) Execute(data map[string]interface{}, match MatchFunc, extrac Extracts: make(map[string][]string), DynamicValues: make(map[string]interface{}), } + // Start with the extractors first and evaluate them. for _, extractor := range r.Extractors { var extractorResults []string diff --git a/v2/pkg/protocols/common/interactsh/interactsh.go b/v2/pkg/protocols/common/interactsh/interactsh.go index 10480ac48..6c11010c5 100644 --- a/v2/pkg/protocols/common/interactsh/interactsh.go +++ b/v2/pkg/protocols/common/interactsh/interactsh.go @@ -22,6 +22,7 @@ type Client struct { // requests is a stored cache for interactsh-url->request-event data. requests *ccache.Cache + matched bool dotHostname string eviction time.Duration pollDuration time.Duration @@ -77,24 +78,38 @@ func New(options *Options) (*Client, error) { 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) + data, ok := item.Value().(*RequestData) if !ok { return } + + data.Event.InternalEvent["interactsh-protocol"] = interaction.Protocol + data.Event.InternalEvent["interactsh-request"] = interaction.RawRequest + data.Event.InternalEvent["interactsh-response"] = interaction.RawResponse + result, matched := data.Operators.Execute(data.Event.InternalEvent, data.MatchFunc, data.ExtractFunc) + if !matched || result == nil { + return // if we don't match, return + } interactClient.requests.Delete(interaction.UniqueID) - data.event.OperatorsResult = &operators.Result{ - Matches: map[string]struct{}{strings.ToLower(interaction.Protocol): {}}, + if data.Event.OperatorsResult != nil { + data.Event.OperatorsResult.Merge(result) + } else { + data.Event.OperatorsResult = result } - data.event.Results = data.makeResultFunc(data.event) - for _, result := range data.event.Results { + data.Event.Results = data.MakeResultFunc(data.Event) + for _, result := range data.Event.Results { result.Interaction = interaction _ = options.Output.Write(result) + if !interactClient.matched { + interactClient.matched = true + } options.Progress.IncrementMatched() } }) @@ -107,12 +122,13 @@ func (c *Client) URL() string { } // Close closes the interactsh clients after waiting for cooldown period. -func (c *Client) Close() { +func (c *Client) Close() bool { if c.cooldownDuration > 0 { time.Sleep(c.cooldownDuration) } c.interactsh.StopPolling() c.interactsh.Close() + return c.matched } // ReplaceMarkers replaces the {{interactsh-url}} placeholders to actual @@ -133,13 +149,36 @@ func (c *Client) ReplaceMarkers(data, interactshURL string) string { // MakeResultEventFunc is a result making function for nuclei type MakeResultEventFunc func(wrapped *output.InternalWrappedEvent) []*output.ResultEvent -type internalRequestEvent struct { - makeResultFunc MakeResultEventFunc - event *output.InternalWrappedEvent +// RequestData contains data for a request event +type RequestData struct { + MakeResultFunc MakeResultEventFunc + Event *output.InternalWrappedEvent + Operators *operators.Operators + MatchFunc operators.MatchFunc + ExtractFunc operators.ExtractFunc } // RequestEvent is the event for a network request sent by nuclei. -func (c *Client) RequestEvent(interactshURL string, event *output.InternalWrappedEvent, makeResult MakeResultEventFunc) { +func (c *Client) RequestEvent(interactshURL string, data *RequestData) { id := strings.TrimSuffix(interactshURL, c.dotHostname) - c.requests.Set(id, &internalRequestEvent{makeResultFunc: makeResult, event: event}, c.eviction) + c.requests.Set(id, data, c.eviction) +} + +// HasMatchers returns true if an operator has interactsh part +// matchers or extractors. +// +// Used by requests to show result or not depending on presence of interact.sh +// data part matchers. +func HasMatchers(operators *operators.Operators) bool { + for _, matcher := range operators.Matchers { + if strings.HasPrefix(matcher.Part, "interactsh-") { + return true + } + } + for _, matcher := range operators.Extractors { + if strings.HasPrefix(matcher.Part, "interactsh-") { + return true + } + } + return false } diff --git a/v2/pkg/protocols/http/request.go b/v2/pkg/protocols/http/request.go index 0e9f5fb80..be2d294f9 100644 --- a/v2/pkg/protocols/http/request.go +++ b/v2/pkg/protocols/http/request.go @@ -17,6 +17,7 @@ import ( "github.com/projectdiscovery/nuclei/v2/pkg/output" "github.com/projectdiscovery/nuclei/v2/pkg/protocols" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators" + "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/interactsh" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/tostring" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/httpclientpool" "github.com/projectdiscovery/rawhttp" @@ -219,8 +220,16 @@ 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) + if interactsh.HasMatchers(r.CompiledOperators) { + if r.options.Interactsh != nil { + r.options.Interactsh.RequestEvent(interactURL, &interactsh.RequestData{ + MakeResultFunc: r.MakeResultEvent, + Event: event, + Operators: r.CompiledOperators, + MatchFunc: r.Match, + ExtractFunc: r.Extract, + }) + } } callback(event) }, requestCount) @@ -398,14 +407,16 @@ func (r *Request) executeRequest(reqURL string, request *generatedRequest, previ } event := &output.InternalWrappedEvent{InternalEvent: outputEvent} - if r.CompiledOperators != nil { - var ok bool - event.OperatorsResult, ok = r.CompiledOperators.Execute(finalEvent, r.Match, r.Extract) - if ok && event.OperatorsResult != nil { - event.OperatorsResult.PayloadValues = request.meta - event.Results = r.MakeResultEvent(event) + if !interactsh.HasMatchers(r.CompiledOperators) { + if r.CompiledOperators != nil { + var ok bool + event.OperatorsResult, ok = r.CompiledOperators.Execute(finalEvent, r.Match, r.Extract) + if ok && event.OperatorsResult != nil { + event.OperatorsResult.PayloadValues = request.meta + event.Results = r.MakeResultEvent(event) + } + event.InternalEvent = outputEvent } - event.InternalEvent = outputEvent } callback(event) return nil diff --git a/v2/pkg/protocols/network/request.go b/v2/pkg/protocols/network/request.go index bcedcf645..dd12cdbc7 100644 --- a/v2/pkg/protocols/network/request.go +++ b/v2/pkg/protocols/network/request.go @@ -13,6 +13,7 @@ import ( "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/nuclei/v2/pkg/output" "github.com/projectdiscovery/nuclei/v2/pkg/protocols" + "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/interactsh" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/replacer" ) @@ -77,6 +78,11 @@ func (r *Request) executeAddress(actualAddress, address, input string, shouldUse defer conn.Close() _ = conn.SetReadDeadline(time.Now().Add(time.Duration(r.options.Options.Timeout) * time.Second)) + var interactURL string + if r.options.Interactsh != nil { + interactURL = r.options.Interactsh.URL() + } + responseBuilder := &strings.Builder{} reqBuilder := &strings.Builder{} @@ -88,6 +94,9 @@ func (r *Request) executeAddress(actualAddress, address, input string, shouldUse case "hex": data, err = hex.DecodeString(input.Data) default: + if r.options.Interactsh != nil { + input.Data = r.options.Interactsh.ReplaceMarkers(input.Data, interactURL) + } data = []byte(input.Data) } if err != nil { @@ -150,11 +159,23 @@ func (r *Request) executeAddress(actualAddress, address, input string, shouldUse } event := &output.InternalWrappedEvent{InternalEvent: outputEvent} - if r.CompiledOperators != nil { - result, ok := r.CompiledOperators.Execute(outputEvent, r.Match, r.Extract) - if ok && result != nil { - event.OperatorsResult = result - event.Results = r.MakeResultEvent(event) + if !interactsh.HasMatchers(r.CompiledOperators) { + if r.CompiledOperators != nil { + result, ok := r.CompiledOperators.Execute(outputEvent, r.Match, r.Extract) + if ok && result != nil { + event.OperatorsResult = result + event.Results = r.MakeResultEvent(event) + } + } + } else { + if r.options.Interactsh != nil { + r.options.Interactsh.RequestEvent(interactURL, &interactsh.RequestData{ + MakeResultFunc: r.MakeResultEvent, + Event: event, + Operators: r.CompiledOperators, + MatchFunc: r.Match, + ExtractFunc: r.Extract, + }) } } callback(event) From e8747fc2da7be02dd05197831d3b4c157dfbb81e Mon Sep 17 00:00:00 2001 From: Ice3man543 Date: Sun, 18 Apr 2021 17:27:45 +0530 Subject: [PATCH 03/11] Made interactsh default, fixed matcher panic --- v2/cmd/nuclei/main.go | 2 +- v2/pkg/protocols/common/interactsh/interactsh.go | 4 ++++ v2/pkg/types/types.go | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/v2/cmd/nuclei/main.go b/v2/cmd/nuclei/main.go index 019c78890..574da4fce 100644 --- a/v2/cmd/nuclei/main.go +++ b/v2/cmd/nuclei/main.go @@ -85,7 +85,7 @@ 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.BoolVar(&options.NoInteractsh, "no-interactsh", false, "Do not 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") diff --git a/v2/pkg/protocols/common/interactsh/interactsh.go b/v2/pkg/protocols/common/interactsh/interactsh.go index 6c11010c5..5f2acc782 100644 --- a/v2/pkg/protocols/common/interactsh/interactsh.go +++ b/v2/pkg/protocols/common/interactsh/interactsh.go @@ -170,6 +170,10 @@ func (c *Client) RequestEvent(interactshURL string, data *RequestData) { // Used by requests to show result or not depending on presence of interact.sh // data part matchers. func HasMatchers(operators *operators.Operators) bool { + if operators == nil { + return false + } + for _, matcher := range operators.Matchers { if strings.HasPrefix(matcher.Part, "interactsh-") { return true diff --git a/v2/pkg/types/types.go b/v2/pkg/types/types.go index d5bd5f22b..d9b407009 100644 --- a/v2/pkg/types/types.go +++ b/v2/pkg/types/types.go @@ -123,6 +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 + // NoInteractsh disables use of interactsh server for interaction polling + NoInteractsh bool } From 993416d77cfc77fbc1893cdc91c79dfcf22c7190 Mon Sep 17 00:00:00 2001 From: Ice3man543 Date: Sun, 18 Apr 2021 17:29:01 +0530 Subject: [PATCH 04/11] Misc --- v2/internal/runner/runner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2/internal/runner/runner.go b/v2/internal/runner/runner.go index 839acc6f8..7b7590a89 100644 --- a/v2/internal/runner/runner.go +++ b/v2/internal/runner/runner.go @@ -199,7 +199,7 @@ func New(options *types.Options) (*Runner, error) { } } - if options.Interactsh { + if !options.NoInteractsh { interactshClient, err := interactsh.New(&interactsh.Options{ ServerURL: options.InteractshURL, CacheSize: int64(options.InteractionsCacheSize), From 959f8935e7fd6d8622522a313ec4431cc0547848 Mon Sep 17 00:00:00 2001 From: Ice3man543 Date: Sun, 18 Apr 2021 17:44:21 +0530 Subject: [PATCH 05/11] Changed - to _ --- v2/pkg/protocols/common/interactsh/interactsh.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/v2/pkg/protocols/common/interactsh/interactsh.go b/v2/pkg/protocols/common/interactsh/interactsh.go index 5f2acc782..49af884b1 100644 --- a/v2/pkg/protocols/common/interactsh/interactsh.go +++ b/v2/pkg/protocols/common/interactsh/interactsh.go @@ -89,9 +89,9 @@ func New(options *Options) (*Client, error) { return } - data.Event.InternalEvent["interactsh-protocol"] = interaction.Protocol - data.Event.InternalEvent["interactsh-request"] = interaction.RawRequest - data.Event.InternalEvent["interactsh-response"] = interaction.RawResponse + data.Event.InternalEvent["interactsh_protocol"] = interaction.Protocol + data.Event.InternalEvent["interactsh_request"] = interaction.RawRequest + data.Event.InternalEvent["interactsh_response"] = interaction.RawResponse result, matched := data.Operators.Execute(data.Event.InternalEvent, data.MatchFunc, data.ExtractFunc) if !matched || result == nil { return // if we don't match, return From e6825d5960984e5545477279978a77bd807d2f38 Mon Sep 17 00:00:00 2001 From: Ice3man543 Date: Sun, 18 Apr 2021 17:53:59 +0530 Subject: [PATCH 06/11] Better marker identification + Misc --- .../protocols/common/interactsh/interactsh.go | 9 ++++++-- v2/pkg/protocols/http/build_request.go | 8 +++---- v2/pkg/protocols/http/request.go | 23 +++++++++---------- v2/pkg/protocols/network/request.go | 7 +++--- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/v2/pkg/protocols/common/interactsh/interactsh.go b/v2/pkg/protocols/common/interactsh/interactsh.go index 49af884b1..41c3ef550 100644 --- a/v2/pkg/protocols/common/interactsh/interactsh.go +++ b/v2/pkg/protocols/common/interactsh/interactsh.go @@ -175,12 +175,17 @@ func HasMatchers(operators *operators.Operators) bool { } for _, matcher := range operators.Matchers { - if strings.HasPrefix(matcher.Part, "interactsh-") { + for _, dsl := range matcher.DSL { + if strings.HasPrefix(dsl, "interactsh") { + return true + } + } + if strings.HasPrefix(matcher.Part, "interactsh") { return true } } for _, matcher := range operators.Extractors { - if strings.HasPrefix(matcher.Part, "interactsh-") { + if strings.HasPrefix(matcher.Part, "interactsh") { return true } } diff --git a/v2/pkg/protocols/http/build_request.go b/v2/pkg/protocols/http/build_request.go index ed5e27960..c040e6dda 100644 --- a/v2/pkg/protocols/http/build_request.go +++ b/v2/pkg/protocols/http/build_request.go @@ -61,7 +61,7 @@ func (r *requestGenerator) Make(baseURL string, dynamicValues map[string]interfa } parsedString := parsed.String() - if r.options.Interactsh != nil { + if interactURL != "" { parsedString = r.options.Interactsh.ReplaceMarkers(parsedString, interactURL) } values["BaseURL"] = parsedString @@ -118,7 +118,7 @@ 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{}, interactURL string) (*generatedRequest, error) { - if r.options.Interactsh != nil { + if interactURL != "" { data = r.options.Interactsh.ReplaceMarkers(data, interactURL) } return r.handleRawWithPayloads(ctx, data, baseURL, values, payloads) @@ -178,7 +178,7 @@ func (r *requestGenerator) handleRawWithPayloads(ctx context.Context, rawRequest 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 { + if interactURL != "" { value = r.options.Interactsh.ReplaceMarkers(value, interactURL) } req.Header[header] = []string{replacer.Replace(value, values)} @@ -192,7 +192,7 @@ func (r *requestGenerator) fillRequest(req *http.Request, values map[string]inte // Check if the user requested a request body if r.request.Body != "" { body := r.request.Body - if interactURL != "" && r.options.Interactsh != nil { + if interactURL != "" { body = r.options.Interactsh.ReplaceMarkers(body, interactURL) } req.Body = ioutil.NopCloser(strings.NewReader(body)) diff --git a/v2/pkg/protocols/http/request.go b/v2/pkg/protocols/http/request.go index be2d294f9..f46a72944 100644 --- a/v2/pkg/protocols/http/request.go +++ b/v2/pkg/protocols/http/request.go @@ -198,9 +198,10 @@ func (r *Request) ExecuteWithResults(reqURL string, dynamicValues, previous outp requestCount := 1 var requestErr error for { - var interactURL string + hasInteractMarkers := interactsh.HasMatchers(r.CompiledOperators) - if r.options.Interactsh != nil { + var interactURL string + if r.options.Interactsh != nil && hasInteractMarkers { interactURL = r.options.Interactsh.URL() } request, err := generator.Make(reqURL, dynamicValues, interactURL) @@ -220,16 +221,14 @@ func (r *Request) ExecuteWithResults(reqURL string, dynamicValues, previous outp gotOutput = true dynamicValues = generators.MergeMaps(dynamicValues, event.OperatorsResult.DynamicValues) } - if interactsh.HasMatchers(r.CompiledOperators) { - if r.options.Interactsh != nil { - r.options.Interactsh.RequestEvent(interactURL, &interactsh.RequestData{ - MakeResultFunc: r.MakeResultEvent, - Event: event, - Operators: r.CompiledOperators, - MatchFunc: r.Match, - ExtractFunc: r.Extract, - }) - } + if hasInteractMarkers && r.options.Interactsh != nil { + r.options.Interactsh.RequestEvent(interactURL, &interactsh.RequestData{ + MakeResultFunc: r.MakeResultEvent, + Event: event, + Operators: r.CompiledOperators, + MatchFunc: r.Match, + ExtractFunc: r.Extract, + }) } callback(event) }, requestCount) diff --git a/v2/pkg/protocols/network/request.go b/v2/pkg/protocols/network/request.go index dd12cdbc7..7db9fca96 100644 --- a/v2/pkg/protocols/network/request.go +++ b/v2/pkg/protocols/network/request.go @@ -78,8 +78,9 @@ func (r *Request) executeAddress(actualAddress, address, input string, shouldUse defer conn.Close() _ = conn.SetReadDeadline(time.Now().Add(time.Duration(r.options.Options.Timeout) * time.Second)) + hasInteractMarkers := interactsh.HasMatchers(r.CompiledOperators) var interactURL string - if r.options.Interactsh != nil { + if r.options.Interactsh != nil && hasInteractMarkers { interactURL = r.options.Interactsh.URL() } @@ -94,7 +95,7 @@ func (r *Request) executeAddress(actualAddress, address, input string, shouldUse case "hex": data, err = hex.DecodeString(input.Data) default: - if r.options.Interactsh != nil { + if interactURL != "" { input.Data = r.options.Interactsh.ReplaceMarkers(input.Data, interactURL) } data = []byte(input.Data) @@ -159,7 +160,7 @@ func (r *Request) executeAddress(actualAddress, address, input string, shouldUse } event := &output.InternalWrappedEvent{InternalEvent: outputEvent} - if !interactsh.HasMatchers(r.CompiledOperators) { + if !hasInteractMarkers { if r.CompiledOperators != nil { result, ok := r.CompiledOperators.Execute(outputEvent, r.Match, r.Extract) if ok && result != nil { From d9145b1c8a508fbb0679cbf3cd97ef4669da8106 Mon Sep 17 00:00:00 2001 From: Ice3man543 Date: Mon, 19 Apr 2021 13:13:08 +0530 Subject: [PATCH 07/11] Fixed DSL interactsh matchers not working --- v2/pkg/protocols/common/interactsh/interactsh.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2/pkg/protocols/common/interactsh/interactsh.go b/v2/pkg/protocols/common/interactsh/interactsh.go index 41c3ef550..e418e115e 100644 --- a/v2/pkg/protocols/common/interactsh/interactsh.go +++ b/v2/pkg/protocols/common/interactsh/interactsh.go @@ -176,7 +176,7 @@ func HasMatchers(operators *operators.Operators) bool { for _, matcher := range operators.Matchers { for _, dsl := range matcher.DSL { - if strings.HasPrefix(dsl, "interactsh") { + if strings.Contains(dsl, "interactsh") { return true } } From d3641bfe12113f4ecf889469291d35dfa70f98cd Mon Sep 17 00:00:00 2001 From: sandeep <8293321+ehsandeep@users.noreply.github.com> Date: Sat, 1 May 2021 12:02:28 +0530 Subject: [PATCH 08/11] mod update --- v2/go.mod | 2 +- v2/go.sum | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/v2/go.mod b/v2/go.mod index 490eb9b02..09be6ace0 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -30,7 +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/interactsh v0.0.2 github.com/projectdiscovery/rawhttp v0.0.6 github.com/projectdiscovery/retryabledns v1.0.10 github.com/projectdiscovery/retryablehttp-go v1.0.1 diff --git a/v2/go.sum b/v2/go.sum index 383067ce1..1fd674cf6 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -61,6 +61,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/eggsampler/acme/v3 v3.2.1 h1:Lfsrg3M2zt00QRnizOFzdpSfsS9oDvPsGrodXS/w1KI= +github.com/eggsampler/acme/v3 v3.2.1/go.mod h1:/qh0rKC/Dh7Jj+p4So7DbWmFNzC4dpcpK53r226Fhuo= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -68,12 +70,12 @@ 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= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-rod/rod v0.91.1 h1:7xIlC/bXCXosZqZUl2x6GVB8tv4yMQ4W/ZVdGVa1qYI= github.com/go-rod/rod v0.91.1/go.mod h1:/W4lcZiCALPD603MnJGIvhtywP3R6yRB9EDfFfsHiiI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -138,7 +140,6 @@ 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= @@ -152,6 +153,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jasonlvhit/gocron v0.0.1 h1:qTt5qF3b3srDjeOIR4Le1LfeyvoYzJlYpqvG7tJX5YU= +github.com/jasonlvhit/gocron v0.0.1/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -197,10 +200,12 @@ github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -219,8 +224,8 @@ github.com/projectdiscovery/gologger v1.1.4 h1:qWxGUq7ukHWT849uGPkagPKF3yBPYAsTt 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/interactsh v0.0.2 h1:v2gsHQbuMKu0OxK+PEduKR7lRQFsdNSZjxmI7iRa46g= +github.com/projectdiscovery/interactsh v0.0.2/go.mod h1:dWnKO14d2FLP3kLhI9DecEsiAC/aZiJoUBGFjGhDskY= 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= From 563c7ab0454cb3a0a34f25c0f94cabe315a4dc24 Mon Sep 17 00:00:00 2001 From: Ice3man543 Date: Sat, 1 May 2021 18:28:24 +0530 Subject: [PATCH 09/11] Fixed lint errors --- v2/go.mod | 3 ++- v2/go.sum | 22 ++++++++++++++----- v2/pkg/operators/operators.go | 4 +--- .../protocols/common/interactsh/interactsh.go | 8 +++---- v2/pkg/templates/templates.go | 16 +++++++------- 5 files changed, 31 insertions(+), 22 deletions(-) diff --git a/v2/go.mod b/v2/go.mod index 490eb9b02..e472f3c06 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -4,6 +4,7 @@ go 1.15 require ( github.com/Knetic/govaluate v3.0.0+incompatible + github.com/alecthomas/jsonschema v0.0.0-20210413112511-5c9c23bdc720 github.com/andygrunwald/go-jira v1.13.0 github.com/blang/semver v3.5.1+incompatible github.com/corpix/uarand v0.1.1 @@ -30,7 +31,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/interactsh v0.0.2 github.com/projectdiscovery/rawhttp v0.0.6 github.com/projectdiscovery/retryabledns v1.0.10 github.com/projectdiscovery/retryablehttp-go v1.0.1 diff --git a/v2/go.sum b/v2/go.sum index 383067ce1..1dd1bc71f 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -38,6 +38,8 @@ github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8L github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= +github.com/alecthomas/jsonschema v0.0.0-20210413112511-5c9c23bdc720 h1:eGgkuR6dLpW0rvJCOH6illGPbxyndL2J3f7wDI2qCsE= +github.com/alecthomas/jsonschema v0.0.0-20210413112511-5c9c23bdc720/go.mod h1:/n6+1/DWPltRLWL/VKyUxg6tzsl5kHUCcraimt4vr60= github.com/andygrunwald/go-jira v1.13.0 h1:vvIImGgX32bHfoiyUwkNo+/YrPnRczNarvhLOncP6dE= github.com/andygrunwald/go-jira v1.13.0/go.mod h1:jYi4kFDbRPZTJdJOVJO4mpMMIwdB+rcZwSO58DzPd2I= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= @@ -61,6 +63,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/eggsampler/acme/v3 v3.2.1 h1:Lfsrg3M2zt00QRnizOFzdpSfsS9oDvPsGrodXS/w1KI= +github.com/eggsampler/acme/v3 v3.2.1/go.mod h1:/qh0rKC/Dh7Jj+p4So7DbWmFNzC4dpcpK53r226Fhuo= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -68,12 +72,12 @@ 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= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-rod/rod v0.91.1 h1:7xIlC/bXCXosZqZUl2x6GVB8tv4yMQ4W/ZVdGVa1qYI= github.com/go-rod/rod v0.91.1/go.mod h1:/W4lcZiCALPD603MnJGIvhtywP3R6yRB9EDfFfsHiiI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -138,7 +142,6 @@ 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= @@ -151,7 +154,11 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk= +github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jasonlvhit/gocron v0.0.1 h1:qTt5qF3b3srDjeOIR4Le1LfeyvoYzJlYpqvG7tJX5YU= +github.com/jasonlvhit/gocron v0.0.1/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -197,10 +204,12 @@ github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -219,8 +228,8 @@ github.com/projectdiscovery/gologger v1.1.4 h1:qWxGUq7ukHWT849uGPkagPKF3yBPYAsTt 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/interactsh v0.0.2 h1:v2gsHQbuMKu0OxK+PEduKR7lRQFsdNSZjxmI7iRa46g= +github.com/projectdiscovery/interactsh v0.0.2/go.mod h1:dWnKO14d2FLP3kLhI9DecEsiAC/aZiJoUBGFjGhDskY= 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= @@ -248,6 +257,7 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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.3.1-0.20190311161405-34c6fa2dc709/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= diff --git a/v2/pkg/operators/operators.go b/v2/pkg/operators/operators.go index 228255d6e..87886e64d 100644 --- a/v2/pkg/operators/operators.go +++ b/v2/pkg/operators/operators.go @@ -80,9 +80,7 @@ func (r *Result) Merge(result *Result) { for k, v := range result.Extracts { r.Extracts[k] = v } - for _, v := range result.OutputExtracts { - r.OutputExtracts = append(r.OutputExtracts, v) - } + r.OutputExtracts = append(r.OutputExtracts, result.OutputExtracts...) for k, v := range result.DynamicValues { r.DynamicValues[k] = v } diff --git a/v2/pkg/protocols/common/interactsh/interactsh.go b/v2/pkg/protocols/common/interactsh/interactsh.go index e418e115e..6bb399d70 100644 --- a/v2/pkg/protocols/common/interactsh/interactsh.go +++ b/v2/pkg/protocols/common/interactsh/interactsh.go @@ -169,12 +169,12 @@ func (c *Client) RequestEvent(interactshURL string, data *RequestData) { // // Used by requests to show result or not depending on presence of interact.sh // data part matchers. -func HasMatchers(operators *operators.Operators) bool { - if operators == nil { +func HasMatchers(op *operators.Operators) bool { + if op == nil { return false } - for _, matcher := range operators.Matchers { + for _, matcher := range op.Matchers { for _, dsl := range matcher.DSL { if strings.Contains(dsl, "interactsh") { return true @@ -184,7 +184,7 @@ func HasMatchers(operators *operators.Operators) bool { return true } } - for _, matcher := range operators.Extractors { + for _, matcher := range op.Extractors { if strings.HasPrefix(matcher.Part, "interactsh") { return true } diff --git a/v2/pkg/templates/templates.go b/v2/pkg/templates/templates.go index f2e841502..610373025 100644 --- a/v2/pkg/templates/templates.go +++ b/v2/pkg/templates/templates.go @@ -17,22 +17,22 @@ type Template struct { // Info contains information about the template Info map[string]interface{} `yaml:"info"` // RequestsHTTP contains the http request to make in the template - RequestsHTTP []*http.Request `yaml:"requests,omitempty"` + RequestsHTTP []*http.Request `yaml:"requests,omitempty" json:"requests"` // RequestsDNS contains the dns request to make in the template - RequestsDNS []*dns.Request `yaml:"dns,omitempty"` + RequestsDNS []*dns.Request `yaml:"dns,omitempty" json:"dns"` // RequestsFile contains the file request to make in the template - RequestsFile []*file.Request `yaml:"file,omitempty"` + RequestsFile []*file.Request `yaml:"file,omitempty" json:"file"` // RequestsNetwork contains the network request to make in the template - RequestsNetwork []*network.Request `yaml:"network,omitempty"` + RequestsNetwork []*network.Request `yaml:"network,omitempty" json:"network"` // RequestsHeadless contains the headless request to make in the template. - RequestsHeadless []*headless.Request `yaml:"headless,omitempty"` + RequestsHeadless []*headless.Request `yaml:"headless,omitempty" json:"headless"` // Workflows is a yaml based workflow declaration code. workflows.Workflow `yaml:",inline,omitempty"` - CompiledWorkflow *workflows.Workflow `yaml:"-"` + CompiledWorkflow *workflows.Workflow `yaml:"-" json:"-" jsonschema:"-"` // TotalRequests is the total number of requests for the template. - TotalRequests int `yaml:"-"` + TotalRequests int `yaml:"-" json:"-"` // Executer is the actual template executor for running template requests - Executer protocols.Executer `yaml:"-"` + Executer protocols.Executer `yaml:"-" json:"-"` } From 6a4f3e133645682f8a4c3de06c2eaaf58ad705fc Mon Sep 17 00:00:00 2001 From: Ice3man543 Date: Mon, 3 May 2021 14:08:09 +0530 Subject: [PATCH 10/11] Reporting added to OOB interaction results --- v2/internal/runner/runner.go | 1 + .../protocols/common/interactsh/interactsh.go | 10 ++++++++ v2/pkg/reporting/format/format.go | 25 +++++++++++++++++++ v2/pkg/reporting/trackers/jira/jira.go | 24 ++++++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/v2/internal/runner/runner.go b/v2/internal/runner/runner.go index d0e6f60aa..5685f9be0 100644 --- a/v2/internal/runner/runner.go +++ b/v2/internal/runner/runner.go @@ -208,6 +208,7 @@ func New(options *types.Options) (*Runner, error) { ColldownPeriod: time.Duration(options.InteractionsColldownPeriod) * time.Second, PollDuration: time.Duration(options.InteractionsPollDuration) * time.Second, Output: runner.output, + IssuesClient: runner.issuesClient, Progress: runner.progress, }) if err != nil { diff --git a/v2/pkg/protocols/common/interactsh/interactsh.go b/v2/pkg/protocols/common/interactsh/interactsh.go index 6bb399d70..b6730b1e7 100644 --- a/v2/pkg/protocols/common/interactsh/interactsh.go +++ b/v2/pkg/protocols/common/interactsh/interactsh.go @@ -7,11 +7,13 @@ import ( "github.com/karlseguin/ccache" "github.com/pkg/errors" + "github.com/projectdiscovery/gologger" "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/projectdiscovery/nuclei/v2/pkg/reporting" "github.com/valyala/fasttemplate" ) @@ -48,6 +50,8 @@ type Options struct { PollDuration time.Duration // Output is the output writer for nuclei Output output.Writer + // IssuesClient is a client for issue exporting + IssuesClient *reporting.Client // Progress is the nuclei progress bar implementation. Progress progress.Progress } @@ -111,6 +115,12 @@ func New(options *Options) (*Client, error) { interactClient.matched = true } options.Progress.IncrementMatched() + + if options.IssuesClient != nil { + if err := options.IssuesClient.CreateIssue(result); err != nil { + gologger.Warning().Msgf("Could not create issue on tracker: %s", err) + } + } } }) return interactClient, nil diff --git a/v2/pkg/reporting/format/format.go b/v2/pkg/reporting/format/format.go index 4654baefa..153b6c24c 100644 --- a/v2/pkg/reporting/format/format.go +++ b/v2/pkg/reporting/format/format.go @@ -86,6 +86,31 @@ func MarkdownDescription(event *output.ResultEvent) string { builder.WriteString("\n") } } + if event.Interaction != nil { + builder.WriteString("**Interaction Data**\n---\n") + builder.WriteString(event.Interaction.Protocol) + if event.Interaction.QType != "" { + builder.WriteString(" (") + builder.WriteString(event.Interaction.QType) + builder.WriteString(")") + } + builder.WriteString(" Interaction from ") + builder.WriteString(event.Interaction.RemoteAddress) + builder.WriteString(" at ") + builder.WriteString(event.Interaction.UniqueID) + + if event.Interaction.RawRequest != "" { + builder.WriteString("\n\n**Interaction Request**\n\n```\n") + builder.WriteString(event.Interaction.RawRequest) + builder.WriteString("\n```\n") + } + if event.Interaction.RawResponse != "" { + builder.WriteString("\n**Interaction Response**\n\n```\n") + builder.WriteString(event.Interaction.RawResponse) + builder.WriteString("\n```\n") + } + } + builder.WriteString("\n---\nGenerated by [Nuclei](https://github.com/projectdiscovery/nuclei)") data := builder.String() return data diff --git a/v2/pkg/reporting/trackers/jira/jira.go b/v2/pkg/reporting/trackers/jira/jira.go index 7053a2c55..0c68b4ce3 100644 --- a/v2/pkg/reporting/trackers/jira/jira.go +++ b/v2/pkg/reporting/trackers/jira/jira.go @@ -129,6 +129,30 @@ func jiraFormatDescription(event *output.ResultEvent) string { builder.WriteString("\n") } } + if event.Interaction != nil { + builder.WriteString("*Interaction Data*\n---\n") + builder.WriteString(event.Interaction.Protocol) + if event.Interaction.QType != "" { + builder.WriteString(" (") + builder.WriteString(event.Interaction.QType) + builder.WriteString(")") + } + builder.WriteString(" Interaction from ") + builder.WriteString(event.Interaction.RemoteAddress) + builder.WriteString(" at ") + builder.WriteString(event.Interaction.UniqueID) + + if event.Interaction.RawRequest != "" { + builder.WriteString("\n\n*Interaction Request*\n\n{code}\n") + builder.WriteString(event.Interaction.RawRequest) + builder.WriteString("\n{code}\n") + } + if event.Interaction.RawResponse != "" { + builder.WriteString("\n*Interaction Response*\n\n{code}\n") + builder.WriteString(event.Interaction.RawResponse) + builder.WriteString("\n{code}\n") + } + } builder.WriteString("\n---\nGenerated by [Nuclei|https://github.com/projectdiscovery/nuclei]") data := builder.String() return data From 8394e696ca34cba12a10f2199c4a48922094f0e6 Mon Sep 17 00:00:00 2001 From: Ice3man543 Date: Mon, 3 May 2021 14:31:44 +0530 Subject: [PATCH 11/11] Support interactsh payloads in baseURL --- v2/pkg/protocols/http/build_request.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/v2/pkg/protocols/http/build_request.go b/v2/pkg/protocols/http/build_request.go index c040e6dda..8b0823789 100644 --- a/v2/pkg/protocols/http/build_request.go +++ b/v2/pkg/protocols/http/build_request.go @@ -60,10 +60,6 @@ func (r *requestGenerator) Make(baseURL string, dynamicValues map[string]interfa parsed.Path = strings.TrimSuffix(parsed.Path, "/") } parsedString := parsed.String() - - if interactURL != "" { - parsedString = r.options.Interactsh.ReplaceMarkers(parsedString, interactURL) - } values["BaseURL"] = parsedString // If data contains \n it's a raw request, process it like raw. Else @@ -102,6 +98,9 @@ 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{}, interactURL string) (*generatedRequest, error) { final := replacer.Replace(data, values) + if interactURL != "" { + final = r.options.Interactsh.ReplaceMarkers(final, interactURL) + } // Build a request on the specified URL req, err := http.NewRequestWithContext(ctx, r.request.Method, final, nil)