2021-02-24 12:07:16 +05:30
|
|
|
package expressions
|
|
|
|
|
|
|
|
|
|
import (
|
2022-01-09 12:52:04 +01:00
|
|
|
"strings"
|
2021-02-24 12:07:16 +05:30
|
|
|
|
|
|
|
|
"github.com/Knetic/govaluate"
|
2021-11-25 15:39:10 +02:00
|
|
|
|
2021-02-24 12:07:16 +05:30
|
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/operators/common/dsl"
|
|
|
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
|
2022-01-09 12:52:04 +01:00
|
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/marker"
|
2021-02-24 12:07:16 +05:30
|
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/replacer"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Evaluate checks if the match contains a dynamic variable, for each
|
|
|
|
|
// found one we will check if it's an expression and can
|
|
|
|
|
// be compiled, it will be evaluated and the results will be returned.
|
|
|
|
|
//
|
|
|
|
|
// The provided keys from finalValues will be used as variable names
|
|
|
|
|
// for substitution inside the expression.
|
|
|
|
|
func Evaluate(data string, base map[string]interface{}) (string, error) {
|
2021-10-09 19:46:23 +05:30
|
|
|
return evaluate(data, base)
|
2021-02-24 12:07:16 +05:30
|
|
|
}
|
2021-07-06 18:27:30 +05:30
|
|
|
|
|
|
|
|
// EvaluateByte checks if the match contains a dynamic variable, for each
|
|
|
|
|
// found one we will check if it's an expression and can
|
|
|
|
|
// be compiled, it will be evaluated and the results will be returned.
|
|
|
|
|
//
|
|
|
|
|
// The provided keys from finalValues will be used as variable names
|
|
|
|
|
// for substitution inside the expression.
|
|
|
|
|
func EvaluateByte(data []byte, base map[string]interface{}) ([]byte, error) {
|
2021-10-09 19:46:23 +05:30
|
|
|
finalData, err := evaluate(string(data), base)
|
|
|
|
|
return []byte(finalData), err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func evaluate(data string, base map[string]interface{}) (string, error) {
|
|
|
|
|
data = replacer.Replace(data, base)
|
2021-07-06 18:27:30 +05:30
|
|
|
|
|
|
|
|
dynamicValues := make(map[string]interface{})
|
2022-01-09 12:52:04 +01:00
|
|
|
for _, match := range findMatches(data) {
|
2021-07-06 18:27:30 +05:30
|
|
|
expr := generators.TrimDelimiters(match)
|
|
|
|
|
|
|
|
|
|
compiled, err := govaluate.NewEvaluableExpressionWithFunctions(expr, dsl.HelperFunctions())
|
|
|
|
|
if err != nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
result, err := compiled.Evaluate(base)
|
|
|
|
|
if err != nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
dynamicValues[expr] = result
|
|
|
|
|
}
|
|
|
|
|
// Replacer dynamic values if any in raw request and parse it
|
2021-10-09 19:46:23 +05:30
|
|
|
return replacer.Replace(data, dynamicValues), nil
|
2021-07-06 18:27:30 +05:30
|
|
|
}
|
2022-01-09 12:52:04 +01:00
|
|
|
|
|
|
|
|
func findMatches(data string) []string {
|
|
|
|
|
var matches []string
|
|
|
|
|
for _, token := range strings.Split(data, marker.ParenthesisOpen) {
|
|
|
|
|
closingToken := strings.LastIndex(token, marker.ParenthesisClose)
|
|
|
|
|
if closingToken > 0 {
|
|
|
|
|
matches = append(matches, token[:closingToken])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return matches
|
|
|
|
|
}
|