From 528397d4d254d4c01eb9a0ff021fe79c5c79d5f2 Mon Sep 17 00:00:00 2001 From: "maximilian.hildebrand" Date: Wed, 27 Apr 2022 11:26:06 +0200 Subject: [PATCH] fixed runtime error (issue #10), improved mutexes --- pkg/recon.go | 31 ------------------- pkg/requests.go | 76 ++++++++++++++++++++++------------------------- pkg/techniques.go | 3 +- 3 files changed, 37 insertions(+), 73 deletions(-) diff --git a/pkg/recon.go b/pkg/recon.go index 7becc6d..d8aeb3a 100644 --- a/pkg/recon.go +++ b/pkg/recon.go @@ -1272,37 +1272,6 @@ func GetWebsite(requrl string, setStatusCode bool, cacheBuster bool) (WebsiteStr return web, nil } -func getStatusCode() int { - errorString := "getStatusCode" - - var req *http.Request - var err error - - webUrl := strings.TrimSuffix(Config.Website.Url.String(), "?") - - if Config.DoPost { - req, err = http.NewRequest("POST", webUrl, bytes.NewBufferString(Config.Body)) - } else { - req, err = http.NewRequest("GET", webUrl, nil) - } - if err != nil { - msg := fmt.Sprintf("%s: http.NewRequest: %s\n", errorString, err.Error()) - Print(msg, Yellow) - return -1 - } - - setRequest(req, Config.DoPost, randInt(), http.Cookie{}) - waitLimiter(errorString) - resp, err := http.DefaultClient.Do(req) - if err != nil { - msg := fmt.Sprintf("%s: http.DefaultClient.Do: %s\n", errorString, err.Error()) - Print(msg, Yellow) - return -1 - } - - return resp.StatusCode -} - func setQueryParameterMap(queryParameterMap map[string]string, querySlice []string) map[string]string { for _, q := range querySlice { q = strings.TrimSuffix(q, "\r") diff --git a/pkg/requests.go b/pkg/requests.go index 13cce9a..831834e 100644 --- a/pkg/requests.go +++ b/pkg/requests.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io/ioutil" - "log" "net/http" "net/http/httputil" "strings" @@ -47,7 +46,7 @@ func getRespSplit() string { return "\\r\\n" + respSplitHeader + ": " + respSplitValue } -func checkPoisoningIndicators(repResult *reportResult, request reportRequest, success string, body string, poison string, statusCode1 int, statusCode2 int, sameBodyLength bool, header http.Header, m *sync.Mutex, m2 *sync.Mutex, recursive bool) bool { +func checkPoisoningIndicators(repResult *reportResult, request reportRequest, success string, body string, poison string, statusCode1 int, statusCode2 int, sameBodyLength bool, header http.Header, recursive bool) bool { testForResponseSplitting := false // forwardheader benutzen keinen mutex. deswegen macht das if hier keinen Sinn /*if m == nil { @@ -71,12 +70,6 @@ func checkPoisoningIndicators(repResult *reportResult, request reportRequest, su } if request.Reason == "" { - // To prevent false positives and too many requests - if !recursive { - m2.Lock() - defer m2.Unlock() - } - if poison != "" && strings.Contains(body, poison) { request.Reason = "Response Body contained " + poison } else if headerWithPoison != "" { @@ -84,39 +77,47 @@ func checkPoisoningIndicators(repResult *reportResult, request reportRequest, su testForResponseSplitting = true } else if statusCode1 >= 0 && statusCode1 != website.StatusCode && statusCode1 == statusCode2 { if !recursive { - Config.Website, _ = GetWebsite(Config.Website.Url.String(), true, true) - return checkPoisoningIndicators(repResult, request, success, body, poison, statusCode1, statusCode2, sameBodyLength, header, m, m2, true) - } else { - var statcode int + var tmpWebsite WebsiteStruct + var err error + count := 3 - if m != nil { - m.Unlock() - } for i := 0; i < count; i++ { - statcode = getStatusCode() - if statcode != -1 { + tmpWebsite, err = GetWebsite(Config.Website.Url.String(), true, true) + if err == nil { break } } - if m != nil { - m.Lock() - } - if statcode == -1 { + if err != nil { repResult.HasError = true - msg := fmt.Sprintf("%s returned both times %d. But getStatusCode() timed out %d times in a row", request.URL, statusCode1, count) + msg := fmt.Sprintf("%s: couldn't verify if status code %d is the new default status code, because the verification encountered the following error %d times: %s", request.URL, statusCode1, count, err.Error()) repResult.ErrorMessages = append(repResult.ErrorMessages, msg) - return testForResponseSplitting - } else if statcode != statusCode1 { - request.Reason = fmt.Sprintf("Status Code %d differed from %d", statusCode1, website.StatusCode) } else { - log.Println(request.URL + ": status code differs from default one, but getStatusCode returns also a different one") - return testForResponseSplitting + Config.Website = tmpWebsite } + return checkPoisoningIndicators(repResult, request, success, body, poison, statusCode1, statusCode2, sameBodyLength, header, true) + } else { + request.Reason = fmt.Sprintf("Status Code %d differed from %d", statusCode1, website.StatusCode) } } else if Config.CLDiff != 0 && success != "" && sameBodyLength && len(body) > 0 && compareLengths(len(body), len(website.Body), Config.CLDiff) { if !recursive { - Config.Website, _ = GetWebsite(Config.Website.Url.String(), true, true) - return checkPoisoningIndicators(repResult, request, success, body, poison, statusCode1, statusCode2, sameBodyLength, header, m, m2, true) + var tmpWebsite WebsiteStruct + var err error + + count := 3 + for i := 0; i < count; i++ { + tmpWebsite, err = GetWebsite(Config.Website.Url.String(), true, true) + if err == nil { + break + } + } + if err != nil { + repResult.HasError = true + msg := fmt.Sprintf("%s: couldn't verify if body length %d is the new default body length, because the verification request encountered the following error %d times: %s", request.URL, statusCode1, count, err.Error()) + repResult.ErrorMessages = append(repResult.ErrorMessages, msg) + } else { + Config.Website = tmpWebsite + } + return checkPoisoningIndicators(repResult, request, success, body, poison, statusCode1, statusCode2, sameBodyLength, header, true) } else { request.Reason = fmt.Sprintf("Length %d differed more than %d bytes from normal length %d", len(body), Config.CLDiff, len(website.Body)) } @@ -332,12 +333,10 @@ func issueRequest(rp requestParams) (bool, bool) { if err.Error() != "stop" { if rp.m != nil { rp.m.Lock() + defer rp.m.Unlock() } rp.repResult.HasError = true rp.repResult.ErrorMessages = append(rp.repResult.ErrorMessages, err.Error()) - if rp.m != nil { - rp.m.Unlock() - } } return false, false @@ -350,25 +349,22 @@ func issueRequest(rp requestParams) (bool, bool) { if err.Error() != "stop" { if rp.m != nil { rp.m.Lock() + defer rp.m.Unlock() } rp.repResult.HasError = true rp.repResult.ErrorMessages = append(rp.repResult.ErrorMessages, err.Error()) - if rp.m != nil { - rp.m.Unlock() - } } return false, true } sameBodyLength := len(body1) == len(body2) + // Lock here, to prevent false positives and too many GetWebsite requests + if rp.m != nil { rp.m.Lock() + defer rp.m.Unlock() } - var m2 = &sync.Mutex{} - responseSplitting := checkPoisoningIndicators(rp.repResult, request, rp.success, string(body2), rp.poison, statusCode1, statusCode2, sameBodyLength, respHeader, rp.m, m2, false) - if rp.m != nil { - rp.m.Unlock() - } + responseSplitting := checkPoisoningIndicators(rp.repResult, request, rp.success, string(body2), rp.poison, statusCode1, statusCode2, sameBodyLength, respHeader, false) return responseSplitting, true } diff --git a/pkg/techniques.go b/pkg/techniques.go index e90eec2..ebdb8e6 100644 --- a/pkg/techniques.go +++ b/pkg/techniques.go @@ -907,8 +907,7 @@ func hho(repResult *reportResult) { msg = fmt.Sprintf("------- HHO DOS was successfully poisoned!!! cb: %s -------\n%s\n", cb, request.URL) m.Lock() - var m2 = &sync.Mutex{} - _ = checkPoisoningIndicators(repResult, request, msg, "", "", statusCode1, statusCode2, false, respHeader, &m, m2, false) + _ = checkPoisoningIndicators(repResult, request, msg, "", "", statusCode1, statusCode2, false, respHeader, false) m.Unlock() <-sem