Added usage of ollvm ofuscation
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user