Skip to content

Commit

Permalink
Remove embedded files feature
Browse files Browse the repository at this point in the history
  • Loading branch information
nodauf committed May 22, 2024
1 parent b1c12c7 commit e43b54a
Show file tree
Hide file tree
Showing 4 changed files with 365 additions and 0 deletions.
230 changes: 230 additions & 0 deletions src/controllers/embeddedFiles.go.old
Original file line number Diff line number Diff line change
@@ -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
}
15 changes: 15 additions & 0 deletions src/controllers/runEmbedded_darwin.go.old
Original file line number Diff line number Diff line change
@@ -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) {

}
16 changes: 16 additions & 0 deletions src/controllers/runEmbedded_linux.go.old
Original file line number Diff line number Diff line change
@@ -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) {

}
104 changes: 104 additions & 0 deletions src/controllers/runEmbedded_windows.go.old
Original file line number Diff line number Diff line change
@@ -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(&regionsize)),
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(&regionsize)),
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)
}*/
}

0 comments on commit e43b54a

Please sign in to comment.