From 0f01d63d8a791b73ed654f6a7567563719e07cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=B1=E8=88=9E=E8=80=85?= Date: Fri, 5 May 2023 18:06:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96poc=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E6=AD=A3=E5=88=99Set-Cookie=E6=97=B6=E7=9A=84=E7=BB=93?= =?UTF-8?q?=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WebScan/lib/check.go | 26 ++++++++++++++++++++-- WebScan/lib/eval.go | 51 ++++++++++++++------------------------------ 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/WebScan/lib/check.go b/WebScan/lib/check.go index fe92be0..f7c75a1 100644 --- a/WebScan/lib/check.go +++ b/WebScan/lib/check.go @@ -148,7 +148,7 @@ func executePoc(oReq *http.Request, p *Poc) (bool, error, string) { variableMap["response"] = resp // 先判断响应页面是否匹配search规则 if rule.Search != "" { - result := doSearch(strings.TrimSpace(rule.Search), GetHeader(resp.Headers)+string(resp.Body)) + result := doSearch(rule.Search, GetHeader(resp.Headers)+string(resp.Body)) if result != nil && len(result) > 0 { // 正则匹配成功 for k, v := range result { variableMap[k] = v @@ -202,6 +202,7 @@ func executePoc(oReq *http.Request, p *Poc) (bool, error, string) { func doSearch(re string, body string) map[string]string { r, err := regexp.Compile(re) if err != nil { + fmt.Println("[-] regexp.Compile error: ", err) return nil } result := r.FindStringSubmatch(body) @@ -210,7 +211,11 @@ func doSearch(re string, body string) map[string]string { paramsMap := make(map[string]string) for i, name := range names { if i > 0 && i <= len(result) { - paramsMap[name] = result[i] + if strings.HasPrefix(re, "Set-Cookie:") && strings.Contains(name, "cookie") { + paramsMap[name] = optimizeCookies(result[i]) + } else { + paramsMap[name] = result[i] + } } } return paramsMap @@ -218,6 +223,23 @@ func doSearch(re string, body string) map[string]string { return nil } +func optimizeCookies(rawCookie string) (output string) { + // Parse the cookies + parsedCookie := strings.Split(rawCookie, "; ") + for _, c := range parsedCookie { + nameVal := strings.Split(c, "=") + if len(nameVal) >= 2 { + switch strings.ToLower(nameVal[0]) { + case "expires", "max-age", "path", "domain", "version", "comment", "secure", "samesite", "httponly": + continue + } + output += fmt.Sprintf("%s=%s; ", nameVal[0], strings.Join(nameVal[1:], "=")) + } + } + + return +} + func newReverse() *Reverse { letters := "1234567890abcdefghijklmnopqrstuvwxyz" randSource := rand.New(rand.NewSource(time.Now().UnixNano())) diff --git a/WebScan/lib/eval.go b/WebScan/lib/eval.go index 191aff9..796e70f 100644 --- a/WebScan/lib/eval.go +++ b/WebScan/lib/eval.go @@ -30,6 +30,9 @@ func NewEnv(c *CustomLib) (*cel.Env, error) { } func Evaluate(env *cel.Env, expression string, params map[string]interface{}) (ref.Val, error) { + if expression == "" { + return types.Bool(true), nil + } ast, iss := env.Compile(expression) if iss.Err() != nil { //fmt.Printf("compile: ", iss.Err()) @@ -105,7 +108,7 @@ func NewEnvOption() CustomLib { cel.Declarations( decls.NewIdent("request", decls.NewObjectType("lib.Request"), nil), decls.NewIdent("response", decls.NewObjectType("lib.Response"), nil), - //decls.NewIdent("reverse", decls.NewObjectType("lib.Reverse"), nil), + decls.NewIdent("reverse", decls.NewObjectType("lib.Reverse"), nil), ), cel.Declarations( // functions @@ -625,7 +628,7 @@ func DoRequest(req *http.Request, redirect bool) (*Response, error) { resp, err := ParseResponse(oResp) if err != nil { common.LogError("[-]ParseResponse error: " + err.Error()) - return nil, err + //return nil, err } return resp, err } @@ -675,42 +678,20 @@ func ParseResponse(oResp *http.Response) (*Response, error) { resp.Headers = header resp.ContentType = oResp.Header.Get("Content-Type") body, err := getRespBody(oResp) - if err != nil { - return nil, err - } resp.Body = body - return &resp, nil + return &resp, err } -func getRespBody(oResp *http.Response) ([]byte, error) { - var body []byte - if oResp.Header.Get("Content-Encoding") == "gzip" { - gr, err := gzip.NewReader(oResp.Body) - if err != nil { - if err == io.EOF { - err = nil - } - return nil, err +func getRespBody(oResp *http.Response) (body []byte, err error) { + body, err = io.ReadAll(oResp.Body) + if strings.Contains(oResp.Header.Get("Content-Encoding"), "gzip") { + reader, err1 := gzip.NewReader(bytes.NewReader(body)) + if err1 == nil { + body, err = io.ReadAll(reader) } - defer gr.Close() - for { - buf := make([]byte, 1024) - n, err := gr.Read(buf) - if err != nil && err != io.EOF { - return nil, err - } - if n == 0 { - break - } - body = append(body, buf...) - } - } else { - raw, err := ioutil.ReadAll(io.LimitReader(oResp.Body, 10240)) - if err != nil { - return nil, err - } - defer oResp.Body.Close() - body = raw } - return body, nil + if err == io.EOF { + err = nil + } + return }