Skip to content

Commit

Permalink
Filedelete plugin cleanup (#208)
Browse files Browse the repository at this point in the history
  • Loading branch information
tklengyel authored Aug 31, 2016
2 parents cf9f0ee + 96f5657 commit 850d4d2
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 40 deletions.
27 changes: 15 additions & 12 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -329,20 +329,23 @@ AC_CHECK_LIB([xentoollog], [xtl_logger_destroy])
if test x$plugin_filedelete = xyes; then
# Check for Python
AM_PATH_PYTHON([2.7])
if test "xPYTHON" != "x"; then
if test "x$PYTHON" != "x"; then
AC_DEFINE_UNQUOTED(PYTHON, "$PYTHON", "Python found")
AX_PYTHON_MODULE([pyvmi])

if test "x$HAVE_PYMOD_PYVMI" = "xyes"; then
AC_PATH_PROG(VOLATILITY, vol.py)

if test "x$VOLATILITY" != "x"; then
AC_DEFINE_UNQUOTED(VOLATILITY, "$VOLATILITY", "Volatility vol.py found")
else
plugin_filedelete="yes (log only)"
fi
else
plugin_filedelete="yes (log only)"
fi
else
AC_ERROR([Python was not found on the system!])
fi

AX_PYTHON_MODULE([pyvmi], [fatal])

AC_PATH_PROG(VOLATILITY, vol.py)

if test "x$VOLATILITY" != "x"; then
AC_DEFINE_UNQUOTED(VOLATILITY, "$VOLATILITY", "Volatility vol.py found")
else
AC_ERROR([** Volatility vol.py was not found in your PATH!])
plugin_filedelete="yes (log only)"
fi
fi

Expand Down
4 changes: 3 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,11 @@ int main(int argc, char** argv) {
"\t -I <injection thread> The ThreadID in the process to hijack for injection (requires -i)\n"
"\t -e <inject_exe> The executable to start with injection\n"
"\t -t <timeout> Timeout (in seconds)\n"
"\t -D <file dump folder> Folder where extracted files should be stored at\n"
"\t -o <format> Output format (default or csv)\n"
"\t -x <plugin> Don't activate the specified plugin\n"
#ifdef VOLATILITY
"\t -D <file dump folder> Folder where extracted files should be stored at\n"
#endif
#ifdef DRAKVUF_DEBUG
"\t -v Turn on verbose (debug) output\n"
#endif
Expand Down
77 changes: 50 additions & 27 deletions src/plugins/filedelete/filedelete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
#include "filedelete.h"

#define FILE_DISPOSITION_INFORMATION 13
#define WIN7_TYPEINDEX_LAST 44

enum offset {
FILE_OBJECT_FILENAME,
Expand All @@ -129,7 +130,7 @@ static const char *offset_names[__OFFSET_MAX][2] = {
[UNICODE_STRING_BUFFER] = {"_UNICODE_STRING", "Buffer" },
};

#define WIN7_TYPEINDEX_LAST 44
#ifdef VOLATILITY
#define VOL_DUMPFILES "%s %s -l vmi://domid/%u --profile=%s -Q 0x%lx -D %s -n dumpfiles 2>&1"
#define PROFILE32 "Win7SP1x86"
#define PROFILE64 "Win7SP1x64"
Expand All @@ -152,6 +153,7 @@ void volatility_extract_file(filedelete *f, addr_t file_object) {
g_spawn_command_line_sync(command, NULL, NULL, NULL, NULL);
g_free(command);
}
#endif

/*
* The approach where the system process list es enumerated looking for
Expand Down Expand Up @@ -194,17 +196,18 @@ static void grab_file_by_handle(filedelete *f, drakvuf_t drakvuf,
return;

addr_t file = obj + f->offsets[OBJECT_HEADER_BODY];
addr_t file_pa = vmi_pagetable_lookup(vmi, info->regs->cr3, file);
addr_t filename = file + f->offsets[FILE_OBJECT_FILENAME];

uint16_t length = 0;
addr_t buffer = 0;

ctx.addr = filename + f->offsets[UNICODE_STRING_BUFFER];
vmi_read_addr(vmi, &ctx, &buffer);
if ( VMI_FAILURE == vmi_read_addr(vmi, &ctx, &buffer) )
return;

ctx.addr = filename + f->offsets[UNICODE_STRING_LENGTH];
vmi_read_16(vmi, &ctx, &length);
if ( VMI_FAILURE == vmi_read_16(vmi, &ctx, &length) )
return;

if (length && buffer) {
unicode_string_t str;
Expand All @@ -213,13 +216,13 @@ static void grab_file_by_handle(filedelete *f, drakvuf_t drakvuf,
str.contents = (unsigned char *)g_malloc0(length);

ctx.addr = buffer;
vmi_read(vmi, &ctx, str.contents, length);
if ( length != vmi_read(vmi, &ctx, str.contents, length) )
return;

unicode_string_t str2 = { .contents = NULL };
status_t rc = vmi_convert_str_encoding(&str, &str2, "UTF-8");
if (rc == VMI_SUCCESS) {
char *procname;
procname = drakvuf_get_current_process_name(drakvuf, info->vcpu, info->regs);
if ( vmi_convert_str_encoding(&str, &str2, "UTF-8") == VMI_SUCCESS )
{
char *procname = drakvuf_get_current_process_name(drakvuf, info->vcpu, info->regs);
switch(f->format) {
case OUTPUT_CSV:
printf("filedelete,%" PRIu32 ",0x%" PRIx64 ",%s,\"%s\"\n",
Expand All @@ -232,16 +235,34 @@ static void grab_file_by_handle(filedelete *f, drakvuf_t drakvuf,
break;
};

if (f->dump_folder)
#ifdef VOLATILITY
if (f->dump_folder) {
addr_t file_pa = vmi_pagetable_lookup(vmi, info->regs->cr3, file);
volatility_extract_file(f, file_pa);
}
#endif

free(procname);
free(str2.contents);
}
free(str.contents);
g_free(str.contents);
}
}

/*
* NTSTATUS ZwSetInformationFile(
* HANDLE FileHandle,
* PIO_STATUS_BLOCK IoStatusBlock,
* PVOID FileInformation,
* ULONG Length,
* FILE_INFORMATION_CLASS FileInformationClass
* );
*
* When FileInformationClass is FileDispositionInformation then FileInformation points to
* struct _FILE_DISPOSITION_INFORMATION {
* BOOLEAN DeleteFile;
* }
*/
static event_response_t setinformation(drakvuf_t drakvuf, drakvuf_trap_info_t *info) {

filedelete *f = (filedelete *)info->trap->data;
Expand All @@ -251,37 +272,39 @@ static event_response_t setinformation(drakvuf_t drakvuf, drakvuf_trap_info_t *i
ctx.translate_mechanism = VMI_TM_PROCESS_DTB;
ctx.dtb = info->regs->cr3;

uint32_t fileinfoclass = 0;
reg_t handle = 0, fileinfo = 0, length = 0;
uint32_t fileinfoclass;
reg_t handle, fileinfo;

if (f->pm == VMI_PM_IA32E) {
handle = info->regs->rcx;
fileinfo = info->regs->r8;
length = info->regs->r9;

ctx.addr = info->regs->rsp + 5 * sizeof(addr_t); // addr of fileinfoclass
vmi_read_32(vmi, &ctx, &fileinfoclass);
if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, &fileinfoclass) )
goto done;
} else {
ctx.addr = info->regs->rsp + sizeof(uint32_t);
vmi_read_32(vmi, &ctx, (uint32_t*) &handle);
if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*) &handle) )
goto done;
ctx.addr += 2 * sizeof(uint32_t);
if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*) &fileinfo) )
goto done;
ctx.addr += 2 * sizeof(uint32_t);
vmi_read_32(vmi, &ctx, (uint32_t*) &fileinfo);
ctx.addr += sizeof(uint32_t);
vmi_read_32(vmi, &ctx, (uint32_t*) &length);
ctx.addr += sizeof(uint32_t);
vmi_read_32(vmi, &ctx, &fileinfoclass);
if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, &fileinfoclass) )
goto done;
}

if (fileinfoclass == FILE_DISPOSITION_INFORMATION && length == 1) {
uint8_t del = 0;
if (fileinfoclass == FILE_DISPOSITION_INFORMATION) {
uint8_t del;
ctx.addr = fileinfo;
vmi_read_8(vmi, &ctx, &del);
if (del) {
//printf("DELETE FILE _FILE_OBJECT Handle: 0x%lx.\n", handle);
if ( VMI_FAILURE == vmi_read_8(vmi, &ctx, &del) )
goto done;

if (del)
grab_file_by_handle(f, drakvuf, vmi, info, handle);
}
}

done:
drakvuf_release_vmi(drakvuf);
return 0;
}
Expand Down

0 comments on commit 850d4d2

Please sign in to comment.