mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-18 04:05:27 +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,
|
||||
IssuesClient: runner.issuesClient,
|
||||
Progress: runner.progress,
|
||||
Debug: runner.options.Debug,
|
||||
})
|
||||
if err != nil {
|
||||
gologger.Error().Msgf("Could not create interactsh client: %s", err)
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
package interactsh
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@ -62,6 +65,8 @@ type Options struct {
|
||||
IssuesClient *reporting.Client
|
||||
// Progress is the nuclei progress bar implementation.
|
||||
Progress progress.Progress
|
||||
// Debug specifies whether debugging output should be shown for interactsh-client
|
||||
Debug bool
|
||||
}
|
||||
|
||||
const defaultMaxInteractionsCount = 5000
|
||||
@ -100,6 +105,9 @@ func New(options *Options) (*Client, error) {
|
||||
}
|
||||
|
||||
interactClient.interactsh.StartPolling(interactClient.pollDuration, func(interaction *server.Interaction) {
|
||||
if options.Debug {
|
||||
debugPrintInteraction(interaction)
|
||||
}
|
||||
item := interactClient.requests.Get(interaction.UniqueID)
|
||||
if item == nil {
|
||||
// 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
|
||||
}
|
||||
|
||||
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)
|
||||
go func(httpRequest *generatedRequest) {
|
||||
defer wg.Done()
|
||||
err := r.executeRequest(reqURL, httpRequest, previous, callback, 0)
|
||||
err := r.executeRequest(reqURL, httpRequest, previous, false, callback, 0)
|
||||
mutex.Lock()
|
||||
if err != nil {
|
||||
requestErr = multierr.Append(requestErr, err)
|
||||
@ -107,7 +107,7 @@ func (r *Request) executeParallelHTTP(reqURL string, dynamicValues output.Intern
|
||||
r.options.RateLimiter.Take()
|
||||
|
||||
previous := make(map[string]interface{})
|
||||
err := r.executeRequest(reqURL, httpRequest, previous, callback, 0)
|
||||
err := r.executeRequest(reqURL, httpRequest, previous, false, callback, 0)
|
||||
mutex.Lock()
|
||||
if err != nil {
|
||||
requestErr = multierr.Append(requestErr, err)
|
||||
@ -166,7 +166,7 @@ func (r *Request) executeTurboHTTP(reqURL string, dynamicValues, previous output
|
||||
go func(httpRequest *generatedRequest) {
|
||||
defer swg.Done()
|
||||
|
||||
err := r.executeRequest(reqURL, httpRequest, previous, callback, 0)
|
||||
err := r.executeRequest(reqURL, httpRequest, previous, false, callback, 0)
|
||||
mutex.Lock()
|
||||
if err != nil {
|
||||
requestErr = multierr.Append(requestErr, err)
|
||||
@ -222,7 +222,7 @@ func (r *Request) ExecuteWithResults(reqURL string, dynamicValues, previous outp
|
||||
}
|
||||
var gotOutput bool
|
||||
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.
|
||||
if event.OperatorsResult != nil {
|
||||
gotOutput = true
|
||||
@ -260,7 +260,7 @@ func (r *Request) ExecuteWithResults(reqURL string, dynamicValues, previous outp
|
||||
const drainReqSize = int64(8 * 1024)
|
||||
|
||||
// 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)
|
||||
|
||||
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.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
|
||||
}
|
||||
defer func() {
|
||||
|
||||
@ -46,7 +46,7 @@ func (i *Exporter) Export(event *output.ResultEvent) error {
|
||||
filenameBuilder.WriteString("-")
|
||||
filenameBuilder.WriteString(strings.ReplaceAll(strings.ReplaceAll(event.Matched, "/", "_"), ":", "_"))
|
||||
filenameBuilder.WriteString(".md")
|
||||
finalFilename := filenameBuilder.String()
|
||||
finalFilename := sanitizeFilename(filenameBuilder.String())
|
||||
|
||||
dataBuilder := &bytes.Buffer{}
|
||||
dataBuilder.WriteString("### ")
|
||||
@ -63,3 +63,10 @@ func (i *Exporter) Export(event *output.ResultEvent) error {
|
||||
func (i *Exporter) Close() error {
|
||||
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