Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}