mirror of https://github.com/daffainfo/nuclei.git
Add generate_jwt & json_{minify,prettify} helper functions (#3160)
* feat(dsl): add generate_jwt helper func * feat(dsl): add json_{minify,prettify} & quote_escape * update(dsl): change type of data var to map[string]interface{} * docs(dsl): list valid algos for generate_jwt * test(dsl): add test case for json_{minify,prettify} & quote_escape * update(dsl): refactor generate_jwt * fix(lint): use time.Until instead of t.Sub(time.Now()) (gosimple) * revert(dsl): remove quote_escape func * ability to fuzz jwt noNe algorithm * fix lint error * jwt dsl minor improvement Co-authored-by: Tarun Koyalwar <tarun@projectdiscovery.io>dev
parent
67c094444e
commit
94ec553234
|
@ -66,6 +66,7 @@ require (
|
|||
github.com/go-git/go-git/v5 v5.5.2
|
||||
github.com/h2non/filetype v1.1.3
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/kataras/jwt v0.1.8
|
||||
github.com/klauspost/compress v1.15.13
|
||||
github.com/labstack/echo/v4 v4.10.0
|
||||
github.com/mholt/archiver v3.1.1+incompatible
|
||||
|
|
|
@ -394,6 +394,8 @@ github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4
|
|||
github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8=
|
||||
github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U=
|
||||
github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE=
|
||||
github.com/kataras/jwt v0.1.8 h1:u71baOsYD22HWeSOg32tCHbczPjdCk7V4MMeJqTtmGk=
|
||||
github.com/kataras/jwt v0.1.8/go.mod h1:Q5j2IkcIHnfwy+oNY3TVWuEBJNw0ADgCcXK9CaZwV4o=
|
||||
github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw=
|
||||
github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE=
|
||||
github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0=
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"crypto/sha512"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash"
|
||||
"html"
|
||||
|
@ -32,6 +33,7 @@ import (
|
|||
"github.com/Knetic/govaluate"
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/kataras/jwt"
|
||||
"github.com/logrusorgru/aurora"
|
||||
"github.com/spaolacci/murmur3"
|
||||
|
||||
|
@ -809,6 +811,118 @@ func init() {
|
|||
data := gcm.Seal(nonce, nonce, []byte(value), nil)
|
||||
return data, nil
|
||||
}),
|
||||
"generate_jwt": makeDslWithOptionalArgsFunction(
|
||||
"(jsonString, optionalAlgorithm, optionalSignature string, optionalMaxAgeUnix interface{}) string",
|
||||
func(args ...interface{}) (interface{}, error) {
|
||||
var optionalAlgorithm string
|
||||
var optionalSignature []byte
|
||||
var optionalMaxAgeUnix time.Time
|
||||
|
||||
var signOpts []jwt.SignOption
|
||||
var jsonData jwt.Map
|
||||
|
||||
argSize := len(args)
|
||||
|
||||
if argSize < 1 || argSize > 4 {
|
||||
return nil, invalidDslFunctionError
|
||||
}
|
||||
jsonString := args[0].(string)
|
||||
|
||||
err := json.Unmarshal([]byte(jsonString), &jsonData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var algorithm jwt.Alg
|
||||
|
||||
if argSize > 1 {
|
||||
alg := args[1].(string)
|
||||
optionalAlgorithm = strings.ToUpper(alg)
|
||||
|
||||
switch optionalAlgorithm {
|
||||
case "":
|
||||
algorithm = jwt.NONE
|
||||
case "HS256":
|
||||
algorithm = jwt.HS256
|
||||
case "HS384":
|
||||
algorithm = jwt.HS384
|
||||
case "HS512":
|
||||
algorithm = jwt.HS512
|
||||
case "RS256":
|
||||
algorithm = jwt.RS256
|
||||
case "RS384":
|
||||
algorithm = jwt.RS384
|
||||
case "RS512":
|
||||
algorithm = jwt.RS512
|
||||
case "PS256":
|
||||
algorithm = jwt.PS256
|
||||
case "PS384":
|
||||
algorithm = jwt.PS384
|
||||
case "PS512":
|
||||
algorithm = jwt.PS512
|
||||
case "ES256":
|
||||
algorithm = jwt.ES256
|
||||
case "ES384":
|
||||
algorithm = jwt.ES384
|
||||
case "ES512":
|
||||
algorithm = jwt.ES512
|
||||
case "EDDSA":
|
||||
algorithm = jwt.EdDSA
|
||||
}
|
||||
|
||||
if isjwtAlgorithmNone(alg) {
|
||||
algorithm = &algNONE{algValue: alg}
|
||||
}
|
||||
if algorithm == nil {
|
||||
return nil, fmt.Errorf("invalid algorithm: %s", optionalAlgorithm)
|
||||
}
|
||||
}
|
||||
|
||||
if argSize > 2 {
|
||||
optionalSignature = []byte(args[2].(string))
|
||||
}
|
||||
|
||||
if argSize > 3 {
|
||||
times := make([]interface{}, 2)
|
||||
times[0] = nil
|
||||
times[1] = args[3]
|
||||
|
||||
optionalMaxAgeUnix, err = getCurrentTimeFromUserInput(times)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
duration := time.Until(optionalMaxAgeUnix)
|
||||
signOpts = append(signOpts, jwt.MaxAge(duration))
|
||||
}
|
||||
|
||||
return jwt.Sign(algorithm, optionalSignature, jsonData, signOpts...)
|
||||
}),
|
||||
"json_minify": makeDslFunction(1, func(args ...interface{}) (interface{}, error) {
|
||||
var data map[string]interface{}
|
||||
|
||||
err := json.Unmarshal([]byte(args[0].(string)), &data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
minified, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return string(minified), nil
|
||||
}),
|
||||
"json_prettify": makeDslFunction(1, func(args ...interface{}) (interface{}, error) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
err := json.Indent(&buf, []byte(args[0].(string)), "", " ")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.String(), nil
|
||||
}),
|
||||
}
|
||||
|
||||
dslFunctions = make(map[string]dslFunction, len(tempDslFunctions))
|
||||
|
@ -1097,3 +1211,28 @@ func (e *CompilationError) Error() string {
|
|||
func (e *CompilationError) Unwrap() error {
|
||||
return e.WrappedError
|
||||
}
|
||||
|
||||
type algNONE struct {
|
||||
algValue string
|
||||
}
|
||||
|
||||
func (a *algNONE) Name() string {
|
||||
return a.algValue
|
||||
}
|
||||
|
||||
func (a *algNONE) Sign(key jwt.PrivateKey, headerAndPayload []byte) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (a *algNONE) Verify(key jwt.PublicKey, headerAndPayload []byte, signature []byte) error {
|
||||
if !bytes.Equal(signature, []byte{}) {
|
||||
return jwt.ErrTokenSignature
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isjwtAlgorithmNone(alg string) bool {
|
||||
alg = strings.TrimSpace(alg)
|
||||
return strings.ToLower(alg) == "none"
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ func TestGetPrintableDslFunctionSignatures(t *testing.T) {
|
|||
dec_to_hex(arg1 interface{}) interface{}
|
||||
ends_with(str string, suffix ...string) bool
|
||||
generate_java_gadget(arg1, arg2, arg3 interface{}) interface{}
|
||||
generate_jwt(jsonString, optionalAlgorithm, optionalSignature string, optionalMaxAgeUnix interface{}) string
|
||||
gzip(arg1 interface{}) interface{}
|
||||
gzip_decode(arg1 interface{}) interface{}
|
||||
hex_decode(arg1 interface{}) interface{}
|
||||
|
@ -118,6 +119,8 @@ func TestGetPrintableDslFunctionSignatures(t *testing.T) {
|
|||
html_unescape(arg1 interface{}) interface{}
|
||||
join(separator string, elements ...interface{}) string
|
||||
join(separator string, elements []interface{}) string
|
||||
json_minify(arg1 interface{}) interface{}
|
||||
json_prettify(arg1 interface{}) interface{}
|
||||
len(arg1 interface{}) interface{}
|
||||
line_ends_with(str string, suffix ...string) bool
|
||||
line_starts_with(str string, prefix ...string) bool
|
||||
|
@ -216,6 +219,7 @@ func TestDslExpressions(t *testing.T) {
|
|||
`zlib_decode(hex_decode("789cf248cdc9c907040000ffff058c01f5"))`: "Hello",
|
||||
`gzip_decode(hex_decode("1f8b08000000000000fff248cdc9c907040000ffff8289d1f705000000"))`: "Hello",
|
||||
`generate_java_gadget("commons-collections3.1", "wget https://{{interactsh-url}}", "base64")`: "rO0ABXNyABFqYXZhLnV0aWwuSGFzaFNldLpEhZWWuLc0AwAAeHB3DAAAAAI/QAAAAAAAAXNyADRvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMua2V5dmFsdWUuVGllZE1hcEVudHJ5iq3SmznBH9sCAAJMAANrZXl0ABJMamF2YS9sYW5nL09iamVjdDtMAANtYXB0AA9MamF2YS91dGlsL01hcDt4cHQAJmh0dHBzOi8vZ2l0aHViLmNvbS9qb2FvbWF0b3NmL2pleGJvc3Mgc3IAKm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5tYXAuTGF6eU1hcG7llIKeeRCUAwABTAAHZmFjdG9yeXQALExvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnMvVHJhbnNmb3JtZXI7eHBzcgA6b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkNoYWluZWRUcmFuc2Zvcm1lcjDHl%2BwoepcEAgABWwANaVRyYW5zZm9ybWVyc3QALVtMb3JnL2FwYWNoZS9jb21tb25zL2NvbGxlY3Rpb25zL1RyYW5zZm9ybWVyO3hwdXIALVtMb3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLlRyYW5zZm9ybWVyO71WKvHYNBiZAgAAeHAAAAAFc3IAO29yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5mdW5jdG9ycy5Db25zdGFudFRyYW5zZm9ybWVyWHaQEUECsZQCAAFMAAlpQ29uc3RhbnRxAH4AA3hwdnIAEWphdmEubGFuZy5SdW50aW1lAAAAAAAAAAAAAAB4cHNyADpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuSW52b2tlclRyYW5zZm9ybWVyh%2Bj/a3t8zjgCAANbAAVpQXJnc3QAE1tMamF2YS9sYW5nL09iamVjdDtMAAtpTWV0aG9kTmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO1sAC2lQYXJhbVR5cGVzdAASW0xqYXZhL2xhbmcvQ2xhc3M7eHB1cgATW0xqYXZhLmxhbmcuT2JqZWN0O5DOWJ8QcylsAgAAeHAAAAACdAAKZ2V0UnVudGltZXVyABJbTGphdmEubGFuZy5DbGFzczurFteuy81amQIAAHhwAAAAAHQACWdldE1ldGhvZHVxAH4AGwAAAAJ2cgAQamF2YS5sYW5nLlN0cmluZ6DwpDh6O7NCAgAAeHB2cQB%2BABtzcQB%2BABN1cQB%2BABgAAAACcHVxAH4AGAAAAAB0AAZpbnZva2V1cQB%2BABsAAAACdnIAEGphdmEubGFuZy5PYmplY3QAAAAAAAAAAAAAAHhwdnEAfgAYc3EAfgATdXIAE1tMamF2YS5sYW5nLlN0cmluZzut0lbn6R17RwIAAHhwAAAAAXQAH3dnZXQgaHR0cHM6Ly97e2ludGVyYWN0c2gtdXJsfX10AARleGVjdXEAfgAbAAAAAXEAfgAgc3EAfgAPc3IAEWphdmEubGFuZy5JbnRlZ2VyEuKgpPeBhzgCAAFJAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cAAAAAFzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAAdwgAAAAQAAAAAHh4eA==",
|
||||
`generate_jwt("{\"name\":\"John Doe\",\"foo\":\"bar\"}", "HS256", "hello-world")`: []byte("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJuYW1lIjoiSm9obiBEb2UifQ.EsrL8lIcYJR_Ns-JuhF3VCllCP7xwbpMCCfHin_WT6U"),
|
||||
`base64_decode("SGVsbG8=")`: "Hello",
|
||||
`hex_decode("6161")`: "aa",
|
||||
`len("Hello")`: float64(5),
|
||||
|
@ -264,6 +268,8 @@ func TestDslExpressions(t *testing.T) {
|
|||
`uniq("ab", "cd", "12", "34", "12", "cd")`: []string{"ab", "cd", "12", "34"},
|
||||
`join(" ", uniq("ab", "cd", "12", "34", "12", "cd"))`: "ab cd 12 34",
|
||||
`join(", ", split(hex_encode("abcdefg"), 2))`: "61, 62, 63, 64, 65, 66, 67",
|
||||
`json_minify("{ \"name\": \"John Doe\", \"foo\": \"bar\" }")`: "{\"foo\":\"bar\",\"name\":\"John Doe\"}",
|
||||
`json_prettify("{\"foo\":\"bar\",\"name\":\"John Doe\"}")`: "{\n \"foo\": \"bar\",\n \"name\": \"John Doe\"\n}",
|
||||
}
|
||||
|
||||
testDslExpressionScenarios(t, dslExpressions)
|
||||
|
|
Loading…
Reference in New Issue