From e43b54a5ec5cc20a3845be6b8c901c4eea2a832d Mon Sep 17 00:00:00 2001 From: nodauf Date: Wed, 22 May 2024 22:36:54 +0200 Subject: [PATCH] Remove embedded files feature --- src/controllers/embeddedFiles.go.old | 230 +++++++++++++++++++++ src/controllers/runEmbedded_darwin.go.old | 15 ++ src/controllers/runEmbedded_linux.go.old | 16 ++ src/controllers/runEmbedded_windows.go.old | 104 ++++++++++ 4 files changed, 365 insertions(+) create mode 100644 src/controllers/embeddedFiles.go.old create mode 100644 src/controllers/runEmbedded_darwin.go.old create mode 100644 src/controllers/runEmbedded_linux.go.old create mode 100644 src/controllers/runEmbedded_windows.go.old diff --git a/src/controllers/embeddedFiles.go.old b/src/controllers/embeddedFiles.go.old new file mode 100644 index 0000000..e9fc33c --- /dev/null +++ b/src/controllers/embeddedFiles.go.old @@ -0,0 +1,230 @@ +package controllers + +import ( + "compress/gzip" + "compress/zlib" + "container/list" + "fmt" + "io" + "log" + "net/http" + "net/url" + "os" + "sort" + "strconv" + "strings" + + "Swego/src/cmd" + "Swego/src/utils" + + rice "github.com/GeertJohan/go.rice" + "github.com/gabriel-vasile/mimetype" + "github.com/yeka/zip" +) + +const pathEmbedded = "./assets/embedded/" + +// EmbeddedRequest manage the request on the embedded files (when the parameter ?embedded is present) +func EmbeddedRequest(w http.ResponseWriter, req *http.Request) { + requestPath := strings.Split(req.RequestURI, "?")[0] + + if requestPath[len(requestPath)-1:] == "/" { // Directory listing if it's a folder (last character is /) + handleEmbeddedDirectory(requestPath, w, req) + } else { // It's a file, we serve the file + fileName := requestPath[1:] + serveEmbeddedFile(fileName, w, req) + } +} + +func serveEmbeddedFile(filePath string, w http.ResponseWriter, req *http.Request) { + //Can't use variable, otherwise rice generate an error when rice embed-go .... + templateBox, err := rice.FindBox("../assets/embedded/") + + if err != nil { + log.Fatal(err) + } + // Opening the file handle + //f, err := os.Open(filePath) + f, err := templateBox.Open(filePath) + // Content-Type handling + query, errParseQuery := url.ParseQuery(req.URL.RawQuery) + + if err != nil { + http.Error(w, "404 Not Found : Error while opening the file.", 404) + log.Println("404 Not Found : Error while opening the file " + filePath) + return + } + defer f.Close() + + // Checking if the opened handle is really a file + statinfo, err := f.Stat() + + //buf := make([]byte, utils.Min(fs_maxbufsize, statinfo.Size())) + //buf := make([]byte, statinfo.Size()) + //fmt.Println(len(buf)) + //f.Read(buf) + + if err != nil || errParseQuery != nil { + http.Error(w, "500 Internal Error : stat() failure.", 500) + log.Println("500 Internal Error : stat() failure for the file: " + filePath) + return + } + if errParseQuery == nil && len(query["dl"]) > 0 { // The user explicitedly wanted to download the file (Dropbox style!) + w.Header().Set("Content-Type", "application/octet-stream") + } else if errParseQuery == nil && len(query["dlenc"]) > 0 { // Download the file as an encrypted zip + + // Absolute path to the file + //filePathName := f.Name() + // Create the zip file can't create in embedded path. Create temporarily in root of the webserver + zipFile, err := os.Create(filePath + ".zip") + if err != nil { + log.Fatalln(err) + } + zipFilePath := zipFile.Name() + zipw := zip.NewWriter(zipFile) + + // Add file f to the zip + utils.AddRicefiletoZip(statinfo.Name(), f, filePath, zipw, true, "infected") + + // Manually close the zip + zipw.Close() + + // Generate the request for the new file + newFile := strings.Split(req.URL.String(), "?") + fmt.Println(zipFilePath) + newRequest, _ := http.NewRequest("GET", "http://"+req.Host+newFile[0], nil) + + // Serve the new file (encrypted zip) + serveFile(zipFilePath, w, newRequest) + os.Remove(zipFilePath) + return + } else { + // Need its own rice.file otherwise it will miss the first chunck + fileForMime, _ := templateBox.Open(filePath) + defer fileForMime.Close() + // Fetching file's mimetype and giving it to the browser + if mimetype, _ := mimetype.DetectReader(fileForMime); mimetype.String() != "" { + w.Header().Set("Content-Type", mimetype.String()) + } else { + w.Header().Set("Content-Type", "application/octet-stream") + } + } + + // Manage gzip/zlib compression + outputWriter := w.(io.Writer) + + isCompressedReply := false + + if (cmd.Gzip) == true && req.Header.Get("Accept-Encoding") != "" { + encodings := utils.ParseCSV(req.Header.Get("Accept-Encoding")) + + for _, val := range encodings { + if val == "gzip" { + w.Header().Set("Content-Encoding", "gzip") + outputWriter = gzip.NewWriter(w) + + isCompressedReply = true + + break + } else if val == "deflate" { + w.Header().Set("Content-Encoding", "deflate") + outputWriter = zlib.NewWriter(w) + + isCompressedReply = true + + break + } + } + } + + if !isCompressedReply { + // Add Content-Length + w.Header().Set("Content-Length", strconv.FormatInt(statinfo.Size(), 10)) + } + + // Stream data out ! + buf := make([]byte, utils.Min(fsMaxbufsize, statinfo.Size())) + n := 0 + + for err == nil { + n, err = f.Read(buf) + buf = utils.SearchAndReplace(cmd.SearchAndReplaceMap, buf) + outputWriter.Write(buf[0:n]) + } + // Closes current compressors + switch outputWriter.(type) { + case *gzip.Writer: + outputWriter.(*gzip.Writer).Close() + case *zlib.Writer: + outputWriter.(*zlib.Writer).Close() + } + //f.Close() +} + +func listEmbeddedFiles() ([]string, []string) { + //Can't use variable, otherwise rice generate an error when rice embed-go .... + templateBox, err := rice.FindBox("../assets/embedded/") + if err != nil { + log.Fatal(err) + } + // Otherwise, generate folder content. + childrenDirTmp := list.New() + childrenFilesTmp := list.New() + err = templateBox.Walk("/", func(path string, info os.FileInfo, err error) error { + // don't add the root directory of embbedded files + if info.IsDir() && info.Name() == "embedded" || info.Name() == "" { + return nil + } + if info.IsDir() { + childrenDirTmp.PushBack(info.Name()) + } else { + childrenFilesTmp.PushBack(info.Name()) + } + return nil + }) + if err != nil { + log.Fatal(err) + } + + // And transfer the content to the final array structure + childrenDir := utils.CopyToArray(childrenDirTmp) + childrenFiles := utils.CopyToArray(childrenFilesTmp) + + return childrenDir, childrenFiles +} + +func handleEmbeddedDirectory(path string, w http.ResponseWriter, req *http.Request) { + if !cmd.DisableListing { + childrenDir, childrenFiles := listEmbeddedFiles() + + //Sort children_dir and children_files + sort.Slice(childrenDir, func(i, j int) bool { return childrenDir[i] < childrenDir[j] }) + + //Sort children_dir and children_files + sort.Slice(childrenFiles, func(i, j int) bool { return childrenFiles[i] < childrenFiles[j] }) + + data := utils.Dirlisting{Name: req.URL.Path, + ServerUA: serverUA, + ChildrenDir: childrenDir, + ChildrenFiles: childrenFiles, + Embedded: true} + err := renderTemplate(w, "directoryListing.tpl", data) + if err != nil { + fmt.Println(err) + } + } +} + +func readEmbeddedBinary(binary string) []byte { + //Can't use variable, otherwise rice generate an error when rice embed-go .... + templateBox, err := rice.FindBox("../assets/embedded/") + if err != nil { + log.Fatal(err) + } + binBytes, err := templateBox.Bytes(binary) + if err != nil { + fmt.Printf("[!] Error finding binary: %s\n", binary) + log.Fatal(err) + } + return binBytes +} diff --git a/src/controllers/runEmbedded_darwin.go.old b/src/controllers/runEmbedded_darwin.go.old new file mode 100644 index 0000000..2c4810f --- /dev/null +++ b/src/controllers/runEmbedded_darwin.go.old @@ -0,0 +1,15 @@ +package controllers + +func EmbeddedFiles() string { + returnValue := "" + _, childrenFiles := listEmbeddedFiles() + for _, value := range childrenFiles { + returnValue += value + "\n" + } + return returnValue +} + +// To avoid generating error on Linux +func RunEmbeddedBinary(binary string, arguments string) { + +} diff --git a/src/controllers/runEmbedded_linux.go.old b/src/controllers/runEmbedded_linux.go.old new file mode 100644 index 0000000..d0da29b --- /dev/null +++ b/src/controllers/runEmbedded_linux.go.old @@ -0,0 +1,16 @@ +package controllers + +// EmbeddedFiles list the embedded files +func EmbeddedFiles() string { + returnValue := "" + _, childrenFiles := listEmbeddedFiles() + for _, value := range childrenFiles { + returnValue += value + "\n" + } + return returnValue +} + +// RunEmbeddedBinary Do nothng, only to avoid generating error on Linux +func RunEmbeddedBinary(binary string, arguments string) { + +} diff --git a/src/controllers/runEmbedded_windows.go.old b/src/controllers/runEmbedded_windows.go.old new file mode 100644 index 0000000..93a0cb0 --- /dev/null +++ b/src/controllers/runEmbedded_windows.go.old @@ -0,0 +1,104 @@ +package controllers + +func checkFatalErr(err error) { + if err != nil { + panic(err) + } +} + +func EmbeddedFiles() string { + returnValue := "" + _, childrenFiles := listEmbeddedFiles() + for _, value := range childrenFiles { + returnValue += value + "\n" + } + return returnValue +} + +func RunEmbeddedBinary(binary string, arguments string) { + // feature not used. Disable it to avoid AV warning + /*binaryBytes := readEmbeddedBinary(binary) + argumentBinary := " " // trick use empty argument if no one is given + if arguments != "" { + argumentBinary = arguments + } + + shellcode, err := donut.ShellcodeFromBytes(bytes.NewBuffer(binaryBytes), &donut.DonutConfig{ + Arch: donut.X84, + Type: donut.DONUT_MODULE_EXE, + InstType: donut.DONUT_INSTANCE_PIC, + Entropy: donut.DONUT_ENTROPY_DEFAULT, + Compress: 1, + Format: 1, + Bypass: 3, + Parameters: argumentBinary, + }) + + bp, err := bananaphone.NewBananaPhone(bananaphone.AutoBananaPhoneMode) + checkFatalErr(err) + + alloc, err := bp.GetSysID("NtAllocateVirtualMemory") + checkFatalErr(err) + protect, err := bp.GetSysID("NtProtectVirtualMemory") + checkFatalErr(err) + createthread, err := bp.GetSysID("NtCreateThreadEx") + checkFatalErr(err) + + // create thread on shellcode + const ( + //special macro that says 'use this thread/process' when provided as a handle. + thisThread = uintptr(0xffffffffffffffff) + memCommit = uintptr(0x00001000) + memreserve = uintptr(0x00002000) + ) + + var baseA uintptr + regionsize := uintptr(len(shellcode.Bytes())) + _, err = bananaphone.Syscall( + alloc, //ntallocatevirtualmemory + thisThread, + uintptr(unsafe.Pointer(&baseA)), + 0, + uintptr(unsafe.Pointer(®ionsize)), + uintptr(memCommit|memreserve), + syscall.PAGE_READWRITE, + ) + checkFatalErr(err) + + bananaphone.WriteMemory(shellcode.Bytes(), baseA) + + var oldprotect uintptr + _, err = bananaphone.Syscall( + protect, //NtProtectVirtualMemory + thisThread, + uintptr(unsafe.Pointer(&baseA)), + uintptr(unsafe.Pointer(®ionsize)), + syscall.PAGE_EXECUTE_READ, + uintptr(unsafe.Pointer(&oldprotect)), + ) + checkFatalErr(err) + + var hhosthread uintptr + _, err = bananaphone.Syscall( + createthread, //NtCreateThreadEx + uintptr(unsafe.Pointer(&hhosthread)), //hthread + 0x1FFFFF, //desiredaccess + 0, //objattributes + thisThread, //processhandle + baseA, //lpstartaddress + 0, //lpparam + uintptr(0), //createsuspended + 0, //zerobits + 0, //sizeofstackcommit + 0, //sizeofstackreserve + 0, //lpbytesbuffer + ) + + _, err = syscall.WaitForSingleObject(syscall.Handle(hhosthread), 0xffffffff) + checkFatalErr(err) + + // bit of a hack because dunno how to wait for bananaphone background thread to complete... + for { + time.Sleep(1000000000) + }*/ +}