diff --git a/README.md b/README.md index 5a5283a..088745c 100755 --- a/README.md +++ b/README.md @@ -98,6 +98,14 @@ http://127.0.0.1:1231 未经授权,使用pocassist攻击目标是非法的。pocassist仅用于安全测试目的。为避免被恶意使用,本项目所有收录的poc均为漏洞的理论判断,不存在漏洞利用过程,不会对目标发起真实攻击和漏洞利用。 +## 404StarLink 2.0 - Galaxy + +![](https://github.com/knownsec/404StarLink-Project/raw/master/logo.png) + +pocassist 是 404Team [星链计划2.0](https://github.com/knownsec/404StarLink2.0-Galaxy) 中的一环,如果对 pocassist 有任何疑问又或是想要找小伙伴交流,可以参考星链计划的加群方式。 + +- [https://github.com/knownsec/404StarLink2.0-Galaxy#community](https://github.com/knownsec/404StarLink2.0-Galaxy#community) + ## 参考项目 - https://github.com/chaitin/xray/tree/master/pocs @@ -105,4 +113,5 @@ http://127.0.0.1:1231 - https://github.com/jjf012/gopoc - https://codelabs.developers.google.com/codelabs/cel-go#0 - https://github.com/projectdiscovery/nuclei -- https://github.com/projectdiscovery/nuclei-templates/ \ No newline at end of file +- https://github.com/projectdiscovery/nuclei-templates/ + diff --git a/api/routers/v1/plugin/plugin.go b/api/routers/v1/plugin/plugin.go index bee4372..6e13755 100644 --- a/api/routers/v1/plugin/plugin.go +++ b/api/routers/v1/plugin/plugin.go @@ -28,7 +28,7 @@ type Serializer struct { type RunSerializer struct { // 运行单个 Target string `json:"target" binding:"required"` - VulId string `json:"vul_id" binding:"required,startswith=poc-"` + VulId string `json:"vul_id"` Affects string `json:"affects" binding:"required"` JsonPoc datatypes.JSON `json:"json_poc"` } diff --git a/poc/rule/param.go b/poc/rule/param.go index 9a49427..618c8f6 100644 --- a/poc/rule/param.go +++ b/poc/rule/param.go @@ -2,7 +2,6 @@ package rule import ( "fmt" - "github.com/jweny/pocassist/pkg/cel/proto" "net/url" "strings" ) @@ -16,7 +15,8 @@ type ReplaceGet struct { } func (r *ReplaceGet) Replace(value string, field string, controller *PocController) { - reqQuery := ReplaceGetParam(controller.NewReq, value, field, controller.Affects) + getQuery := controller.NewReq.Url.Query + reqQuery := ReplaceGetParam(getQuery, value, field, controller.Affects) req := controller.NewReq curURL := fmt.Sprintf("%s://%s%s?%s", req.Url.Scheme, req.Url.Host, req.Url.Path, reqQuery) controller.FastReq.SetRequestURI(curURL) @@ -27,14 +27,14 @@ type ReplacePost struct { } func (r *ReplacePost) Replace(value string, field string, controller *PocController) { - bodyString := ReplacePostParam(string(controller.reqData), value, field, controller.Affects) + postData := string(controller.reqData) + bodyString := ReplacePostParam(postData, value, field, controller.Affects) controller.FastReq.SetBodyString(bodyString) return } // 返回 get url -func ReplaceGetParam(originalReq *proto.Request, paramValue string, originalFields string, affects string) string { - originalQuery := originalReq.Url.Query +func ReplaceGetParam(originalQuery string, paramValue string, originalFields string, affects string) string { qs, err := url.ParseQuery(originalQuery) if err != nil { return "" diff --git a/poc/rule/poc.go b/poc/rule/poc.go index 4be645b..e4735c9 100644 --- a/poc/rule/poc.go +++ b/poc/rule/poc.go @@ -144,9 +144,9 @@ func RunPoc(inter interface{}) (*util.ScanResult, error) { return result, nil } controller.Reset() - util.RequestPut(newReq) } } + util.RequestPut(newReq) WriteVulResult(scanItem, "", nil) } else { // 影响为其他类型 diff --git a/poc/rule/request.go b/poc/rule/request.go index 1851ff7..22e8c9e 100644 --- a/poc/rule/request.go +++ b/poc/rule/request.go @@ -2,12 +2,14 @@ package rule import ( "bytes" + "errors" "fmt" "github.com/jweny/pocassist/pkg/cel/proto" "github.com/jweny/pocassist/pkg/util" "github.com/valyala/fasthttp" "io/ioutil" "net/http" + "regexp" "strings" ) @@ -72,7 +74,7 @@ func DoSingleRuleRequest(controller *PocController, rule *Rule) (*proto.Response curPath = rule.Path // url级 case AffectURL: - curPath = fmt.Sprint(curPath, strings.TrimPrefix(rule.Path, "/")) + //curPath = curPath, strings.TrimPrefix(rule.Path, "/")) default: } // 兼容xray: 某些 poc 没有区分path和query @@ -86,7 +88,50 @@ func DoSingleRuleRequest(controller *PocController, rule *Rule) (*proto.Response httpRequest.Header.Set(k, v) } httpRequest.Header.SetMethod(rule.Method) - httpRequest.SetBody([]byte(rule.Body)) + // 处理multipart + contentType := string(httpRequest.Header.ContentType()) + if strings.HasPrefix(strings.ToLower(contentType),"multipart/form-data") && strings.Contains(rule.Body,"\n\n") { + multipartBody, err := DealMultipart(contentType, rule.Body) + if err != nil { + return nil, err + } + httpRequest.SetBody([]byte(multipartBody)) + }else { + httpRequest.SetBody([]byte(rule.Body)) + } return util.DoFasthttpRequest(httpRequest, rule.FollowRedirects) -} \ No newline at end of file +} + +func DealMultipart(contentType string, ruleBody string) (result string, err error) { + // 处理multipart的/n + re := regexp.MustCompile(`(?m)multipart\/form-data; boundary=(.*)`) + match := re.FindStringSubmatch(contentType) + if len(match) != 2 { + return "", errors.New("no boundary in content-type") + } + boundary := "--" + match[1] + multiPartContent := "" + + // 处理rule + multiFile := strings.Split(ruleBody, boundary) + if len(multiFile) == 0 { + return multiPartContent, errors.New("ruleBody.Body multi content format err") + } + + for _, singleFile := range multiFile { + // 处理单个文件 + // 文件头和文件响应 + spliteTmp := strings.Split(singleFile,"\n\n") + if len(spliteTmp) == 2 { + fileHeader := spliteTmp[0] + fileBody := spliteTmp[1] + fileHeader = strings.Replace(fileHeader,"\n","\r\n",-1) + multiPartContent += boundary + fileHeader + "\r\n\r\n" + strings.TrimRight(fileBody ,"\n") + "\r\n" + } + } + multiPartContent += boundary + "--" + "\r\n" + return multiPartContent, nil +} + +