Merge branch 'serializingme-dev-hackingteam-v1' into dev-chaos

This commit is contained in:
Alberto Ortega 2015-07-11 11:50:17 +02:00
commit bc9971f06e
14 changed files with 303 additions and 4 deletions

View File

@ -4,9 +4,9 @@ LINK = i686-w64-mingw32-gcc
WINDRES = i686-w64-mingw32-windres
OBJ = Objects/MingW/main.o Objects/MingW/common.o Objects/MingW/utils.o Objects/MingW/debuggers.o Objects/MingW/sandboxie.o \
Objects/MingW/vbox.o Objects/MingW/gensandbox.o Objects/MingW/wine.o Objects/MingW/vmware.o \
Objects/MingW/qemu.o Objects/MingW/hooks.o Objects/MingW/cpu.o Objects/MingW/pafish_private.res
Objects/MingW/qemu.o Objects/MingW/hooks.o Objects/MingW/cpu.o Objects/MingW/cuckoo.o Objects/MingW/pafish_private.res
LINKOBJ = $(OBJ)
LIBS = -lwsock32 -liphlpapi -lsetupapi -lmpr -s
LIBS = -lwsock32 -liphlpapi -lsetupapi -lmpr -lole32 -lwbemuuid -loleaut32 -s
INCS =
BIN = Output/MingW/pafish.exe
CFLAGS = $(INCS) -Wall -Wextra -O0
@ -57,5 +57,8 @@ Objects/MingW/hooks.o: $(GLOBALDEPS) hooks.c
Objects/MingW/cpu.o: $(GLOBALDEPS) cpu.c
$(CC) -c cpu.c -o Objects/MingW/cpu.o $(CFLAGS)
Objects/MingW/cuckoo.o: $(GLOBALDEPS) cuckoo.c
$(CC) -c cuckoo.c -o Objects/MingW/cuckoo.o $(CFLAGS)
Objects/MingW/pafish_private.res: Objects/MingW/pafish_private.rc
$(WINDRES) Objects/MingW/pafish_private.rc --input-format=rc -o Objects/MingW/pafish_private.res -O coff

View File

@ -4,9 +4,9 @@ LINK = gcc.exe
WINDRES = windres.exe
OBJ = Objects/MingW/main.o Objects/MingW/common.o Objects/MingW/utils.o Objects/MingW/debuggers.o Objects/MingW/sandboxie.o \
Objects/MingW/vbox.o Objects/MingW/gensandbox.o Objects/MingW/wine.o Objects/MingW/vmware.o \
Objects/MingW/qemu.o Objects/MingW/hooks.o Objects/MingW/cpu.o Objects/MingW/pafish_private.res
Objects/MingW/qemu.o Objects/MingW/hooks.o Objects/MingW/cpu.o Objects/MingW/cuckoo.o Objects/MingW/pafish_private.res
LINKOBJ = $(OBJ)
LIBS = -lwsock32 -liphlpapi -lsetupapi -lmpr -s
LIBS = -lwsock32 -liphlpapi -lsetupapi -lmpr -lole32 -lwbemuuid -loleaut32 -s
INCS =
BIN = Output/MingW/pafish.exe
CFLAGS = $(INCS) -Wall -Wextra -O0
@ -57,5 +57,8 @@ Objects/MingW/hooks.o: $(GLOBALDEPS) hooks.c
Objects/MingW/cpu.o: $(GLOBALDEPS) cpu.c
$(CC) -c cpu.c -o Objects/MingW/cpu.o $(CFLAGS)
Objects/MingW/cuckoo.o: $(GLOBALDEPS) cuckoo.c
$(CC) -c cuckoo.c -o Objects/MingW/cuckoo.o $(CFLAGS)
Objects/MingW/pafish_private.res: Objects/MingW/pafish_private.rc
$(WINDRES) Objects/MingW/pafish_private.rc --input-format=rc -o Objects/MingW/pafish_private.res -O coff

64
pafish/cuckoo.c Normal file
View File

@ -0,0 +1,64 @@
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
#include "cuckoo.h"
/**
* Cuckoo Sandbox definitions.
*/
/**
* Extra space allocated with the hooks information structure.
*/
#define TLS_HOOK_INFO_RETADDR_SPACE 0x100
/**
* Hook informnation stored by Cuckoo at FS:[TLS_HOOK_INFO].
*/
struct hook_info {
unsigned int depth_count;
unsigned int hook_count;
unsigned int retaddr_esp;
unsigned int last_error;
unsigned int ret_last_error;
unsigned int eax;
unsigned int ecx;
unsigned int edx;
unsigned int ebx;
unsigned int esp;
unsigned int ebp;
unsigned int esi;
unsigned int edi;
};
/**
* Read the address of the hooks information in the TLS.
*/
struct hook_info *read_hook_info() {
void *result = NULL;
__asm__ volatile ("mov %%fs:0x44,%%eax" : "=a" (result));
return result;
}
/**
* Cuckoo stores the return addresses in a extra space allocated in conjunction
* with the hook information function. The only way to check if the structure
* is valid is to calculate what is the minimum and maximum value for the
* return address value location.
*/
int cuckoo_check_tls() {
struct hook_info *info = read_hook_info();
if (info == NULL) {
return FALSE;
}
unsigned int minimum = ((unsigned int) info + sizeof(struct hook_info));
unsigned int maximum = minimum + TLS_HOOK_INFO_RETADDR_SPACE;
return (info != NULL) && (info->retaddr_esp >= minimum && info->retaddr_esp <= maximum) ?
TRUE : FALSE;
}

8
pafish/cuckoo.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef CUCKOO_H
#define CUCKOO_H
int cuckoo_check_tls();
#endif

View File

@ -7,6 +7,7 @@
#include <stdint.h>
#include <stdio.h>
#include <ctype.h>
#include <wbemidl.h>
#include "types.h"
#include "gensandbox.h"

View File

@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <wbemidl.h>
#include "types.h"
#include "common.h"
@ -16,6 +17,7 @@
#include "vmware.h"
#include "qemu.h"
#include "cpu.h"
#include "cuckoo.h"
/*
Pafish (Paranoid fish)
@ -367,6 +369,14 @@ int main(void)
}
else print_not_traced();
printf("[*] Looking for VBox devices using WMI ... ");
if (vbox_wmi_devices() == TRUE) {
write_log("VirtualBox device identifiers traced using WMI");
print_traced();
write_trace("hi_virtualbox_wmi");
}
else print_not_traced();
/* VMware detection tricks */
printf("\n[-] VMware detection\n");
printf("[*] Scsi port 0,1,2 ->bus->target id->logical unit id-> 0 identifier ... ");
@ -417,6 +427,14 @@ int main(void)
}
else print_not_traced();
printf("[*] Looking for VMware serial number ... ");
if (vmware_wmi_serial() == TRUE) {
write_log("VMware serial number traced using WMI");
print_traced();
write_trace("hi_vmware_wmi");
}
else print_not_traced();
/* Qemu detection tricks */
printf("\n[-] Qemu detection\n");
printf("[*] Scsi port->bus->target id->logical unit id-> 0 identifier ... ");
@ -435,6 +453,16 @@ int main(void)
}
else print_not_traced();
/* Cuckoo detection tricks */
printf("\n[-] Cuckoo detection\n");
printf("[*] Looking in the TLS for the hooks information structure ... ");
if (cuckoo_check_tls() == TRUE) {
write_log("Cuckoo hooks information structure traced in the TLS");
print_traced();
write_trace("hi_cuckoo");
}
else print_not_traced();
printf("\n\n");
printf("[-] Feel free to RE me, check log file for more information.");

View File

@ -1,6 +1,7 @@
#include <windows.h>
#include <string.h>
#include <wbemidl.h>
#include "qemu.h"
#include "types.h"

View File

@ -8,6 +8,7 @@
#include <ctype.h>
#include <iphlpapi.h>
#include <tlhelp32.h>
#include <wbemidl.h>
#include "utils.h"
#include "types.h"
@ -177,3 +178,106 @@ int pafish_check_mac_vendor(char * mac_vendor) {
return res;
}
/**
* Initialise the WMI client that will connect to the local machine WMI
* namespace. It will return TRUE if the connection was successful, FALSE
* otherwise.
*/
int wmi_initialize(const wchar_t *query_namespace, IWbemServices **services) {
BSTR namespace;
IWbemLocator *locator = NULL;
int result;
HRESULT hresult = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hresult)) {
return FALSE;
}
hresult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
if (FAILED(hresult)) {
CoUninitialize();
return FALSE;
}
hresult = CoCreateInstance(&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
&IID_IWbemLocator, (LPVOID *) & locator);
if (FAILED(hresult)) {
CoUninitialize();
return FALSE;
}
namespace = SysAllocString(query_namespace);
// Connect to the namespace with the current user and obtain pointer
// services to make IWbemServices calls.
hresult = locator->lpVtbl->ConnectServer(locator, namespace, NULL, NULL, NULL, 0,
NULL, NULL, services);
result = FAILED(hresult) ? FALSE : TRUE;
SysFreeString(namespace);
locator->lpVtbl->Release(locator);
return result;
}
/**
* Execute the suplied WMI query and call the row checking function for each row returned.
*/
int wmi_check_query(IWbemServices *services, const wchar_t *language, const wchar_t *query,
wmi_check_row check_row) {
int status = FALSE;
IEnumWbemClassObject *queryrows = NULL;
IWbemClassObject * batchrows[10];
BSTR wmilang = SysAllocString(language);
BSTR wmiquery = SysAllocString(query);
// Execute the query.
HRESULT result = services->lpVtbl->ExecQuery(
services, wmilang, wmiquery, WBEM_FLAG_BIDIRECTIONAL, NULL, &queryrows);
if (!FAILED(result) && (queryrows != NULL)) {
ULONG index, count = 0;
result = WBEM_S_NO_ERROR;
while (WBEM_S_NO_ERROR == result && status == FALSE) {
// Retrieve 10 rows (instances) each time.
result = queryrows->lpVtbl->Next(queryrows, WBEM_INFINITE, 10,
batchrows, &count);
if (!SUCCEEDED(result)) {
continue;
}
for (index = 0; index < count && status == FALSE; index++) {
status = check_row(batchrows[index]);
batchrows[index]->lpVtbl->Release(batchrows[index]);
}
}
queryrows->lpVtbl->Release(queryrows);
}
SysFreeString(wmiquery);
SysFreeString(wmilang);
return status;
}
/**
* Cleanup WMI.
*/
void wmi_cleanup(IWbemServices *services) {
if (services != NULL) {
services->lpVtbl->Release(services);
}
CoUninitialize();
}

View File

@ -16,4 +16,17 @@ inline int pafish_exists_file(char * filename);
int pafish_check_mac_vendor(char * mac_vendor);
/**
* Prototype for the WMI caller implemented function for checking the
* WMI query results.
*/
typedef int (*wmi_check_row) (IWbemClassObject *);
int wmi_initialize(const wchar_t *, IWbemServices **);
int wmi_check_query(IWbemServices *, const wchar_t *, const wchar_t *,
wmi_check_row check_row);
void wmi_cleanup(IWbemServices *);
#endif

View File

@ -5,6 +5,7 @@
#include <string.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <wbemidl.h>
#include "vbox.h"
#include "utils.h"
@ -251,3 +252,36 @@ int vbox_processes(int writelogs) {
return res;
}
/**
* Check if the device identifier ("PCI\\VEN_80EE&DEV_CAFE") in the returned rows.
*/
int vbox_wmi_check_row(IWbemClassObject *row) {
CIMTYPE type = CIM_ILLEGAL;
VARIANT value;
HRESULT hresult = row->lpVtbl->Get(row, L"DeviceId", 0, &value, &type, 0);
if (FAILED(hresult) || V_VT(&value) == VT_NULL || type != CIM_STRING) {
return FALSE;
}
return (wcsstr(V_BSTR(&value), L"PCI\\VEN_80EE&DEV_CAFE") != NULL) ? TRUE : FALSE;
}
/**
* Check for devices VirtualBox devices using WMI.
*/
int vbox_wmi_devices() {
IWbemServices *services = NULL;
if (wmi_initialize(L"root\\cimv2", &services) != TRUE) {
return FALSE;
}
int result = wmi_check_query(services, L"WQL", L"SELECT DeviceId FROM Win32_PnPEntity",
&vbox_wmi_check_row);
wmi_cleanup(services);
return result;
}

View File

@ -25,4 +25,6 @@ int vbox_network_share();
int vbox_processes(int writelogs);
int vbox_wmi_devices();
#endif

View File

@ -2,6 +2,7 @@
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <wbemidl.h>
#include "vmware.h"
#include "types.h"
@ -74,3 +75,37 @@ int vmware_devices(int writelogs) {
}
return res;
}
/**
* Check the serial number ("VMware") in the returned rows.
*/
int vmware_wmi_check_row(IWbemClassObject *row) {
CIMTYPE type = CIM_ILLEGAL;
VARIANT value;
HRESULT hresult = row->lpVtbl->Get(row, L"SerialNumber", 0, &value, &type, 0);
if (FAILED(hresult) || V_VT(&value) == VT_NULL || type != CIM_STRING) {
return FALSE;
}
return (wcsstr(V_BSTR(&value), L"VMware") != NULL) ? TRUE : FALSE;
}
/**
* Check for the computer serial using WMI.
*/
int vmware_wmi_serial() {
IWbemServices *services = NULL;
if (wmi_initialize(L"root\\cimv2", &services) != TRUE) {
return FALSE;
}
int result = wmi_check_query(services, L"WQL", L"SELECT SerialNumber FROM Win32_Bios",
&vmware_wmi_check_row);
wmi_cleanup(services);
return result;
}

View File

@ -14,4 +14,6 @@ int vmware_mac();
int vmware_devices();
int vmware_wmi_serial();
#endif

View File

@ -1,5 +1,6 @@
#include <windows.h>
#include <wbemidl.h>
#include "wine.h"
#include "types.h"