use ccache to store matchedTemplates with template-id+host hash as key

dev
Sajad Parra 2021-12-29 12:28:18 +05:30
parent 0edb4274b1
commit e2b39e403c
1 changed files with 25 additions and 7 deletions

View File

@ -2,6 +2,8 @@ package interactsh
import ( import (
"bytes" "bytes"
"crypto/sha1"
"encoding/hex"
"fmt" "fmt"
"net/url" "net/url"
"os" "os"
@ -32,6 +34,8 @@ type Client struct {
requests *ccache.Cache requests *ccache.Cache
// interactions is a stored cache for interactsh-interaction->interactsh-url data // interactions is a stored cache for interactsh-interaction->interactsh-url data
interactions *ccache.Cache interactions *ccache.Cache
// matchedTemplates is a stored cache to track matched templates
matchedTemplates *ccache.Cache
options *Options options *Options
eviction time.Duration eviction time.Duration
@ -41,7 +45,6 @@ type Client struct {
firstTimeGroup sync.Once firstTimeGroup sync.Once
generated uint32 // decide to wait if we have a generated url generated uint32 // decide to wait if we have a generated url
matched bool matched bool
matchedTemplates []string
} }
var ( var (
@ -97,9 +100,12 @@ func New(options *Options) (*Client, error) {
interactionsCfg = interactionsCfg.MaxSize(defaultMaxInteractionsCount) interactionsCfg = interactionsCfg.MaxSize(defaultMaxInteractionsCount)
interactionsCache := ccache.New(interactionsCfg) interactionsCache := ccache.New(interactionsCfg)
matchedTemplateCache := ccache.New(ccache.Configure().MaxSize(defaultMaxInteractionsCount))
interactClient := &Client{ interactClient := &Client{
eviction: options.Eviction, eviction: options.Eviction,
interactions: interactionsCache, interactions: interactionsCache,
matchedTemplates: matchedTemplateCache,
dotHostname: "." + parsed.Host, dotHostname: "." + parsed.Host,
options: options, options: options,
requests: cache, requests: cache,
@ -162,14 +168,24 @@ func (c *Client) firstTimeInitializeClient() error {
return return
} }
if _, ok := request.Event.InternalEvent["stop-at-first-match"]; ok && contains(c.matchedTemplates, request.Event.InternalEvent["template-id"].(string)) { if _, ok := request.Event.InternalEvent["stop-at-first-match"]; ok {
gotItem := c.matchedTemplates.Get(hash(request.Event.InternalEvent["template-id"].(string) + request.Event.InternalEvent["host"].(string)))
if gotItem != nil {
return return
} }
}
_ = c.processInteractionForRequest(interaction, request) _ = c.processInteractionForRequest(interaction, request)
}) })
return nil return nil
} }
func hash(s string) string {
h := sha1.New()
h.Write([]byte(s))
return hex.EncodeToString(h.Sum(nil))
}
// processInteractionForRequest processes an interaction for a request // processInteractionForRequest processes an interaction for a request
func (c *Client) processInteractionForRequest(interaction *server.Interaction, data *RequestData) bool { func (c *Client) processInteractionForRequest(interaction *server.Interaction, data *RequestData) bool {
data.Event.InternalEvent["interactsh_protocol"] = interaction.Protocol data.Event.InternalEvent["interactsh_protocol"] = interaction.Protocol
@ -194,7 +210,9 @@ func (c *Client) processInteractionForRequest(interaction *server.Interaction, d
if writer.WriteResult(data.Event, c.options.Output, c.options.Progress, c.options.IssuesClient) { if writer.WriteResult(data.Event, c.options.Output, c.options.Progress, c.options.IssuesClient) {
c.matched = true c.matched = true
c.matchedTemplates = append(c.matchedTemplates, data.Event.InternalEvent["template-id"].(string)) if _, ok := data.Event.InternalEvent["stop-at-first-match"]; ok {
c.matchedTemplates.Set(hash(data.Event.InternalEvent["template-id"].(string)+data.Event.InternalEvent["host"].(string)), true, defaultInteractionDuration)
}
} }
return true return true
} }