joakim Posted July 5, 2011 Share Posted July 5, 2011 (edited) As part of another PoC tool, I've whipped together an au3 that uses NtSetInformationFile to update timestamps as available in the FILE_BASIC_INFORMATION structure. However, is it ok to post it? The tool follows similar logic as Timestomp that was written in 2005 by James C. Foster and Vincent Liu, and presented at BlackHat the same year; http://www.forensicswiki.org/wiki/Timestomp Joakim Last version added 16.08.11; http://www.mediafire.com/?77f3bw52oxc9v5g (including au3 and exe) Edited August 16, 2011 by joakim Link to comment Share on other sites More sharing options...
JohnOne Posted July 5, 2011 Share Posted July 5, 2011 If its not breaking forum rules. Yes. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
joakim Posted July 6, 2011 Author Share Posted July 6, 2011 Here it is; http://www.mediafire.com/file/o9s82nzom2lj47k/setmace.zip exe and au3. This tool follows similar logic as Timestomp that was written in 2005 by James C. Foster and Vincent Liu, and presented at BlackHat the same year (http://www.forensicswiki.org/wiki/Timestomp). It is a specialized tool for manipulating all 4 MAC(E) timestamps on files located on an NTFS volume (MAC values on FAT). It will update information in the $STANDARD_INFORMATION attribute of an MFT entry. Technically it is using the NtSetInformationFile function inside ntdll.dll with the FILE_BASIC_INFORMATION structure in FILE_INFORMATION_CLASS. As is explained on the referenced site above, the $FILE_NAME attribute cannot be set by api, but a workaround is explained. That workaround is implemented in this tool by the -x parameter. Ie, it will update wanted timestamp for file and then move the target file into a randomly named subdirectory before redoing the update of timestamp on the target file now located in a new directory. This way all 8 timestamps may be modified. Explanation of usage: Commandline with parameter order fixed and must be followed. - Parameter 1 is input/target file. Must be full path like "%CD%\file.ext" or "c:\folder\file.ext" - Parameter 2 is determining which timestamp to update. "-m" = LastWriteTime "-a" = LastAccessTime "-c" = CreationTime "-e" = ChangeTime (in $MFT) "-z" = all 4 - Parameter 3 is the wanted new timestamp. Format must be strictly followed like; "1954:20:49:22:39:44". That is YYYY:MM:DD:HH:MM:SS. Mseconds are always set to 0 to generate valid NTFS timestamps (1 second = 10.000). The smallest possible value is; "1601:01:01:00:00:00". However for that specific value mseconds is set to 1, so that the value is not ignored when writing it. It is written as UTC and thus will show up in explorer as interpreted by your timezone location. - Parameter 4 determines if $FILE_NAME attribute should be updated as well. "-n" will only update timestamps in $STANDARD_INFORMATION. "-x" will also update timestamps in $FILE_NAME as well as in $STANDARD_INFORMATION. A subdir is created where the file is moved into. Example; setmace.exe "%CD%\file.txt" -z "2000:01:01:00:00:00" -x Currently annoying message boxes is used to show error messages. That may change into logfile writing. Thanks to wraithdu for good hints from the NtQueryInformationFile implementation in; and Ascend4nt for the _WinTimeFunctions.au3 Source; expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Res_Comment=Same logic as timestomp written by James C. Foster and Vincent Liu in 2005. #AutoIt3Wrapper_Res_Description=Changes MACE timestamps as you like #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ;----------------------------- ;by Joakim ;----------------------------- #include "_WinTimeFunctions.au3";Ascend4nt #include <WinAPI.au3> #include <Date.au3> #include <FileConstants.au3> Opt("MustDeclareVars", 1) Global $file = "" Global $input2LocalFileTime = "" Global Const $FileBasicInformation = 4 Global Const $OBJ_CASE_INSENSITIVE = 0x00000040 Global Const $FILE_DIRECTORY_FILE = 0x00000002 Global Const $FILE_NON_DIRECTORY_FILE = 0x00000040 Global Const $FILE_RANDOM_ACCESS = 0x00000800 Global Const $tagFILEBASICINFO = "int64 CreationTime;int64 LastAccessTime;int64 LastWriteTime;int64 ChangeTime;ulong FileAttributes;" Global Const $tagIOSTATUSBLOCK = "dword Status;dword Information" Global Const $tagOBJECTATTRIBUTES = "ulong Length;hwnd RootDirectory;ptr ObjectName;ulong Attributes;ptr SecurityDescriptor;ptr SecurityQualityOfService" Global Const $tagUNICODESTRING = "ushort Length;ushort MaximumLength;ptr Buffer" _validate_parameters() _config_timestamp() If $input2LocalFileTime = -1 Then MsgBox(0,"Error","Timestamp generation went wrong") Exit EndIf ;divisible by 10,000,000 (one second) _set_mace($file) If $cmdline[4] = "-x" Then _fn_mace() Exit EndIf Exit Func _set_mace($file) Local $hNTDLL = DllOpen("ntdll.dll") Local $szName = DllStructCreate("wchar[260]") Local $sUS = DllStructCreate($tagUNICODESTRING) Local $sOA = DllStructCreate($tagOBJECTATTRIBUTES) Local $sISB = DllStructCreate($tagIOSTATUSBLOCK) Local $buffer = DllStructCreate("byte[16384]") Local $ret $file = "\??\" & $file DllStructSetData($szName, 1, $file) $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", Chr(0)) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", Chr(0)) DllStructSetData($sOA, "SecurityQualityOfService", Chr(0)) $ret = DllCall($hNTDLL, "int", "NtOpenFile", "hwnd*", "", "dword", $GENERIC_WRITE, "ptr", DllStructGetPtr($sOA), "ptr", DllStructGetPtr($sISB), _ "ulong", $FILE_SHARE_WRITE, "ulong", BitOR($FILE_NON_DIRECTORY_FILE, $FILE_RANDOM_ACCESS)) Local $hFile = $ret[1] Local $pFSO = DllStructGetPtr($buffer) Local $sFSO = DllStructCreate($tagFILEBASICINFO, $pFSO) Select Case $cmdline[2] = "-m" DllStructSetData($sFSO, "LastWriteTime",$input2LocalFileTime) Case $cmdline[2] = "-a" DllStructSetData($sFSO, "LastAccessTime",$input2LocalFileTime) Case $cmdline[2] = "-c" DllStructSetData($sFSO, "CreationTime",$input2LocalFileTime) Case $cmdline[2] = "-e" DllStructSetData($sFSO, "ChangeTime",$input2LocalFileTime) Case $cmdline[2] = "-z" DllStructSetData($sFSO, "LastWriteTime",$input2LocalFileTime) DllStructSetData($sFSO, "LastAccessTime",$input2LocalFileTime) DllStructSetData($sFSO, "CreationTime",$input2LocalFileTime) DllStructSetData($sFSO, "ChangeTime",$input2LocalFileTime) EndSelect $ret = DllCall($hNTDLL, "int", "NtSetInformationFile", "hwnd", $hFile, "ptr", DllStructGetPtr($sISB), "ptr", DllStructGetPtr($sFSO), _ "int", 16384, "int", $FileBasicInformation) $ret = DllCall($hNTDLL, "int", "NtClose", "hwnd", $hFile) DllClose($hNTDLL) EndFunc Func _config_timestamp() Local $timestamp_array Local $msec = 0 If StringLen($cmdline[3]) <> 19 Then MsgBox(0,"Error","Length of date/time is not correct: " & $cmdline[3]) Exit EndIf $timestamp_array = StringSplit(StringReplace($cmdline[3],'"',''),":") If $timestamp_array[0] <> 6 Then MsgBox(0,"Error","Not right date/time parameters supplied: " & $timestamp_array[0]) Exit EndIf For $dateinputs = 1 To $timestamp_array[0] If StringIsDigit($timestamp_array[$dateinputs]) <> 1 Then MsgBox(0,"Error","Not right date/time format supplied: " & $timestamp_array[$dateinputs]) Exit EndIf If StringLen($timestamp_array[$dateinputs]) <> 2 And StringLen($timestamp_array[$dateinputs]) <> 4 Then MsgBox(0,"Error","Not right date/time format supplied: " & $timestamp_array[$dateinputs]) Exit EndIf ContinueLoop Next If $cmdline[3] = "1601:01:01:00:00:00" Then $msec = 1 EndIf $input2LocalFileTime = _WinTime_SystemTimeToLocalFileTime($timestamp_array[1],$timestamp_array[2],$timestamp_array[3],$timestamp_array[4],$timestamp_array[5],$timestamp_array[6],$msec,-1) Return $input2LocalFileTime EndFunc Func _validate_parameters() If $cmdline[0] <> 4 Then MsgBox(0,"Error","Wrong number of parameters supplied: " & $cmdline[0]) Exit EndIf If $cmdline[2] <> "-m" And $cmdline[2] <> "-a" And $cmdline[2] <> "-c" And $cmdline[2] <> "-e" And $cmdline[2] <> "-z" Then MsgBox(0,"Error","Input parameter number 2 is unknown: " & $cmdline[2]) Exit EndIf If $cmdline[4] <> "-x" And $cmdline[4] <> "-n" Then MsgBox(0,"Error","Input parameter number 4 is unknown: " & $cmdline[4]) Exit EndIf If FileExists($cmdline[1]) <> 1 Then MsgBox(0,"Error","Target file does not exist: " & $cmdline[1]) Exit EndIf $file = $cmdline[1] EndFunc Func _fn_mace() Local $l, $rnddir Local $inptarget_lenght, $targetname, $output_folder, $newfile $rnddir = Random(99, 99999, 1) $l = 1 If StringInStr($cmdline[1],"\") Then $inptarget_lenght = StringLen($cmdline[1]) For $l = 1 To $inptarget_lenght If StringMid($cmdline[1],$inptarget_lenght-$l,1) = "\" Then ExitLoop Next $targetname = StringMid($cmdline[1],$inptarget_lenght-$l+1,$l) EndIf $output_folder = StringMid($cmdline[1],1,$inptarget_lenght-$l) & $rnddir & "\" FileMove($file,$output_folder,9) $newfile = $output_folder & $targetname _set_mace($newfile) EndFunc Func NT_SUCCESS($status) If 0 <= $status And $status <= 0x7FFFFFFF Then Return True Else Return False EndIf EndFunc Link to comment Share on other sites More sharing options...
joakim Posted August 16, 2011 Author Share Posted August 16, 2011 Added millisec as configurable in the timestamps; http://www.mediafire.com/?77f3bw52oxc9v5g (au3 and exe included) New sample use; setmace.exe "%CD%\file.txt" -z "2000:01:01:11:22:33:666" -x Link to comment Share on other sites More sharing options...
joakim Posted December 22, 2011 Author Share Posted December 22, 2011 There's a much improved version with for instance nanosecond, directories and 64-bit supported; http://reboot.pro/files/file/91-setmace/ (au3 and exe in same download) Link to comment Share on other sites More sharing options...
KaFu Posted December 22, 2011 Share Posted December 22, 2011 Access denied for non-members. Would it be possible if you provide a mirror? OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
joakim Posted December 22, 2011 Author Share Posted December 22, 2011 Oops, sorry. Here; http://www.mediafire.com/download.php?j7andfxikey2d2i Link to comment Share on other sites More sharing options...
KaFu Posted December 22, 2011 Share Posted December 22, 2011 Thanks a lot , I'll definitly will take a deeper look into this one. But on a second glance the site you're hosting on looks so interesting I think I'll sign-up anyhow ... OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
joakim Posted January 26, 2012 Author Share Posted January 26, 2012 Made a new version with complete $FILE_NAME attribute timestamp support by writing the timestamps directly to physical disk. That means an extra 4 (and 8 for files with long file names because of the extra attribute) can now also be set to the most accurate precision possible (nanosec). That stupid "move" trick is now history and directories are supported too. Some restriction are present on nt6.x which means the systemdrive of a running system (and the volume with the pagefile) can not be written to without the help of a kernel mode driver. Also added support for dumping all $STANDARD_INFORMATION and $FILE_NAME for a file/directory (4+4 or 4+8). Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now