[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fuP0O_H1P9-CejsA5gEfDpFRSQyBxdjq7EjFHcvE-cFs":3},{"id":4,"question":5,"answer":6,"answerHtml":7,"slug":8,"keywords":9,"article":10,"status":34,"aiModel":39,"aiConfidence":39,"updatedAt":52,"createdAt":52,"_status":51},832,"What is PowerForensics and how can it be used to recover deleted files?","PowerForensics is a PowerShell module for forensic analysis, including file recovery. You can import it and run `Get-ForensicFileRecord | Where {$_.Deleted -eq $true} | Select FullName` to list recoverable files, then use the `CopyFile` method on a specific record to restore it. This tool is demonstrated in [Penetration Techniques - File Recovery and Deletion in Windows Systems](\u002Fnews\u002Fpenetration-techniques-file-recovery-and-deletion-in-windows-systems).","\u003Cp>PowerForensics is a PowerShell module for forensic analysis, including file recovery. You can import it and run `Get-ForensicFileRecord | Where {$_.Deleted -eq $true} | Select FullName` to list recoverable files, then use the `CopyFile` method on a specific record to restore it. This tool is demonstrated in [Penetration Techniques - File Recovery and Deletion in Windows Systems](\u002Fnews\u002Fpenetration-techniques-file-recovery-and-deletion-in-windows-systems).\u003C\u002Fp>\u003Cp>\u003Ca href=\"\u002Fnews\u002Fpenetration-techniques-file-recovery-and-deletion-in-windows-systems\">Read the related One Day Sec article\u003C\u002Fa>\u003C\u002Fp>","what-is-powerforensics-and-how-can-it-be-used-to-recover-deleted-files-1777481539895","PowerForensics, PowerShell, file recovery, Get-ForensicFileRecord",{"id":11,"title":12,"slug":13,"description":14,"content":15,"contentHtml":30,"cover":31,"author":32,"views":19,"readingTime":33,"status":34,"publishedAt":35,"seo":36,"tags":41,"qaPairs":42,"meta":48,"updatedAt":49,"createdAt":50,"_status":51},204,"Penetration Techniques - File Recovery and Deletion in Windows Systems","penetration-techniques-file-recovery-and-deletion-in-windows-systems","Learn how to recover and securely delete files in Windows systems using NTFS principles, PowerForensics, and SDelete for penetration testing.",{"root":16},{"type":17,"format":18,"indent":19,"version":20,"children":21,"direction":29},"root","",0,1,[22],{"type":23,"format":18,"indent":19,"version":20,"children":24,"direction":29},"paragraph",[25],{"mode":26,"text":27,"type":28,"style":18,"detail":19,"format":19,"version":20},"normal","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>In penetration testing, file recovery and deletion are like spear and shield.\u003C\u002Fp>\u003Cp>File recovery refers to restoring deleted files on the target system, while file deletion means removing tools used on the target system to prevent recovery.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following topics:\u003C\u002Fp>\u003Cul>\u003Cli>Principles of file deletion\u003C\u002Fli>\u003Cli>Principles of file recovery\u003C\u002Fli>\u003Cli>Using PowerForensics for file recovery\u003C\u002Fli>\u003Cli>Using SDelete for file deletion\u003C\u002Fli>\u003Cli>Can PowerForensics recover files after deletion with SDelete?\u003C\u002Fli>\u003Cli>Preventing file recovery through file overwriting\u003C\u002Fli>\u003Cli>Enumerate all processes, search for handles to specific files, release those handles to free file locks, and achieve file deletion\u003C\u002Fli>\u003Cli>Program implementation details and open-source code\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Principles of File Deletion and Recovery\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>References:\u003C\u002Fp>\u003Cp>http:\u002F\u002Fwww.ntfs.com\u002Fntfs_basics.htm\u003C\u002Fp>\u003Ch3>Basic Concepts\u003C\u002Fh3>\u003Cp>Most Windows file systems use NTFS (New Technology File System) technology\u003C\u002Fp>\u003Cp>Each file in NTFS corresponds to a Master File Table (MFT)\u003C\u002Fp>\u003Cp>The MFT serves as a file index, storing file attributes\u003C\u002Fp>\u003Ch4>Intuitive understanding of file deletion:\u003C\u002Fh4>\u003Cp>Only modifies the MFT (i.e., file attributes), without altering the deleted file's content\u003C\u002Fp>\u003Ch4>Intuitive understanding of file recovery:\u003C\u002Fh4>\u003Cp>Restoring the file's MFT is sufficient\u003C\u002Fp>\u003Ch3>Simple Test\u003C\u002Fh3>\u003Cp>Create a new file test.txt and write the content 0123456789\u003C\u002Fp>\u003Cp>Using tool: WinHex\u003C\u002Fp>\u003Cp>Download link:\u003C\u002Fp>\u003Cp>http:\u002F\u002Fwww.x-ways.net\u002Fwinhex\u002F\u003C\u002Fp>\u003Cp>Select Tools -&gt; Open Disk, choose the drive letter\u003C\u002Fp>\u003Cp>Locate the file test.txt, right-click -&gt; Navigation -&gt; Seek FILE Record\u003C\u002Fp>\u003Cp>View the MFT information of test.txt, as shown below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017247577_0_41d915c63d.jpeg\">\u003C\u002Fp>\u003Cp>The structure of MFT is as follows\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017270145_1_8dc725765f.jpeg\">\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Screenshot taken from http:\u002F\u002Fwww.blogfshare.com\u002Fdetail-ntfs-filesys.html\u003C\u002Fp>\u003Cp>Next, delete the file test.txt and empty the files in the Recycle Bin\u003C\u002Fp>\u003Cp>Use WinHex to view the hard disk content again, close the current drive, reselect Tools -&gt; Open Disk, choose the drive letter\u003C\u002Fp>\u003Cp>A dialog box prompts, select to update the snapshot, as shown below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017301566_2_c3f5dacc62.jpeg\">\u003C\u002Fp>\u003Cp>Review the MFT structure again, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017325401_3_76130460ce.jpeg\">\u003C\u002Fp>\u003Cp>Comparison reveals the following differences:\u003C\u002Fp>\u003Cul>\u003Cli>Offset 0x08\u003C\u002Fli>\u003Cli>Offset 0x10, value increased by 1\u003C\u002Fli>\u003Cli>Offset 0x16, changed from 1 to 0\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Select 'Recover File' in the WinHex interface to successfully restore the file\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Successful recovery depends on the file not being overwritten\u003C\u002Fp>\u003Cp>In summary, the principle of file recovery can be simply understood as follows:\u003C\u002Fp>\u003Cp>\u003Cstrong>File deletion only modifies the file's MFT; if the file content has not been overwritten, the file can be recovered\u003C\u002Fstrong>\u003C\u002Fp>\u003Ch2>0x03 Using PowerForensics for File Recovery\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>There are various file recovery software tools; here is one that uses PowerShell for file recovery: PowerForensics\u003C\u002Fp>\u003Cp>Project address:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002FInvoke-IR\u002FPowerForensics\u002F\u003C\u002Fp>\u003Cp>Download URL:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002FInvoke-IR\u002FPowerForensics\u002Freleases\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>PowerForensicsv2.zip corresponds to PowerShell v2, the default version for Win7 and Server 2008\u003C\u002Fp>\u003Cp>For tool usage, refer directly to xpn's blog:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fblog.xpnsec.com\u002Foffensive-forensics\u002F\u003C\u002Fp>\u003Cp>To obtain a list of all recoverable files, use the following PowerShell command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>powershell -executionpolicy bypass\u003Cbr>import-module .\\PowerForensicsv2.psd1\u003Cbr>Get-ForensicFileRecord | Where {$_.Deleted -eq $true} | Select FullName\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>To recover a specific file C:\\test.txt and save it as recovered.txt:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>$file = Get-ForensicFileRecord | Where {$_.FullName -eq \"C:\\test.txt\"}\u003Cbr>$file.CopyFile(\"recovered.txt\")\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch2>0x04 Preventing File Recovery\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Using the tool SDelete\u003C\u002Fh3>\u003Cp>Download link:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fsysinternals\u002Fdownloads\u002Fsdelete\u003C\u002Fp>\u003Cp>The deletion command is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>sdelete64.exe -accepteula C:\\test.txt\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>2. Implementation via C++\u003C\u002Fh3>\u003Cp>Based on the principle analysis in 0x01, we know that overwriting the original file can prevent its recovery.\u003C\u002Fp>\u003Ch4>The simplest implementation approach:\u003C\u002Fh4>\u003Cp>Modify the content of the original file by filling it with random strings, then delete the file.\u003C\u002Fp>\u003Cp>I wrote a simple test code that first fills the file to be deleted with zeros, then deletes the file. Even if the file is recovered, its content will be all zeros. The reference C code is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>#include \u003Cwindows.h>\u003Cbr>int main(int argc, char *argv[])\u003Cbr>{\u003Cbr>\tif (argc != 2)\u003Cbr>\t{\u003Cbr>\t\tprintf(\"\\nOverwrite the file,avoid being restored\\n\\n\");\u003Cbr>\t\tprintf(\"Usage:\\n\");\u003Cbr>\t\tprintf(\"%s \u003Cfile path=\"\">\\n\",argv[0]);\u003Cbr>\t\treturn 0;\u003Cbr>\t}\u003Cbr>\tprintf(\"[*]Try to overwrite file &lt;%s&gt;   \", argv[1]);\u003Cbr>\tFILE* fp;\u003Cbr>\tint err = fopen_s(&amp;fp, argv[1], \"rb+\");\u003Cbr>\tif (err != 0)\u003Cbr>\t{\u003Cbr>\t\tprintf(\"\\n[!]Openfile error!\");\u003Cbr>\t\treturn 0;\u003Cbr>\t}\u003Cbr>\tfseek(fp, 0, SEEK_END);\u003Cbr>\tint len = ftell(fp);\u003Cbr>\tchar *buf = new char[len];\u003Cbr>\tmemset(buf, 0, len);\u003Cbr>\tfclose(fp);\u003Cbr>\terr = fopen_s(&amp;fp, argv[1], \"wb+\");\u003Cbr>\tif (err != 0)\u003Cbr>\t{\u003Cbr>\t\tprintf(\"\\n[!]Openfile error!\");\u003Cbr>\t\treturn 0;\u003Cbr>\t}\u003Cbr>\tfwrite(buf, len, 1, fp);\u003Cbr>\tfclose(fp);\u003Cbr>\tprintf(\"done\\n\");\u003Cbr>\u003Cbr>\tprintf(\"[*]Try to delete file   &lt;%s&gt;   \", argv[1]);\u003Cbr>\tif(DeleteFile(argv[1])!=0)\u003Cbr>\t\tprintf(\"done\\n\");\u003Cbr>\telse\u003Cbr>\t\tprintf(\"error\\n\");\u003Cbr>\treturn 0;\u003Cbr>}\u003C\u002Ffile>\u003C\u002Fwindows.h>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch2>0x05 Release File Lock\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>When actually deleting files, it's common to encounter situations where files cannot be deleted because they are in use.\u003C\u002Fp>\u003Cp>Here we need to find the process occupying the file, obtain the file handle, and release the handle before deleting the file.\u003C\u002Fp>\u003Cp>The implementation approach is as follows:\u003C\u002Fp>\u003Cul>\u003Cli>Elevate program to debug privileges\u003C\u002Fli>\u003Cli>Enumerate all processes\u003C\u002Fli>\u003Cli>Obtain handles to specified files\u003C\u002Fli>\u003Cli>Release those handles\u003C\u002Fli>\u003C\u002Ful>\u003Cp>When mapping this to actual program implementation, the following issues require attention:\u003C\u002Fp>\u003Ch3>1. Elevate to debug privilege\u003C\u002Fh3>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>BOOL EnableDebugPrivilege(BOOL fEnable)\u003Cbr>{\u003Cbr>\tBOOL fOk = FALSE;\u003Cbr>\tHANDLE hToken;\u003Cbr>\tif (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &amp;hToken))\u003Cbr>\t{\u003Cbr>\t\tTOKEN_PRIVILEGES tp;\u003Cbr>\t\ttp.PrivilegeCount = 1;\u003Cbr>\t\tLookupPrivilegeValue(NULL, SE_DEBUG_NAME, &amp;tp.Privileges[0].Luid);\u003Cbr>\t\ttp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;\u003Cbr>\t\tAdjustTokenPrivileges(hToken, FALSE, &amp;tp, sizeof(tp), NULL, NULL);\u003Cbr>\t\tfOk = (GetLastError() == ERROR_SUCCESS);\u003Cbr>\t\tCloseHandle(hToken);\u003Cbr>\t}\u003Cbr>\treturn(fOk);\u003Cbr>}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>2. Enumerate all processes to obtain handles to the specified file\u003C\u002Fh3>\u003Cp>Use the kernel API NtQuerySystemInformation to query SystemHandleInformation and obtain handles from all processes\u003C\u002Fp>\u003Cp>Filter out handles of type file: ObjectTypeNumber = 0x1e\u003C\u002Fp>\u003Cp>If the process corresponding to a handle cannot be opened, set a flag and avoid repeatedly attempting to open that process\u003C\u002Fp>\u003Cp>Filter out handles that may cause hangs, using the API WaitForSingleObject for judgment\u003C\u002Fp>\u003Ch3>3. Release handles\u003C\u002Fh3>\u003Cp>Handles obtained via the kernel API NtQuerySystemInformation querying SystemHandleInformation are pseudo-handles and cannot be directly released\u003C\u002Fp>\u003Cp>Use the API DuplicateHandle to convert pseudo-handles into real handles\u003C\u002Fp>\u003Cp>Function prototype as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>BOOL WINAPI DuplicateHandle(\u003Cbr>  _In_  HANDLE   hSourceProcessHandle,\u003Cbr>  _In_  HANDLE   hSourceHandle,\u003Cbr>  _In_  HANDLE   hTargetProcessHandle,\u003Cbr>  _Out_ LPHANDLE lpTargetHandle,\u003Cbr>  _In_  DWORD    dwDesiredAccess,\u003Cbr>  _In_  BOOL     bInheritHandle,\u003Cbr>  _In_  DWORD    dwOptions\u003Cbr>);\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The 7th parameter is set to DUPLICATE_CLOSE_SOURCE, indicating that the handle in the source process will be released\u003C\u002Fp>\u003Cp>Specific parameters are as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>DuplicateHandle(processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &amp;dupHandle, 0, 0, DUPLICATE_CLOSE_SOURCE)\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The complete code has been open-sourced, address as follows:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code implements enumerating all processes in the current system, finding handles to specified files, and releasing them\u003C\u002Fp>\u003Cp>It can not only be used to release file locks but also to disable certain logging functions\u003C\u002Fp>\u003Cp>For example, if the handle to system.evtx is released, the logging service cannot write logs to system.evtx, causing logs under system.evtx to become invalid\u003C\u002Fp>\u003Ch2>0x06 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article briefly introduces the principles of file deletion and recovery, testing tools, writing programs to prevent file recovery through file overwriting, addresses file occupancy issues, and provides open-source code.\u003C\u002Fp>\u003Cp>From a penetration perspective, one approach is to attempt to recover files from the target system, while the other is to securely delete one's own tools to prevent recovery.\u003C\u002Fp>\u003Cp>From a defensive standpoint, important files can be securely deleted using the tool SDelete.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>","text","ltr","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>In penetration testing, file recovery and deletion are like spear and shield.\u003C\u002Fp>\u003Cp>File recovery refers to restoring deleted files on the target system, while file deletion means removing tools used on the target system to prevent recovery.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following topics:\u003C\u002Fp>\u003Cul>\u003Cli>Principles of file deletion\u003C\u002Fli>\u003Cli>Principles of file recovery\u003C\u002Fli>\u003Cli>Using PowerForensics for file recovery\u003C\u002Fli>\u003Cli>Using SDelete for file deletion\u003C\u002Fli>\u003Cli>Can PowerForensics recover files after deletion with SDelete?\u003C\u002Fli>\u003Cli>Preventing file recovery through file overwriting\u003C\u002Fli>\u003Cli>Enumerate all processes, search for handles to specific files, release those handles to free file locks, and achieve file deletion\u003C\u002Fli>\u003Cli>Program implementation details and open-source code\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Principles of File Deletion and Recovery\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>References:\u003C\u002Fp>\u003Cp>http:\u002F\u002Fwww.ntfs.com\u002Fntfs_basics.htm\u003C\u002Fp>\u003Ch3>Basic Concepts\u003C\u002Fh3>\u003Cp>Most Windows file systems use NTFS (New Technology File System) technology\u003C\u002Fp>\u003Cp>Each file in NTFS corresponds to a Master File Table (MFT)\u003C\u002Fp>\u003Cp>The MFT serves as a file index, storing file attributes\u003C\u002Fp>\u003Ch4>Intuitive understanding of file deletion:\u003C\u002Fh4>\u003Cp>Only modifies the MFT (i.e., file attributes), without altering the deleted file's content\u003C\u002Fp>\u003Ch4>Intuitive understanding of file recovery:\u003C\u002Fh4>\u003Cp>Restoring the file's MFT is sufficient\u003C\u002Fp>\u003Ch3>Simple Test\u003C\u002Fh3>\u003Cp>Create a new file test.txt and write the content 0123456789\u003C\u002Fp>\u003Cp>Using tool: WinHex\u003C\u002Fp>\u003Cp>Download link:\u003C\u002Fp>\u003Cp>http:\u002F\u002Fwww.x-ways.net\u002Fwinhex\u002F\u003C\u002Fp>\u003Cp>Select Tools -&gt; Open Disk, choose the drive letter\u003C\u002Fp>\u003Cp>Locate the file test.txt, right-click -&gt; Navigation -&gt; Seek FILE Record\u003C\u002Fp>\u003Cp>View the MFT information of test.txt, as shown below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017247577_0_41d915c63d-1.jpeg\">\u003C\u002Fp>\u003Cp>The structure of MFT is as follows\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017270145_1_8dc725765f-1.jpeg\">\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Screenshot taken from http:\u002F\u002Fwww.blogfshare.com\u002Fdetail-ntfs-filesys.html\u003C\u002Fp>\u003Cp>Next, delete the file test.txt and empty the files in the Recycle Bin\u003C\u002Fp>\u003Cp>Use WinHex to view the hard disk content again, close the current drive, reselect Tools -&gt; Open Disk, choose the drive letter\u003C\u002Fp>\u003Cp>A dialog box prompts, select to update the snapshot, as shown below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017301566_2_c3f5dacc62-1.jpeg\">\u003C\u002Fp>\u003Cp>Review the MFT structure again, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017325401_3_76130460ce-1.jpeg\">\u003C\u002Fp>\u003Cp>Comparison reveals the following differences:\u003C\u002Fp>\u003Cul>\u003Cli>Offset 0x08\u003C\u002Fli>\u003Cli>Offset 0x10, value increased by 1\u003C\u002Fli>\u003Cli>Offset 0x16, changed from 1 to 0\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Select 'Recover File' in the WinHex interface to successfully restore the file\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Successful recovery depends on the file not being overwritten\u003C\u002Fp>\u003Cp>In summary, the principle of file recovery can be simply understood as follows:\u003C\u002Fp>\u003Cp>\u003Cstrong>File deletion only modifies the file's MFT; if the file content has not been overwritten, the file can be recovered\u003C\u002Fstrong>\u003C\u002Fp>\u003Ch2>0x03 Using PowerForensics for File Recovery\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>There are various file recovery software tools; here is one that uses PowerShell for file recovery: PowerForensics\u003C\u002Fp>\u003Cp>Project address:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002FInvoke-IR\u002FPowerForensics\u002F\u003C\u002Fp>\u003Cp>Download URL:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002FInvoke-IR\u002FPowerForensics\u002Freleases\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>PowerForensicsv2.zip corresponds to PowerShell v2, the default version for Win7 and Server 2008\u003C\u002Fp>\u003Cp>For tool usage, refer directly to xpn's blog:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fblog.xpnsec.com\u002Foffensive-forensics\u002F\u003C\u002Fp>\u003Cp>To obtain a list of all recoverable files, use the following PowerShell command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>powershell -executionpolicy bypass\u003Cbr>import-module .\\PowerForensicsv2.psd1\u003Cbr>Get-ForensicFileRecord | Where {$_.Deleted -eq $true} | Select FullName\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>To recover a specific file C:\\test.txt and save it as recovered.txt:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>$file = Get-ForensicFileRecord | Where {$_.FullName -eq \"C:\\test.txt\"}\u003Cbr>$file.CopyFile(\"recovered.txt\")\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch2>0x04 Preventing File Recovery\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Using the tool SDelete\u003C\u002Fh3>\u003Cp>Download link:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fsysinternals\u002Fdownloads\u002Fsdelete\u003C\u002Fp>\u003Cp>The deletion command is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>sdelete64.exe -accepteula C:\\test.txt\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>2. Implementation via C++\u003C\u002Fh3>\u003Cp>Based on the principle analysis in 0x01, we know that overwriting the original file can prevent its recovery.\u003C\u002Fp>\u003Ch4>The simplest implementation approach:\u003C\u002Fh4>\u003Cp>Modify the content of the original file by filling it with random strings, then delete the file.\u003C\u002Fp>\u003Cp>I wrote a simple test code that first fills the file to be deleted with zeros, then deletes the file. Even if the file is recovered, its content will be all zeros. The reference C code is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>#include \u003Cwindows.h>\u003Cbr>int main(int argc, char *argv[])\u003Cbr>{\u003Cbr>\tif (argc != 2)\u003Cbr>\t{\u003Cbr>\t\tprintf(\"\\nOverwrite the file,avoid being restored\\n\\n\");\u003Cbr>\t\tprintf(\"Usage:\\n\");\u003Cbr>\t\tprintf(\"%s \u003Cfile path=\"\">\\n\",argv[0]);\u003Cbr>\t\treturn 0;\u003Cbr>\t}\u003Cbr>\tprintf(\"[*]Try to overwrite file &lt;%s&gt;   \", argv[1]);\u003Cbr>\tFILE* fp;\u003Cbr>\tint err = fopen_s(&amp;fp, argv[1], \"rb+\");\u003Cbr>\tif (err != 0)\u003Cbr>\t{\u003Cbr>\t\tprintf(\"\\n[!]Openfile error!\");\u003Cbr>\t\treturn 0;\u003Cbr>\t}\u003Cbr>\tfseek(fp, 0, SEEK_END);\u003Cbr>\tint len = ftell(fp);\u003Cbr>\tchar *buf = new char[len];\u003Cbr>\tmemset(buf, 0, len);\u003Cbr>\tfclose(fp);\u003Cbr>\terr = fopen_s(&amp;fp, argv[1], \"wb+\");\u003Cbr>\tif (err != 0)\u003Cbr>\t{\u003Cbr>\t\tprintf(\"\\n[!]Openfile error!\");\u003Cbr>\t\treturn 0;\u003Cbr>\t}\u003Cbr>\tfwrite(buf, len, 1, fp);\u003Cbr>\tfclose(fp);\u003Cbr>\tprintf(\"done\\n\");\u003Cbr>\u003Cbr>\tprintf(\"[*]Try to delete file   &lt;%s&gt;   \", argv[1]);\u003Cbr>\tif(DeleteFile(argv[1])!=0)\u003Cbr>\t\tprintf(\"done\\n\");\u003Cbr>\telse\u003Cbr>\t\tprintf(\"error\\n\");\u003Cbr>\treturn 0;\u003Cbr>}\u003C\u002Ffile>\u003C\u002Fwindows.h>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch2>0x05 Release File Lock\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>When actually deleting files, it's common to encounter situations where files cannot be deleted because they are in use.\u003C\u002Fp>\u003Cp>Here we need to find the process occupying the file, obtain the file handle, and release the handle before deleting the file.\u003C\u002Fp>\u003Cp>The implementation approach is as follows:\u003C\u002Fp>\u003Cul>\u003Cli>Elevate program to debug privileges\u003C\u002Fli>\u003Cli>Enumerate all processes\u003C\u002Fli>\u003Cli>Obtain handles to specified files\u003C\u002Fli>\u003Cli>Release those handles\u003C\u002Fli>\u003C\u002Ful>\u003Cp>When mapping this to actual program implementation, the following issues require attention:\u003C\u002Fp>\u003Ch3>1. Elevate to debug privilege\u003C\u002Fh3>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>BOOL EnableDebugPrivilege(BOOL fEnable)\u003Cbr>{\u003Cbr>\tBOOL fOk = FALSE;\u003Cbr>\tHANDLE hToken;\u003Cbr>\tif (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &amp;hToken))\u003Cbr>\t{\u003Cbr>\t\tTOKEN_PRIVILEGES tp;\u003Cbr>\t\ttp.PrivilegeCount = 1;\u003Cbr>\t\tLookupPrivilegeValue(NULL, SE_DEBUG_NAME, &amp;tp.Privileges[0].Luid);\u003Cbr>\t\ttp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;\u003Cbr>\t\tAdjustTokenPrivileges(hToken, FALSE, &amp;tp, sizeof(tp), NULL, NULL);\u003Cbr>\t\tfOk = (GetLastError() == ERROR_SUCCESS);\u003Cbr>\t\tCloseHandle(hToken);\u003Cbr>\t}\u003Cbr>\treturn(fOk);\u003Cbr>}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>2. Enumerate all processes to obtain handles to the specified file\u003C\u002Fh3>\u003Cp>Use the kernel API NtQuerySystemInformation to query SystemHandleInformation and obtain handles from all processes\u003C\u002Fp>\u003Cp>Filter out handles of type file: ObjectTypeNumber = 0x1e\u003C\u002Fp>\u003Cp>If the process corresponding to a handle cannot be opened, set a flag and avoid repeatedly attempting to open that process\u003C\u002Fp>\u003Cp>Filter out handles that may cause hangs, using the API WaitForSingleObject for judgment\u003C\u002Fp>\u003Ch3>3. Release handles\u003C\u002Fh3>\u003Cp>Handles obtained via the kernel API NtQuerySystemInformation querying SystemHandleInformation are pseudo-handles and cannot be directly released\u003C\u002Fp>\u003Cp>Use the API DuplicateHandle to convert pseudo-handles into real handles\u003C\u002Fp>\u003Cp>Function prototype as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>BOOL WINAPI DuplicateHandle(\u003Cbr>  _In_  HANDLE   hSourceProcessHandle,\u003Cbr>  _In_  HANDLE   hSourceHandle,\u003Cbr>  _In_  HANDLE   hTargetProcessHandle,\u003Cbr>  _Out_ LPHANDLE lpTargetHandle,\u003Cbr>  _In_  DWORD    dwDesiredAccess,\u003Cbr>  _In_  BOOL     bInheritHandle,\u003Cbr>  _In_  DWORD    dwOptions\u003Cbr>);\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The 7th parameter is set to DUPLICATE_CLOSE_SOURCE, indicating that the handle in the source process will be released\u003C\u002Fp>\u003Cp>Specific parameters are as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>DuplicateHandle(processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &amp;dupHandle, 0, 0, DUPLICATE_CLOSE_SOURCE)\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The complete code has been open-sourced, address as follows:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code implements enumerating all processes in the current system, finding handles to specified files, and releasing them\u003C\u002Fp>\u003Cp>It can not only be used to release file locks but also to disable certain logging functions\u003C\u002Fp>\u003Cp>For example, if the handle to system.evtx is released, the logging service cannot write logs to system.evtx, causing logs under system.evtx to become invalid\u003C\u002Fp>\u003Ch2>0x06 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article briefly introduces the principles of file deletion and recovery, testing tools, writing programs to prevent file recovery through file overwriting, addresses file occupancy issues, and provides open-source code.\u003C\u002Fp>\u003Cp>From a penetration perspective, one approach is to attempt to recover files from the target system, while the other is to securely delete one's own tools to prevent recovery.\u003C\u002Fp>\u003Cp>From a defensive standpoint, important files can be securely deleted using the tool SDelete.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>",741,"Onedaysec",5,"published","2026-02-02T07:38:21.197Z",{"title":37,"description":14,"keywords":38,"ogImage":39,"canonicalUrl":39,"noIndex":40},"Windows File Recovery & Deletion Techniques for Penetration Testing","file recovery, file deletion, Windows NTFS, penetration testing, PowerForensics, SDelete, MFT, data security",null,false,[],{"docs":43,"hasNextPage":40},[44,45,46,4,47],835,834,833,831,{"title":39,"description":39,"image":39},"2026-07-24T15:37:11.297Z","2026-07-23T16:02:10.350Z","draft","2026-07-23T16:15:00.841Z"]