0x01 前言
项目地址:
https://github.com/AgeloVito/self_delete_bof
https://github.com/seventeenman/SelfDel-BOF
点点star好兄弟们!
0x02 解释及代码
SetFileInformationByHandle函数允许通过打开的文件句柄修改元数据而不锁定文件内容,因为它只修改文件的元数据信息,而不会修改文件的内容。在这段代码中,它被用于设置文件的删除信息,从而实现对文件的删除。具体来说,它使用了FILE_DISPOSITION_INFO结构体,将DeleteFile成员设置为TRUE,表示要删除该文件。这个结构体被传递给SetFileInformationByHandle函数,从而实现对文件的删除。同时,文件系统将文件存储和元数据管理分离,获取目标进程文件句柄后先通过该句柄重命名切断进程对文件名的联系避免进程检测到删除标记而中断,再设置删除标记通知文件系统后续删除内容但是现在内容仍需保留以便进程可以正常运行访问,进程看到的仍是老文件名不会发现内容被标记删除,直到进程退出关闭最后一个文件句柄时文件系统才实际删除文件内容,在此过程中进程可以继续正常运行最后安全删除文件。
static HANDLE openHandle(PWCHAR pwPath)
{
return CreateFileW(pwPath, DELETE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
static BOOL renameHandle(HANDLE hHandle)
{
FILE_RENAME_INFO fRename;
RtlSecureZeroMemory(&fRename, sizeof(fRename));
LPWSTR lpwStream = DS_STREAM_RENAME;
fRename.FileNameLength = sizeof(lpwStream);
RtlCopyMemory(fRename.FileName, lpwStream, sizeof(lpwStream));
return SetFileInformationByHandle(hHandle, FileRenameInfo, &fRename, sizeof(fRename) + sizeof(lpwStream));
}
static BOOL depositeHandle(HANDLE hHandle)
{
FILE_DISPOSITION_INFO fDelete;
RtlSecureZeroMemory(&fDelete, sizeof(fDelete));
fDelete.DeleteFile = TRUE;
return SetFileInformationByHandle(hHandle, FileDispositionInfo, &fDelete, sizeof(fDelete));
}
BOOL DeleteExecutableByPID(DWORD dwProcessID)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessID);
if (hProcess == NULL)
{
return FALSE;
}
WCHAR szModulePath[MAX_PATH];
DWORD dwSize = MAX_PATH;
if (QueryFullProcessImageNameW(hProcess, 0, szModulePath, &dwSize))
{
CloseHandle(hProcess);
HANDLE hRename = openHandle(szModulePath);
renameHandle(hRename);
CloseHandle(hRename);
HANDLE hDelete = openHandle(szModulePath);
depositeHandle(hDelete);
CloseHandle(hDelete);
return TRUE;
}
CloseHandle(hProcess);
return FALSE;
}
BOOL DeleteFileByPath(PWCHAR pwPath)
{
HANDLE hRename = openHandle(pwPath);
renameHandle(hRename);
CloseHandle(hRename);
HANDLE hDelete = openHandle(pwPath);
depositeHandle(hDelete);
CloseHandle(hDelete);
return TRUE;
}
int wmain(int argc, wchar_t* argv[])
{
if (argc == 1)
{
WCHAR wcPath[MAX_PATH + 1];
RtlSecureZeroMemory(wcPath, sizeof(wcPath));
if (GetModuleFileNameW(NULL, wcPath, MAX_PATH) != 0)
{
HANDLE hRename = openHandle(wcPath);
renameHandle(hRename);
CloseHandle(hRename);
HANDLE hDelete = openHandle(wcPath);
depositeHandle(hDelete);
CloseHandle(hDelete);
return 0;
}
return 1;
}
else if (argc == 3)
{
if (wcscmp(argv[1], L"-f") == 0)
{
if (DeleteFileByPath(argv[2]))
{
return 0;
}
return 1;
}
else if (wcscmp(argv[1], L"-p") == 0)
{
DWORD dwProcessID = _wtoi(argv[2]);
if (DeleteExecutableByPID(dwProcessID))
{
return 0;
}
return 1;
}
}
wprintf(L"Usage: %s [-f file_path] [-p process_id]n", argv[0]);
return 1;
}
0x03 用法及效果
-
默认自删除:运行工具而不带任何参数。
-
指定文件路径删除:
-
指定进程ID删除文件:
使用-f参数,后面跟着要删除的文件的路径。
工具会尝试删除指定路径的文件。
示例命令:tool.exe -f C:file.txt。
使用-p参数,后面跟着要删除文件的进程ID。
工具会尝试删除与给定进程ID相关联的可执行文件。
示例命令:tool.exe -p 1234。
原文始发于微信公众号(小黑说安全):强制delete运行中文件
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论