refactor: In case of binary data, show a hexadecimal view as well #1080

* small enhancements with regards to dumping responses
This commit is contained in:
forgedhallpass 2021-11-01 20:45:54 +02:00
parent b477508521
commit 8f6280dc9d
5 changed files with 70 additions and 53 deletions

View File

@ -65,22 +65,22 @@ func (request *Request) ExecuteWithResults(input string, metadata /*TODO review
event := eventcreator.CreateEvent(request, outputEvent, request.options.Options.Debug || request.options.Options.DebugResponse) event := eventcreator.CreateEvent(request, outputEvent, request.options.Options.Debug || request.options.Options.DebugResponse)
debug(event, request, domain, response.String()) dumpResponse(event, request.options, response.String(), domain)
callback(event) callback(event)
return nil return nil
} }
func debug(event *output.InternalWrappedEvent, request *Request, domain string, response string) { func dumpResponse(event *output.InternalWrappedEvent, requestOptions *protocols.ExecuterOptions, response string, domain string) {
if request.options.Options.Debug || request.options.Options.DebugResponse { cliOptions := requestOptions.Options
gologger.Debug().Msgf("[%s] Dumped DNS response for %s\n", request.options.TemplateID, domain) if cliOptions.Debug || cliOptions.DebugResponse {
hexDump := false hexDump := false
if !responsehighlighter.IsASCII(response) { if responsehighlighter.HasBinaryContent(response) {
hexDump = true hexDump = true
response = hex.Dump([]byte(response)) response = hex.Dump([]byte(response))
} }
gologger.Print().Msgf("%s", responsehighlighter.Highlight(event.OperatorsResult, response, request.options.Options.NoColor, hexDump)) highlightedResponse := responsehighlighter.Highlight(event.OperatorsResult, response, cliOptions.NoColor, hexDump)
gologger.Debug().Msgf("[%s] Dumped DNS response for %s\n\n%s", requestOptions.TemplateID, domain, highlightedResponse)
} }
} }

View File

@ -2,7 +2,6 @@ package file
import ( import (
"encoding/hex" "encoding/hex"
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -61,7 +60,7 @@ func (request *Request) ExecuteWithResults(input string, metadata /*TODO review
event := eventcreator.CreateEvent(request, outputEvent, request.options.Options.Debug || request.options.Options.DebugResponse) event := eventcreator.CreateEvent(request, outputEvent, request.options.Options.Debug || request.options.Options.DebugResponse)
debug(event, request, filePath, fileContent) dumpResponse(event, request.options, fileContent, filePath)
callback(event) callback(event)
}(data) }(data)
@ -76,14 +75,15 @@ func (request *Request) ExecuteWithResults(input string, metadata /*TODO review
return nil return nil
} }
func debug(event *output.InternalWrappedEvent, request *Request, filePath string, fileContent string) { func dumpResponse(event *output.InternalWrappedEvent, requestOptions *protocols.ExecuterOptions, fileContent string, filePath string) {
if request.options.Options.Debug || request.options.Options.DebugResponse { cliOptions := requestOptions.Options
if cliOptions.Debug || cliOptions.DebugResponse {
hexDump := false hexDump := false
if !responsehighlighter.IsASCII(fileContent) { if responsehighlighter.HasBinaryContent(fileContent) {
hexDump = true hexDump = true
fileContent = hex.Dump([]byte(fileContent)) fileContent = hex.Dump([]byte(fileContent))
} }
logHeader := fmt.Sprintf("[%s] Dumped file request for %s\n", request.options.TemplateID, filePath) highlightedResponse := responsehighlighter.Highlight(event.OperatorsResult, fileContent, cliOptions.NoColor, hexDump)
gologger.Debug().Msgf("%s\n%s", logHeader, responsehighlighter.Highlight(event.OperatorsResult, fileContent, request.options.Options.NoColor, hexDump)) gologger.Debug().Msgf("[%s] Dumped file request for %s\n\n%s", requestOptions.TemplateID, filePath, highlightedResponse)
} }
} }

View File

@ -67,15 +67,16 @@ func (request *Request) ExecuteWithResults(inputURL string, metadata, previous o
event := eventcreator.CreateEvent(request, outputEvent, request.options.Options.Debug || request.options.Options.DebugResponse) event := eventcreator.CreateEvent(request, outputEvent, request.options.Options.Debug || request.options.Options.DebugResponse)
debug(event, request, responseBody, inputURL) dumpResponse(event, request.options, responseBody, inputURL)
callback(event) callback(event)
return nil return nil
} }
func debug(event *output.InternalWrappedEvent, request *Request, responseBody string, input string) { func dumpResponse(event *output.InternalWrappedEvent, requestOptions *protocols.ExecuterOptions, responseBody string, input string) {
if request.options.Options.Debug || request.options.Options.DebugResponse { cliOptions := requestOptions.Options
gologger.Debug().Msgf("[%s] Dumped Headless response for %s\n", request.options.TemplateID, input) if cliOptions.Debug || cliOptions.DebugResponse {
gologger.Print().Msgf("%s", responsehighlighter.Highlight(event.OperatorsResult, responseBody, request.options.Options.NoColor, false)) highlightedResponse := responsehighlighter.Highlight(event.OperatorsResult, responseBody, cliOptions.NoColor, false)
gologger.Debug().Msgf("[%s] Dumped Headless response for %s\n\n%s", requestOptions.TemplateID, input, highlightedResponse)
} }
} }

View File

@ -511,7 +511,7 @@ func (request *Request) executeRequest(reqURL string, generatedRequest *generate
internalWrappedEvent.OperatorsResult.PayloadValues = generatedRequest.meta internalWrappedEvent.OperatorsResult.PayloadValues = generatedRequest.meta
}) })
debug(request, formedURL, redirectedResponse, responseContentType, event) dumpResponse(event, request.options, redirectedResponse, formedURL, responseContentType)
callback(event) callback(event)
return nil return nil
@ -534,26 +534,33 @@ func (request *Request) setCustomHeaders(req *generatedRequest) {
const CRLF = "\r\n" const CRLF = "\r\n"
func debug(request *Request, formedURL string, redirectedResponse []byte, responseContentType string, event *output.InternalWrappedEvent) { func dumpResponse(event *output.InternalWrappedEvent, requestOptions *protocols.ExecuterOptions, redirectedResponse []byte, formedURL string, responseContentType string) {
if request.options.Options.Debug || request.options.Options.DebugResponse { cliOptions := requestOptions.Options
hexDump := false if cliOptions.Debug || cliOptions.DebugResponse {
response := string(redirectedResponse) response := string(redirectedResponse)
var headers string var highlightedResult string
if responseContentType == "" || responseContentType == "application/octet-stream" || (responseContentType == "application/x-www-form-urlencoded" && responsehighlighter.IsASCII(response)) { if responseContentType == "application/octet-stream" || ((responseContentType == "" || responseContentType == "application/x-www-form-urlencoded") && responsehighlighter.HasBinaryContent(response)) {
hexDump = true highlightedResult = createResponseHexDump(event, response, cliOptions.NoColor)
responseLines := strings.Split(response, CRLF) } else {
for i, value := range responseLines { highlightedResult = responsehighlighter.Highlight(event.OperatorsResult, response, cliOptions.NoColor, false)
headers += value + CRLF
if value == "" {
response = hex.Dump([]byte(strings.Join(responseLines[i+1:], "")))
break
}
}
} }
logMessageHeader := fmt.Sprintf("[%s] Dumped HTTP response for %s\n", request.options.TemplateID, formedURL)
gologger.Debug().Msgf("%s\n%s", logMessageHeader, responsehighlighter.Highlight(event.OperatorsResult, headers, request.options.Options.NoColor, false)) gologger.Debug().Msgf("[%s] Dumped HTTP response for %s\n\n%s", requestOptions.TemplateID, formedURL, highlightedResult)
gologger.Print().Msgf("%s", responsehighlighter.Highlight(event.OperatorsResult, response, request.options.Options.NoColor, hexDump)) }
}
func createResponseHexDump(event *output.InternalWrappedEvent, response string, noColor bool) string {
CRLFs := CRLF + CRLF
headerEndIndex := strings.Index(response, CRLFs) + len(CRLFs)
if headerEndIndex > 0 {
headers := response[0:headerEndIndex]
responseBodyHexDump := hex.Dump([]byte(response[headerEndIndex:]))
highlightedHeaders := responsehighlighter.Highlight(event.OperatorsResult, headers, noColor, false)
highlightedResponse := responsehighlighter.Highlight(event.OperatorsResult, responseBodyHexDump, noColor, true)
return fmt.Sprintf("%s\n%s", highlightedHeaders, highlightedResponse)
} else {
return responsehighlighter.Highlight(event.OperatorsResult, hex.Dump([]byte(response)), noColor, true)
} }
} }

View File

@ -13,6 +13,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectdiscovery/gologger" "github.com/projectdiscovery/gologger"
"github.com/projectdiscovery/nuclei/v2/pkg/operators"
"github.com/projectdiscovery/nuclei/v2/pkg/output" "github.com/projectdiscovery/nuclei/v2/pkg/output"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols" "github.com/projectdiscovery/nuclei/v2/pkg/protocols"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/expressions" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/expressions"
@ -189,9 +190,8 @@ func (request *Request) executeRequestWithPayloads(actualAddress, address, input
request.options.Progress.IncrementRequests() request.options.Progress.IncrementRequests()
if request.options.Options.Debug || request.options.Options.DebugRequests { if request.options.Options.Debug || request.options.Options.DebugRequests {
gologger.Info().Str("address", actualAddress).Msgf("[%s] Dumped Network request for %s\n", request.options.TemplateID, actualAddress)
requestBytes := []byte(reqBuilder.String()) requestBytes := []byte(reqBuilder.String())
gologger.Print().Msgf("%s", hex.Dump(requestBytes)) gologger.Debug().Str("address", actualAddress).Msgf("[%s] Dumped Network request for %s\n%s", request.options.TemplateID, actualAddress, hex.Dump(requestBytes))
if request.options.Options.VerboseVerbose { if request.options.Options.VerboseVerbose {
gologger.Print().Msgf("\nCompact HEX view:\n%s", hex.EncodeToString(requestBytes)) gologger.Print().Msgf("\nCompact HEX view:\n%s", hex.EncodeToString(requestBytes))
} }
@ -277,29 +277,38 @@ func (request *Request) executeRequestWithPayloads(actualAddress, address, input
}) })
} }
debug(event, request, response, actualAddress) dumpResponse(event, request.options, response, actualAddress)
return nil return nil
} }
func debug(event *output.InternalWrappedEvent, request *Request, response string, actualAddress string) { func dumpResponse(event *output.InternalWrappedEvent, requestOptions *protocols.ExecuterOptions, response string, actualAddress string) {
if request.options.Options.Debug || request.options.Options.DebugResponse { cliOptions := requestOptions.Options
gologger.Debug().Msgf("[%s] Dumped Network response for %s\n", request.options.TemplateID, actualAddress) if cliOptions.Debug || cliOptions.DebugResponse {
requestBytes := []byte(response) requestBytes := []byte(response)
gologger.Print().Msgf("%s", responsehighlighter.Highlight(event.OperatorsResult, hex.Dump(requestBytes), request.options.Options.NoColor, true)) highlightedResponse := responsehighlighter.Highlight(event.OperatorsResult, hex.Dump(requestBytes), cliOptions.NoColor, true)
if request.options.Options.VerboseVerbose { gologger.Debug().Msgf("[%s] Dumped Network response for %s\n\n%s", requestOptions.TemplateID, actualAddress, highlightedResponse)
var allMatches []string
for _, namedMatch := range event.OperatorsResult.Matches { if cliOptions.VerboseVerbose {
for _, matchElement := range namedMatch { displayCompactHexView(event, response, cliOptions.NoColor)
allMatches = append(allMatches, hex.EncodeToString([]byte(matchElement)))
}
}
event.OperatorsResult.Matches["compact"] = allMatches
gologger.Print().Msgf("\nCompact HEX view:\n%s", responsehighlighter.Highlight(event.OperatorsResult, hex.EncodeToString([]byte(response)), request.options.Options.NoColor, false))
} }
} }
} }
func displayCompactHexView(event *output.InternalWrappedEvent, response string, noColor bool) {
operatorsResult := event.OperatorsResult
if operatorsResult != nil {
var allMatches []string
for _, namedMatch := range operatorsResult.Matches {
for _, matchElement := range namedMatch {
allMatches = append(allMatches, hex.EncodeToString([]byte(matchElement)))
}
}
tempOperatorResult := &operators.Result{Matches: map[string][]string{"matchesInHex": allMatches}}
gologger.Print().Msgf("\nCompact HEX view:\n%s", responsehighlighter.Highlight(tempOperatorResult, hex.EncodeToString([]byte(response)), noColor, false))
}
}
// getAddress returns the address of the host to make request to // getAddress returns the address of the host to make request to
func getAddress(toTest string) (string, error) { func getAddress(toTest string) (string, error) {
if strings.Contains(toTest, "://") { if strings.Contains(toTest, "://") {