mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-17 18:25:25 +00:00
adding support for dsl extractors
This commit is contained in:
parent
3bbce299ae
commit
72c5c399ec
@ -5,7 +5,9 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Knetic/govaluate"
|
||||
"github.com/itchyny/gojq"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/operators/common/dsl"
|
||||
)
|
||||
|
||||
// CompileExtractors performs the initial setup operation on an extractor
|
||||
@ -40,6 +42,14 @@ func (e *Extractor) CompileExtractors() error {
|
||||
e.jsonCompiled = append(e.jsonCompiled, compiled)
|
||||
}
|
||||
|
||||
for _, dslExp := range e.DSL {
|
||||
compiled, err := govaluate.NewEvaluableExpressionWithFunctions(dslExp, dsl.HelperFunctions())
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not compile dsl: %s", dslExp)
|
||||
}
|
||||
e.dslCompiled = append(e.dslCompiled, compiled)
|
||||
}
|
||||
|
||||
if e.CaseInsensitive {
|
||||
if e.GetType() != KValExtractor {
|
||||
return fmt.Errorf("case-insensitive flag is supported only for 'kval' extractors (not '%s')", e.Type)
|
||||
|
||||
@ -2,6 +2,7 @@ package extractors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/antchfx/htmlquery"
|
||||
@ -122,3 +123,24 @@ func (e *Extractor) ExtractJSON(corpus string) map[string]struct{} {
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// ExtractDSL execute the expression and returns the results
|
||||
func (e *Extractor) ExtractDSL(data map[string]interface{}) map[string]struct{} {
|
||||
results := make(map[string]struct{})
|
||||
|
||||
for _, compiledExpression := range e.dslCompiled {
|
||||
result, err := compiledExpression.Evaluate(data)
|
||||
if err != nil {
|
||||
return results
|
||||
}
|
||||
|
||||
if result != nil {
|
||||
resultString := fmt.Sprint(result)
|
||||
if resultString != "" {
|
||||
results[resultString] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
@ -21,6 +21,8 @@ const (
|
||||
XPathExtractor
|
||||
// name:json
|
||||
JSONExtractor
|
||||
// name:dsl
|
||||
DSLExtractor
|
||||
limit
|
||||
)
|
||||
|
||||
@ -30,6 +32,7 @@ var extractorMappings = map[ExtractorType]string{
|
||||
KValExtractor: "kval",
|
||||
XPathExtractor: "xpath",
|
||||
JSONExtractor: "json",
|
||||
DSLExtractor: "dsl",
|
||||
}
|
||||
|
||||
// GetType returns the type of the matcher
|
||||
|
||||
@ -3,6 +3,7 @@ package extractors
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/Knetic/govaluate"
|
||||
"github.com/itchyny/gojq"
|
||||
)
|
||||
|
||||
@ -87,6 +88,11 @@ type Extractor struct {
|
||||
// jsonCompiled is the compiled variant
|
||||
jsonCompiled []*gojq.Code
|
||||
|
||||
// description: |
|
||||
// Extracts using DSL expressions.
|
||||
DSL []string
|
||||
dslCompiled []*govaluate.EvaluableExpression
|
||||
|
||||
// description: |
|
||||
// Part is the part of the request response to extract data from.
|
||||
//
|
||||
|
||||
6
v2/pkg/operators/extractors/util.go
Normal file
6
v2/pkg/operators/extractors/util.go
Normal file
@ -0,0 +1,6 @@
|
||||
package extractors
|
||||
|
||||
// SupportsMap determines if the extractor type requires a map
|
||||
func SupportsMap(extractor *Extractor) bool {
|
||||
return extractor.Type.ExtractorType == KValExtractor || extractor.Type.ExtractorType == DSLExtractor
|
||||
}
|
||||
@ -48,7 +48,7 @@ func (request *Request) Match(data map[string]interface{}, matcher *matchers.Mat
|
||||
// Extract performs extracting operation for an extractor on model and returns true or false.
|
||||
func (request *Request) Extract(data map[string]interface{}, extractor *extractors.Extractor) map[string]struct{} {
|
||||
item, ok := request.getMatchPart(extractor.Part, data)
|
||||
if !ok && extractor.Type.ExtractorType != extractors.KValExtractor {
|
||||
if !ok && !extractors.SupportsMap(extractor) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -57,6 +57,8 @@ func (request *Request) Extract(data map[string]interface{}, extractor *extracto
|
||||
return extractor.ExtractRegex(types.ToString(item))
|
||||
case extractors.KValExtractor:
|
||||
return extractor.ExtractKval(data)
|
||||
case extractors.DSLExtractor:
|
||||
return extractor.ExtractDSL(data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ func (request *Request) Match(data map[string]interface{}, matcher *matchers.Mat
|
||||
// Extract performs extracting operation for an extractor on model and returns true or false.
|
||||
func (request *Request) Extract(data map[string]interface{}, extractor *extractors.Extractor) map[string]struct{} {
|
||||
itemStr, ok := request.getMatchPart(extractor.Part, data)
|
||||
if !ok && extractor.Type.ExtractorType != extractors.KValExtractor {
|
||||
if !ok && !extractors.SupportsMap(extractor) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -46,6 +46,8 @@ func (request *Request) Extract(data map[string]interface{}, extractor *extracto
|
||||
return extractor.ExtractRegex(itemStr)
|
||||
case extractors.KValExtractor:
|
||||
return extractor.ExtractKval(data)
|
||||
case extractors.DSLExtractor:
|
||||
return extractor.ExtractDSL(data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ func (request *Request) Match(data map[string]interface{}, matcher *matchers.Mat
|
||||
// Extract performs extracting operation for an extractor on model and returns true or false.
|
||||
func (request *Request) Extract(data map[string]interface{}, extractor *extractors.Extractor) map[string]struct{} {
|
||||
itemStr, ok := request.getMatchPart(extractor.Part, data)
|
||||
if !ok && extractor.Type.ExtractorType != extractors.KValExtractor {
|
||||
if !ok && !extractors.SupportsMap(extractor) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -46,6 +46,8 @@ func (request *Request) Extract(data map[string]interface{}, extractor *extracto
|
||||
return extractor.ExtractRegex(itemStr)
|
||||
case extractors.KValExtractor:
|
||||
return extractor.ExtractKval(data)
|
||||
case extractors.DSLExtractor:
|
||||
return extractor.ExtractDSL(data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ func getStatusCode(data map[string]interface{}) (int, bool) {
|
||||
// Extract performs extracting operation for an extractor on model and returns true or false.
|
||||
func (request *Request) Extract(data map[string]interface{}, extractor *extractors.Extractor) map[string]struct{} {
|
||||
item, ok := request.getMatchPart(extractor.Part, data)
|
||||
if !ok && extractor.Type.ExtractorType != extractors.KValExtractor {
|
||||
if !ok && !extractors.SupportsMap(extractor) {
|
||||
return nil
|
||||
}
|
||||
switch extractor.GetType() {
|
||||
@ -70,6 +70,8 @@ func (request *Request) Extract(data map[string]interface{}, extractor *extracto
|
||||
return extractor.ExtractHTML(item)
|
||||
case extractors.JSONExtractor:
|
||||
return extractor.ExtractJSON(item)
|
||||
case extractors.DSLExtractor:
|
||||
return extractor.ExtractDSL(data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ func (request *Request) Match(data map[string]interface{}, matcher *matchers.Mat
|
||||
// Extract performs extracting operation for an extractor on model and returns true or false.
|
||||
func (request *Request) Extract(data map[string]interface{}, extractor *extractors.Extractor) map[string]struct{} {
|
||||
itemStr, ok := request.getMatchPart(extractor.Part, data)
|
||||
if !ok && extractor.Type.ExtractorType != extractors.KValExtractor {
|
||||
if !ok && !extractors.SupportsMap(extractor) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -46,6 +46,8 @@ func (request *Request) Extract(data map[string]interface{}, extractor *extracto
|
||||
return extractor.ExtractRegex(itemStr)
|
||||
case extractors.KValExtractor:
|
||||
return extractor.ExtractKval(data)
|
||||
case extractors.DSLExtractor:
|
||||
return extractor.ExtractDSL(data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ func getStatusCode(data map[string]interface{}) (int, bool) {
|
||||
// Extract performs extracting operation for an extractor on model and returns true or false.
|
||||
func (request *Request) Extract(data map[string]interface{}, extractor *extractors.Extractor) map[string]struct{} {
|
||||
item, ok := getMatchPart(extractor.Part, data)
|
||||
if !ok && extractor.Type.ExtractorType != extractors.KValExtractor {
|
||||
if !ok && !extractors.SupportsMap(extractor) {
|
||||
return nil
|
||||
}
|
||||
switch extractor.GetType() {
|
||||
@ -66,6 +66,8 @@ func (request *Request) Extract(data map[string]interface{}, extractor *extracto
|
||||
return extractor.ExtractRegex(item)
|
||||
case extractors.KValExtractor:
|
||||
return extractor.ExtractKval(data)
|
||||
case extractors.DSLExtractor:
|
||||
return extractor.ExtractDSL(data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ func MakeDefaultExtractFunc(data map[string]interface{}, extractor *extractors.E
|
||||
}
|
||||
|
||||
item, ok := data[part]
|
||||
if !ok && extractor.Type.ExtractorType != extractors.KValExtractor {
|
||||
if !ok && !extractors.SupportsMap(extractor) {
|
||||
return nil
|
||||
}
|
||||
itemStr := types.ToString(item)
|
||||
@ -158,6 +158,8 @@ func MakeDefaultExtractFunc(data map[string]interface{}, extractor *extractors.E
|
||||
return extractor.ExtractJSON(itemStr)
|
||||
case extractors.XPathExtractor:
|
||||
return extractor.ExtractHTML(itemStr)
|
||||
case extractors.DSLExtractor:
|
||||
return extractor.ExtractDSL(data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user