diff options
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 292 |
1 files changed, 156 insertions, 136 deletions
@@ -584,142 +584,6 @@ fn main() { } ` -func main() { - filePath := flag.String("file", "", "path to binary shellcode file") - stubLang := flag.String("stub", "", "stub language to output (py, c, cwin, cs, rs)") - xorFlag := flag.Bool("xor", false, "enable single-byte xor encoding with random key") - rc4Flag := flag.Bool("rc4", false, "enable rc4 encryption with 16bit random key") - flag.Parse() - - if *filePath == "" { - flag.Usage() - os.Exit(1) - } - - data, err := os.ReadFile(*filePath) - if err != nil { - fmt.Fprintf(os.Stderr, "[err] failed to read file: %v\n", err) - os.Exit(1) - } - - origLen := len(data) - if origLen%16 != 0 { - fmt.Printf("[inf] shellcode size (%d bytes) is not a multiple of 16, will pad with nullbytes\n", origLen) - pad := 16 - (origLen % 16) - data = append(data, make([]byte, pad)...) - } - - if *xorFlag && *rc4Flag { - fmt.Fprintf(os.Stderr, "[err] cannot use both xor and rc4\n") - os.Exit(1) - } - - var rc4Key []byte - var xorKey byte = 0 - - if *xorFlag { - key := make([]byte, 1) - _, err := rand.Read(key) - if err != nil { - fmt.Fprintf(os.Stderr, "[err] failed to generate xor key: %v\n", err) - os.Exit(1) - } - xorKey = key[0] - fmt.Printf("[inf] using xor key: 0x%02x\n", xorKey) - - for i := 0; i < len(data); i++ { - data[i] ^= xorKey - } - } else if *rc4Flag { - var err error - rc4Key, err = generateRC4Key() - if err != nil { - fmt.Fprintf(os.Stderr, "[err] failed to generate rc4 key: %v\n", err) - os.Exit(1) - } - fmt.Printf("[inf] using rc4 key: %s\n", string(rc4Key)) - data, err = rc4Encrypt(data, rc4Key) - if err != nil { - fmt.Fprintf(os.Stderr, "[err] rc4 encryption failed: %v\n", err) - os.Exit(1) - } - } - - var uuids []string - for i := 0; i < len(data); i += 16 { - chunk := data[i : i+16] - uuid := formatAsUUID(chunk) - uuids = append(uuids, uuid) - fmt.Println(uuid) - } - - if *stubLang != "" { - var stubContent string - var fileName string - - switch *stubLang { - case "py": - stubContent = pythonStub - fileName = "stub.py" - case "c": - stubContent = cStub - fileName = "stub.c" - case "cwin": - stubContent = cWinStub - fileName = "stub.c" - case "cs": - stubContent = csharpStub - fileName = "stub.cs" - case "rs": - stubContent = rustStub - baseDir := "stub" - srcDir := filepath.Join(baseDir, "src") - err = os.MkdirAll(srcDir, 0755) - if err != nil { - fmt.Fprintf(os.Stderr, "[err] failed to create directories: %v\n", err) - os.Exit(1) - } - - cargoToml := `[package] -name = "stub" -version = "0.0.1" -edition = "2024" - -[dependencies] -uuid = "1.3" -libc = "0.2" - -[target.'cfg(windows)'.dependencies] -winapi = { version = "0.3", features = ["memoryapi", "winnt"] } -` - err = os.WriteFile(filepath.Join(baseDir, "Cargo.toml"), []byte(cargoToml), 0644) - if err != nil { - fmt.Fprintf(os.Stderr, "[err] failed to write Cargo.toml: %v\n", err) - os.Exit(1) - } - - fileName = filepath.Join(srcDir, "main.rs") - err = renderTemplateToFile(stubContent, uuids, origLen, xorKey, string(rc4Key), fileName) - if err != nil { - fmt.Fprintf(os.Stderr, "[err] failed to write stub.rs: %v\n", err) - os.Exit(1) - } - - fmt.Printf("[inf] rust stub written to %s\n", fileName) - default: - fmt.Fprintf(os.Stderr, "[err] unsupported stub language\n") - os.Exit(1) - } - - err := renderTemplateToFile(stubContent, uuids, origLen, xorKey, string(rc4Key), fileName) - if err != nil { - fmt.Fprintf(os.Stderr, "[err] failed to write stub: %v\n", err) - os.Exit(1) - } - fmt.Printf("[inf] stub written to %s\n", fileName) - } -} - func generateRC4Key() ([]byte, error) { const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" key := make([]byte, 16) @@ -791,3 +655,159 @@ func renderTemplateToFile(tmplStr string, uuids []string, origLen int, xorKey by "RC4Key": string(rc4Key), }) } + +func init() { + const usageHeader = ` +offensive security utility that encodes arbitrary binary shellcode into UUID strings, generating C and Python stubs to decode and execute the shellcode at runtime + +author: heqnx - https://heqnx.com + +` + flag.Usage = func() { + fmt.Fprint(os.Stderr, usageHeader) + fmt.Fprintf(os.Stderr, "usage of %s:\n", os.Args[0]) + flag.PrintDefaults() + } + flag.CommandLine.SetOutput(os.Stderr) +} + +func main() { + filePath := flag.String("file", "", "path to binary shellcode file") + stubLang := flag.String("stub", "", "stub language to output (py, c, cwin, cs, rs)") + xorFlag := flag.Bool("xor", false, "enable single-byte xor encoding with random key") + rc4Flag := flag.Bool("rc4", false, "enable rc4 encryption with 16bit random key") + flag.Parse() + + if flag.NFlag() == 0 && flag.NArg() == 0 { + flag.Usage() + os.Exit(1) + } + + if *filePath == "" { + flag.Usage() + os.Exit(1) + } + + data, err := os.ReadFile(*filePath) + if err != nil { + fmt.Fprintf(os.Stderr, "[err] failed to read file: %v\n", err) + os.Exit(1) + } + + origLen := len(data) + if origLen%16 != 0 { + fmt.Printf("[inf] shellcode size (%d bytes) is not a multiple of 16, will pad with nullbytes\n", origLen) + pad := 16 - (origLen % 16) + data = append(data, make([]byte, pad)...) + } + + if *xorFlag && *rc4Flag { + fmt.Fprintf(os.Stderr, "[err] cannot use both xor and rc4\n") + os.Exit(1) + } + + var rc4Key []byte + var xorKey byte = 0 + + if *xorFlag { + key := make([]byte, 1) + _, err := rand.Read(key) + if err != nil { + fmt.Fprintf(os.Stderr, "[err] failed to generate xor key: %v\n", err) + os.Exit(1) + } + xorKey = key[0] + fmt.Printf("[inf] using xor key: 0x%02x\n", xorKey) + + for i := 0; i < len(data); i++ { + data[i] ^= xorKey + } + } else if *rc4Flag { + var err error + rc4Key, err = generateRC4Key() + if err != nil { + fmt.Fprintf(os.Stderr, "[err] failed to generate rc4 key: %v\n", err) + os.Exit(1) + } + fmt.Printf("[inf] using rc4 key: %s\n", string(rc4Key)) + data, err = rc4Encrypt(data, rc4Key) + if err != nil { + fmt.Fprintf(os.Stderr, "[err] rc4 encryption failed: %v\n", err) + os.Exit(1) + } + } + + var uuids []string + for i := 0; i < len(data); i += 16 { + chunk := data[i : i+16] + uuid := formatAsUUID(chunk) + uuids = append(uuids, uuid) + fmt.Println(uuid) + } + + if *stubLang != "" { + var stubContent string + var fileName string + + switch *stubLang { + case "py": + stubContent = pythonStub + fileName = "stub.py" + case "c": + stubContent = cStub + fileName = "stub.c" + case "cwin": + stubContent = cWinStub + fileName = "stub.c" + case "cs": + stubContent = csharpStub + fileName = "stub.cs" + case "rs": + stubContent = rustStub + baseDir := "stub" + srcDir := filepath.Join(baseDir, "src") + err = os.MkdirAll(srcDir, 0755) + if err != nil { + fmt.Fprintf(os.Stderr, "[err] failed to create directories: %v\n", err) + os.Exit(1) + } + + cargoToml := `[package] +name = "stub" +version = "0.0.1" +edition = "2024" + +[dependencies] +uuid = "1.3" +libc = "0.2" + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["memoryapi", "winnt"] } +` + err = os.WriteFile(filepath.Join(baseDir, "Cargo.toml"), []byte(cargoToml), 0644) + if err != nil { + fmt.Fprintf(os.Stderr, "[err] failed to write Cargo.toml: %v\n", err) + os.Exit(1) + } + + fileName = filepath.Join(srcDir, "main.rs") + err = renderTemplateToFile(stubContent, uuids, origLen, xorKey, string(rc4Key), fileName) + if err != nil { + fmt.Fprintf(os.Stderr, "[err] failed to write stub.rs: %v\n", err) + os.Exit(1) + } + + fmt.Printf("[inf] rust stub written to %s\n", fileName) + default: + fmt.Fprintf(os.Stderr, "[err] unsupported stub language\n") + os.Exit(1) + } + + err := renderTemplateToFile(stubContent, uuids, origLen, xorKey, string(rc4Key), fileName) + if err != nil { + fmt.Fprintf(os.Stderr, "[err] failed to write stub: %v\n", err) + os.Exit(1) + } + fmt.Printf("[inf] stub written to %s\n", fileName) + } +}
\ No newline at end of file |