func (ce *CoreEngine) scanErr(k string, d *decode.Decode, i int, checkType int) { _, s, err := d.Get(i) if err != nil { log.Println(err) return } for _, sig := range errSig { v, err := d.Set(i, s+sig) if err != nil { log.Println(err) return } body := ce.setRequest(k, v, checkType) resp, err := ce.sendRequest() if err != nil { continue } if resp.StatusCode >= 500 { reqc := string(DumpRequestHead(ce.Req)) switch b := body.(type) { case string: reqc += b case []byte: reqc += string(b) } respc := DumpResponse(resp, true) resp.Body.Close() ce.ExportRlt(30000, sig, reqc, string(respc)) break } if bErr, cErr := isDbError(resp); bErr { reqc := string(DumpRequestHead(ce.Req)) switch b := body.(type) { case string: reqc += b case []byte: reqc += string(b) } ce.ExportRlt(30001, sig, reqc, cErr) break } resp.Body.Close() } // for errSig }
func (ce *CoreEngine) scanXss(k string, d *decode.Decode, i int, checkType int) { _, s, err := d.Get(i) if err != nil { log.Println(err) return } for _, sig := range xssSig { v, err := d.Set(i, s+sig) if err != nil { log.Println(err) return } body := ce.setRequest(k, v, checkType) resp, err := ce.sendRequest() if err != nil { continue } conTyp := strings.ToLower(resp.Header.Get("Content-Type")) if strings.Index(conTyp, "text/json") == 0 { respByte, _ := ioutil.ReadAll(resp.Body) respString := string(respByte) json := decode.NewDecode(respString) for i := 0; i < json.Count(); i++ { _, s, err = json.Get(i) if err != nil { log.Println(err) continue } if strings.Contains(strings.ToLower(s), sig) { reqc := string(DumpRequestHead(ce.Req)) switch b := body.(type) { case string: reqc += b case []byte: reqc += string(b) } ce.ExportRlt(20001, sig, reqc, respString) resp.Body.Close() break } } } if strings.Index(conTyp, "text/xml") == 0 { respByte, _ := ioutil.ReadAll(resp.Body) respString := string(respByte) xml := decode.NewDecode(respString) for i := 0; i < xml.Count(); i++ { _, s, err := xml.Get(i) if err != nil { log.Println(err) continue } if strings.Contains(strings.ToLower(s), sig) { reqc := string(DumpRequestHead(ce.Req)) switch b := body.(type) { case string: reqc += b case []byte: reqc += string(b) } ce.ExportRlt(20002, sig, reqc, respString) resp.Body.Close() break } } } if strings.Index(conTyp, "text/html") == 0 { var line []byte xss := false bsig := []byte(sig) q := NewQueue(5, false) b := bufio.NewReader(resp.Body) for { line, _ = b.ReadBytes('\n') if len(line) == 0 { break } q.Push(line) if bytes.Contains(bytes.ToLower(line), bsig) { xss = true break } } if xss { if last1, _ := b.ReadBytes('\n'); len(last1) != 0 { q.Push(last1) } if last2, _ := b.ReadBytes('\n'); len(last2) != 0 { q.Push(last2) } result := make([]byte, 0, q.Len()*len(line)) for i := 0; i < q.Len(); i++ { result = append(result, q.Poll().([]byte)...) } reqc := string(DumpRequestHead(ce.Req)) switch b := body.(type) { case string: reqc += b case []byte: reqc += string(b) } ce.ExportRlt(20000, sig, reqc, string(result)) resp.Body.Close() break } } resp.Body.Close() } // for xssSig }
func (ce *CoreEngine) scanSql(k string, d *decode.Decode, i int, checkType int) { _, s, err := d.Get(i) if err != nil { log.Println(err) return } isChr := isChar(s) if len(k) >= 2 && k[:2] == "__" && checkType != checkUrl { return } // --------------------------------SQL injection base blind------------------------------- for _, sig := range injectSig { if isChr && sig.t == sigNum || !isChr && sig.t == sigSch { continue } v, err := d.Set(i, s) if err != nil { log.Println(err) return } body0 := ce.setRequest(k, v, checkType) resp0, err := ce.sendRequest() // original request if err != nil { return } conTyp := strings.ToLower(resp0.Header.Get("Content-Type")) //Content-Type: Text/* if strings.Index(conTyp, "text") != 0 { continue } len0, err := GetRealContentLength(resp0) if err != nil { log.Println("GetRealContentLength err: ", err) continue } resp0.Body.Close() reqc0 := DumpRequestHead(ce.Req) if v, err = d.Set(i, s+sig.s[0]); err != nil { log.Println(err) return } body1 := ce.setRequest(k, v, checkType) resp1, err := ce.sendRequest() // true request if err != nil { continue } conTyp = strings.ToLower(resp1.Header.Get("Content-Type")) //Content-Type: Text/* if strings.Index(conTyp, "text") != 0 { continue } len1, err := GetRealContentLength(resp1) if err != nil { log.Println("GetRealContentLength err: ", err) continue } resp1.Body.Close() reqc1 := DumpRequestHead(ce.Req) if v, err = d.Set(i, s+sig.s[1]); err != nil { log.Println(err) break } body2 := ce.setRequest(k, v, checkType) resp2, err := ce.sendRequest() // false request if err != nil { continue } conTyp = strings.ToLower(resp2.Header.Get("Content-Type")) //Content-Type: Text/* if strings.Index(conTyp, "text") != 0 { continue } len2, err := GetRealContentLength(resp2) if err != nil { log.Println("GetRealContentLength err: ", err) continue } resp2.Body.Close() reqc2 := DumpRequestHead(ce.Req) diff := int(math.Abs(float64(len1-len2)) - math.Abs(float64(len0-len1))) if diff > 20 { respc0 := DumpResponse(resp0, false) respc1 := DumpResponse(resp1, false) respc2 := DumpResponse(resp2, false) reqc := "原始请求: \n" + string(reqc0) switch body := body0.(type) { case string: reqc += body case []byte: reqc += string(body) } reqc += "真条件请求: \n" + string(reqc1) switch body := body1.(type) { case string: reqc += body case []byte: reqc += string(body) } reqc += "假条件请求: \n" + string(reqc2) switch body := body2.(type) { case string: reqc += body case []byte: reqc += string(body) } respc := fmt.Sprintf("|%d-%d|-|%d-%d|=%d\n", len1, len2, len0, len1, diff) respc += "原始响应: \n" + string(respc0) + "真条件响应: \n" + string(respc1) + "假条件响应: \n" + string(respc2) ce.ExportRlt(10000, sig.s, reqc, respc) return } } // for injectSig // --------------------------------SQL injection base time------------------------------- for _, sig := range injectTimeSig { if isChr && sig.t == sigNum || !isChr && sig.t == sigSch { continue } v, err := d.Set(i, s+sig.s) if err != nil { log.Println(err) break } nextSig := false var t0, t1 time.Time var body interface{} var resp *http.Response for j := 0; j < 2; j++ { // try two body = ce.setRequest(k, v, checkType) t0 = time.Now() resp, err = ce.sendRequest() t1 = time.Now() if err != nil { nextSig = true break } resp.Body.Close() if t1.Sub(t0).Seconds() < 15-1 { // No high precision clock nextSig = true break } } if nextSig { continue } reqc := string(DumpRequestHead(ce.Req)) switch b := body.(type) { case string: reqc += b case []byte: reqc += string(b) } respc := DumpResponse(resp, false) s1 := "发送请求时间: " + t0.Format("2006-01-02 15:04:05") + "\n\n" + reqc s2 := "接收请求时间: " + t1.Format("2006-01-02 15:04:05") + "\n\n" + string(respc) ce.ExportRlt(10001, sig.s, s1, s2) return } // for injectTimeSig }