Fixed interactsh edge case + debug mode logging for interact

This commit is contained in:
Ice3man543 2021-08-26 02:43:58 +05:30
parent bd722c2474
commit e7a0417bc2
4 changed files with 55 additions and 6 deletions

View File

@ -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)

View File

@ -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())
}

View File

@ -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() {

View File

@ -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
}