mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-22 19:15:26 +00:00
Fixed interactsh edge case + debug mode logging for interact
This commit is contained in:
parent
bd722c2474
commit
e7a0417bc2
@ -248,6 +248,7 @@ func New(options *types.Options) (*Runner, error) {
|
|||||||
Output: runner.output,
|
Output: runner.output,
|
||||||
IssuesClient: runner.issuesClient,
|
IssuesClient: runner.issuesClient,
|
||||||
Progress: runner.progress,
|
Progress: runner.progress,
|
||||||
|
Debug: runner.options.Debug,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gologger.Error().Msgf("Could not create interactsh client: %s", err)
|
gologger.Error().Msgf("Could not create interactsh client: %s", err)
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
package interactsh
|
package interactsh
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -62,6 +65,8 @@ type Options struct {
|
|||||||
IssuesClient *reporting.Client
|
IssuesClient *reporting.Client
|
||||||
// Progress is the nuclei progress bar implementation.
|
// Progress is the nuclei progress bar implementation.
|
||||||
Progress progress.Progress
|
Progress progress.Progress
|
||||||
|
// Debug specifies whether debugging output should be shown for interactsh-client
|
||||||
|
Debug bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultMaxInteractionsCount = 5000
|
const defaultMaxInteractionsCount = 5000
|
||||||
@ -100,6 +105,9 @@ func New(options *Options) (*Client, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interactClient.interactsh.StartPolling(interactClient.pollDuration, func(interaction *server.Interaction) {
|
interactClient.interactsh.StartPolling(interactClient.pollDuration, func(interaction *server.Interaction) {
|
||||||
|
if options.Debug {
|
||||||
|
debugPrintInteraction(interaction)
|
||||||
|
}
|
||||||
item := interactClient.requests.Get(interaction.UniqueID)
|
item := interactClient.requests.Get(interaction.UniqueID)
|
||||||
if item == nil {
|
if item == nil {
|
||||||
// If we don't have any request for this ID, add it to temporary
|
// If we don't have any request for this ID, add it to temporary
|
||||||
@ -252,3 +260,20 @@ func HasMatchers(op *operators.Operators) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func debugPrintInteraction(interaction *server.Interaction) {
|
||||||
|
builder := &bytes.Buffer{}
|
||||||
|
|
||||||
|
switch interaction.Protocol {
|
||||||
|
case "dns":
|
||||||
|
builder.WriteString(fmt.Sprintf("[%s] Received DNS interaction (%s) from %s at %s", interaction.FullId, interaction.QType, interaction.RemoteAddress, interaction.Timestamp.Format("2006-01-02 15:04:05")))
|
||||||
|
builder.WriteString(fmt.Sprintf("\n-----------\nDNS Request\n-----------\n\n%s\n\n------------\nDNS Response\n------------\n\n%s\n\n", interaction.RawRequest, interaction.RawResponse))
|
||||||
|
case "http":
|
||||||
|
builder.WriteString(fmt.Sprintf("[%s] Received HTTP interaction from %s at %s", interaction.FullId, interaction.RemoteAddress, interaction.Timestamp.Format("2006-01-02 15:04:05")))
|
||||||
|
builder.WriteString(fmt.Sprintf("\n------------\nHTTP Request\n------------\n\n%s\n\n-------------\nHTTP Response\n-------------\n\n%s\n\n", interaction.RawRequest, interaction.RawResponse))
|
||||||
|
case "smtp":
|
||||||
|
builder.WriteString(fmt.Sprintf("[%s] Received SMTP interaction from %s at %s", interaction.FullId, interaction.RemoteAddress, interaction.Timestamp.Format("2006-01-02 15:04:05")))
|
||||||
|
builder.WriteString(fmt.Sprintf("\n------------\nSMTP Interaction\n------------\n\n%s\n\n", interaction.RawRequest))
|
||||||
|
}
|
||||||
|
fmt.Fprint(os.Stderr, builder.String())
|
||||||
|
}
|
||||||
|
|||||||
@ -67,7 +67,7 @@ func (r *Request) executeRaceRequest(reqURL string, previous output.InternalEven
|
|||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(httpRequest *generatedRequest) {
|
go func(httpRequest *generatedRequest) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
err := r.executeRequest(reqURL, httpRequest, previous, callback, 0)
|
err := r.executeRequest(reqURL, httpRequest, previous, false, callback, 0)
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
requestErr = multierr.Append(requestErr, err)
|
requestErr = multierr.Append(requestErr, err)
|
||||||
@ -107,7 +107,7 @@ func (r *Request) executeParallelHTTP(reqURL string, dynamicValues output.Intern
|
|||||||
r.options.RateLimiter.Take()
|
r.options.RateLimiter.Take()
|
||||||
|
|
||||||
previous := make(map[string]interface{})
|
previous := make(map[string]interface{})
|
||||||
err := r.executeRequest(reqURL, httpRequest, previous, callback, 0)
|
err := r.executeRequest(reqURL, httpRequest, previous, false, callback, 0)
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
requestErr = multierr.Append(requestErr, err)
|
requestErr = multierr.Append(requestErr, err)
|
||||||
@ -166,7 +166,7 @@ func (r *Request) executeTurboHTTP(reqURL string, dynamicValues, previous output
|
|||||||
go func(httpRequest *generatedRequest) {
|
go func(httpRequest *generatedRequest) {
|
||||||
defer swg.Done()
|
defer swg.Done()
|
||||||
|
|
||||||
err := r.executeRequest(reqURL, httpRequest, previous, callback, 0)
|
err := r.executeRequest(reqURL, httpRequest, previous, false, callback, 0)
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
requestErr = multierr.Append(requestErr, err)
|
requestErr = multierr.Append(requestErr, err)
|
||||||
@ -222,7 +222,7 @@ func (r *Request) ExecuteWithResults(reqURL string, dynamicValues, previous outp
|
|||||||
}
|
}
|
||||||
var gotOutput bool
|
var gotOutput bool
|
||||||
r.options.RateLimiter.Take()
|
r.options.RateLimiter.Take()
|
||||||
err = r.executeRequest(reqURL, request, previous, func(event *output.InternalWrappedEvent) {
|
err = r.executeRequest(reqURL, request, previous, hasInteractMarkers, func(event *output.InternalWrappedEvent) {
|
||||||
// Add the extracts to the dynamic values if any.
|
// Add the extracts to the dynamic values if any.
|
||||||
if event.OperatorsResult != nil {
|
if event.OperatorsResult != nil {
|
||||||
gotOutput = true
|
gotOutput = true
|
||||||
@ -260,7 +260,7 @@ func (r *Request) ExecuteWithResults(reqURL string, dynamicValues, previous outp
|
|||||||
const drainReqSize = int64(8 * 1024)
|
const drainReqSize = int64(8 * 1024)
|
||||||
|
|
||||||
// executeRequest executes the actual generated request and returns error if occurred
|
// executeRequest executes the actual generated request and returns error if occurred
|
||||||
func (r *Request) executeRequest(reqURL string, request *generatedRequest, previous output.InternalEvent, callback protocols.OutputEventCallback, requestCount int) error {
|
func (r *Request) executeRequest(reqURL string, request *generatedRequest, previous output.InternalEvent, hasInteractMarkers bool, callback protocols.OutputEventCallback, requestCount int) error {
|
||||||
r.setCustomHeaders(request)
|
r.setCustomHeaders(request)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -330,6 +330,22 @@ func (r *Request) executeRequest(reqURL string, request *generatedRequest, previ
|
|||||||
}
|
}
|
||||||
r.options.Output.Request(r.options.TemplateID, formedURL, "http", err)
|
r.options.Output.Request(r.options.TemplateID, formedURL, "http", err)
|
||||||
r.options.Progress.IncrementErrorsBy(1)
|
r.options.Progress.IncrementErrorsBy(1)
|
||||||
|
|
||||||
|
// If we have interactsh markers and request times out, still send
|
||||||
|
// a callback event so in case we recieve an interaction, correlation is possible.
|
||||||
|
if hasInteractMarkers {
|
||||||
|
outputEvent := r.responseToDSLMap(&http.Response{}, reqURL, formedURL, tostring.UnsafeToString(dumpedRequest), "", "", "", 0, request.meta)
|
||||||
|
if i := strings.LastIndex(hostname, ":"); i != -1 {
|
||||||
|
hostname = hostname[:i]
|
||||||
|
}
|
||||||
|
outputEvent["ip"] = httpclientpool.Dialer.GetDialedIP(hostname)
|
||||||
|
|
||||||
|
event := &output.InternalWrappedEvent{InternalEvent: outputEvent}
|
||||||
|
if r.CompiledOperators != nil {
|
||||||
|
event.InternalEvent = outputEvent
|
||||||
|
}
|
||||||
|
callback(event)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|||||||
@ -46,7 +46,7 @@ func (i *Exporter) Export(event *output.ResultEvent) error {
|
|||||||
filenameBuilder.WriteString("-")
|
filenameBuilder.WriteString("-")
|
||||||
filenameBuilder.WriteString(strings.ReplaceAll(strings.ReplaceAll(event.Matched, "/", "_"), ":", "_"))
|
filenameBuilder.WriteString(strings.ReplaceAll(strings.ReplaceAll(event.Matched, "/", "_"), ":", "_"))
|
||||||
filenameBuilder.WriteString(".md")
|
filenameBuilder.WriteString(".md")
|
||||||
finalFilename := filenameBuilder.String()
|
finalFilename := sanitizeFilename(filenameBuilder.String())
|
||||||
|
|
||||||
dataBuilder := &bytes.Buffer{}
|
dataBuilder := &bytes.Buffer{}
|
||||||
dataBuilder.WriteString("### ")
|
dataBuilder.WriteString("### ")
|
||||||
@ -63,3 +63,10 @@ func (i *Exporter) Export(event *output.ResultEvent) error {
|
|||||||
func (i *Exporter) Close() error {
|
func (i *Exporter) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sanitizeFilename(filename string) string {
|
||||||
|
if len(filename) > 256 {
|
||||||
|
filename = filename[0:255]
|
||||||
|
}
|
||||||
|
return filename
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user