Added usage of ollvm ofuscation

This commit is contained in:
Marmeus
2026-01-20 12:56:11 +00:00
parent bcca25fd5c
commit 9cd0157d46
3 changed files with 168 additions and 40 deletions
+4 -1
View File
@@ -18,9 +18,12 @@ RUN apt-get update && \
apt-get install -y --no-install-recommends \
apt-utils ca-certificates git zip make build-essential \
libssl-dev zlib1g-dev libbz2-dev xz-utils tk-dev libffi-dev \
liblzma-dev libsqlite3-dev protobuf-compiler mingw-w64 nasm && \
liblzma-dev libsqlite3-dev protobuf-compiler mingw-w64 nasm docker.io && \
rm -rf /var/lib/apt/lists/*
# Create the /tmp/converter directory For OLLVM
RUN mkdir -p /tmp/converter
# --- Reconfirma pip y setuptools actualizados (ya viene, pero por si acaso) ---
RUN python -m pip install --upgrade pip setuptools wheel
@@ -5,9 +5,14 @@ from mythic_container.PayloadBuilder import *
from mythic_container.MythicCommandBase import *
from mythic_container.MythicRPC import *
import json
from distutils.dir_util import copy_tree
from distutils.dir_util import copy_tree,remove_tree
import asyncio
import string, random, os, subprocess
def generate_random_string(length=100):
chars = string.ascii_letters + string.digits # a-zA-Z0-9
return ''.join(random.choices(chars, k=length))
class CazallaAgent(PayloadType):
name = "Cazalla"
@@ -43,6 +48,13 @@ class CazallaAgent(PayloadType):
choices=["console", "file"],
default_value="console"
),
BuildParameter(
name="ollvm_compilation",
parameter_type=BuildParameterType.ChooseOne,
description="OLLVM obfuscation",
choices=["0","1","2"],
default_value="0"
)
]
agent_path = pathlib.Path(".") / "cazalla"
agent_icon_path = agent_path / "agent_functions" / "cazalla.png"
@@ -51,7 +63,7 @@ class CazallaAgent(PayloadType):
build_steps = [
BuildStep(step_name="Gathering Files", step_description="Creating script payload"),
BuildStep(step_name="Applying configuration", step_description="Updating configuration constants"),
BuildStep(step_name="Compiling", step_description="Compiling with mingw"),
BuildStep(step_name="Compiling", step_description="Compiling the code"),
]
async def build(self) -> BuildResponse:
@@ -192,6 +204,7 @@ class CazallaAgent(PayloadType):
output_format = self.get_parameter("output")
debug_level = self.get_parameter("debug_level")
debug_output = self.get_parameter("debug_output")
ollvm_compilation = int(self.get_parameter("ollvm_compilation"))
config_path = f"{agent_build_path.name}/agent_code/cazalla/Config.h"
@@ -248,6 +261,8 @@ class CazallaAgent(PayloadType):
StepSuccess=True
))
# Local Compilation (without OLLVM)
if ollvm_compilation == 0:
# Determine build target and filename based on output format and debug settings
if debug_level == "none":
make_target = output_format
@@ -295,4 +310,106 @@ class CazallaAgent(PayloadType):
resp.payload = open(filename, "rb").read()
resp.build_message = f"Successfully built {output_filename}{debug_info}"
# OLLVM compilation in a Docker container
else:
container_name = generate_random_string(6)
docker_volume_folder = os.path.join("/", "tmp", "converter",container_name)
# Translate debug variables to Docker container variables
# DEBUG_LEVEL: none=0, errors=1, warnings=2, info=3, all=4
# DEBUG_OUTPUT: console=0, file=1
debug_level_docker = debug_level.replace("none", "0")
debug_level_docker = debug_level.replace("errors", "1")
debug_level_docker = debug_level.replace("warnings", "2")
debug_level_docker = debug_level.replace("info", "3")
debug_level_docker = debug_level.replace("all", "4")
debug_output_docker = debug_output.replace("console", "0")
debug_output_docker = debug_output.replace("file", "1")
# Ollvm parameters:
level_1_obfuscation_parameters = "-mllvm -fla -mllvm -bcf -mllvm -sub"
level_2_obfuscation_parameters = "-mllvm -sub -mllvm -sub_loop=3 -mllvm -split -mllvm -split_num=3 -mllvm -fla -mllvm -bcf -mllvm -bcf_loop=3 -mllvm -bcf_prob=40"
if ollvm_compilation == 1:
obfuscation_parameters = level_1_obfuscation_parameters
elif ollvm_compilation == 2:
obfuscation_parameters = level_2_obfuscation_parameters
# Compilation Command
compilation_command = f"clang -target x86_64-w64-mingw32 \
-fuse-ld=lld \
-DDEBUG_LEVEL={debug_level_docker} \
-DDEBUG_OUTPUT={debug_output_docker} \
{obfuscation_parameters} \
-L/usr/lib/gcc/x86_64-w64-mingw32/13-posix \
--sysroot=/usr/x86_64-w64-mingw32 \
/tmp/cazalla/*.c \
-o /tmp/cazalla/cazalla.exe \
-lntdll -lgdi32 -lws2_32 -lcrypt32 -liphlpapi -lshlwapi -lole32 -luser32 -ladvapi32 \
-lncrypt -lbcrypt -lversion -lnetapi32 -lwinhttp "
# Create Docker Containter ollvm16-builder
create_container_command = [
"docker", "run",
"--name", f"{container_name}",
"--volume", f"{docker_volume_folder}:/tmp/cazalla/",
"ollvm16-builder:latest",
"sh", "-c" ,compilation_command
]
# Delete Docker Container
delete_container_command = [
"docker",
f"fm {container_name}"
]
try:
# Move agent_build_path.name to docker_volume_folder
copy_tree(f"{agent_build_path.name}/agent_code/cazalla", docker_volume_folder)
# Create Docker Container
result = subprocess.run(create_container_command, capture_output=True, text=True, check=True)
if result.returncode != 0:
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
PayloadUUID=self.uuid,
StepName="Compiling",
StepStdout=f"Error creating Docker Container: {result.stderr}",
StepSuccess=False
))
resp.status = BuildStatus.Error
resp.build_message = f"Error creating Docker Container: {result.stderr}"
return resp
# Get the output from the Docker Container
resp.payload = open(f"{docker_volume_folder}/cazalla.exe", "rb").read()
resp.build_message = "Successfully built!"
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
PayloadUUID=self.uuid,
StepName="Compiling",
StepStdout=f"Successfully built cazalla.exe",
StepSuccess=True
))
# Delete Docker Container
delete_container_command = await asyncio.create_subprocess_shell(
" ".join(delete_container_command),
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
remove_tree(docker_volume_folder)
remove_tree(str(self.agent_path))
except Exception as e:
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
PayloadUUID=self.uuid,
StepName="Compiling",
StepStdout=f"Error creating Docker Container: {e}",
StepSuccess=False
))
resp.status = BuildStatus.Error
resp.build_message = f"Error creating Docker Container: {e}"
return resp
return resp
+9 -1
View File
@@ -67,7 +67,8 @@ This project was inspired by the article [How to build your own Mythic agent in
### Prerequisites
1. **Mythic Server** (v3.x or later) installed and running
2. Clone this repository
2. Build the [Docker Image ollvm](https://git.redteam/jesus.rodenas/ollvm-clang) in the Mythic server.
### Install Cazalla on Mythic
@@ -82,6 +83,13 @@ Or install from local directory:
./mythic-cli install folder /path/to/Cazalla
```
Then, modify the Mythic `docker-compose.yaml`, adding the following volumnes in the "cazalla" service:
```
- /var/run/docker.sock:/var/run/docker.sock
- /tmp/converter:/tmp/converter
```
### Build the Agent
Cazalla can be built directly from the Mythic UI: