C/C++恶意代码盘点之文件自动删除

前言

恶意代码的分类包括计算机病毒、蠕虫、木马、后门、Rootkit、流氓软件、间谍软件、广告软件、僵尸(bot) 、Exploit等等,有些技术经常用到,有的也是必然用到。

上次咱们分享了一部分,那么今天我们就分享一下文件自动删除。

自删除功能对病毒木马来说同样至关重要,它通常在完成目标任务之后删除自身,不留下任何蛛丝马迹,自删除的方法有很多种,常见的有利用MoveFileEx重启删除和利用批处理删除两种方式。

1、MoveFileEx重启删除

MOVEFILE_DELAY_UNTIL_REBOOT这个标志只能由拥有管理员权限的程序或者拥有本地系统权限的程序使用,而且这个标志不能MOVEFILE_COPY_ALLOWED一起使用,并且,删除文件的路径开头需要加上“\?\"前缀。

源代码实现

#include "stdafx.h"
#include <Windows.h>
BOOL RebootDelete(char *pszFileName)
{
 // 重启删除文件
 char szTemp[MAX_PATH] = "\\\\?\\";
 ::lstrcat(szTemp, pszFileName);
 BOOL bRet = ::MoveFileEx(szTemp, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
 return bRet;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
 if (FALSE == RebootDelete("C:\\Users\\Test\\Desktop\\520.exe"))
 {
 printf("Set Reboot Delete Error.\n");
 }
 else
 {
 printf("Set Reboot Delete OK.\n");
 }
 
 system("pause");
 return 0;
}

2、利用批处理命令删除

del %0

批处理命令会将自身批处理文件删除而且不放进回收站。

具体流程

1 构造自删除批处理文件,该批处理文件的功能就是先利用choice或ping命令延迟一定的时间,之后才开始执行删除文件操作,最后执行自删除命令。

2 在程序中创建一个新进程并调用批处理文件,程序在进程创建成功后,立刻退出整个程序。

源代码实现

#include "stdafx.h"
#include <Windows.h>
BOOL CreateChoiceBat(char *pszBatFileName)
{
 int iTime = 5;
 char szBat[MAX_PATH] = { 0 };
 // 构造批处理内容
 /*
 @echo off
 choice /t 5 /d y /n >nul
 del *.exe
 del %0
 */
 ::wsprintf(szBat, "@echo off\nchoice /t %d /d y /n >nul\ndel *.exe\ndel %%0\n", iTime);
 // 生成批处理文件
 FILE *fp = NULL;
 fopen_s(&fp, pszBatFileName, "w+");
 if (NULL == fp)
 {
 return FALSE;
 }
 fwrite(szBat, (1 + ::lstrlen(szBat)), 1, fp);
 fclose(fp);
 return TRUE;
}
BOOL CreatePingBat(char *pszBatFileName)
{
 int iTime = 5;
 char szBat[MAX_PATH] = {0};
 // 构造批处理内容
 /*
 @echo off
 ping 127.0.0.1 -n 5
 del *.exe
 del %0
 */
 ::wsprintf(szBat, "@echo off\nping 127.0.0.1 -n %d\ndel *.exe\ndel %%0\n", iTime);
 // 生成批处理文件
 FILE *fp = NULL;
 fopen_s(&fp, pszBatFileName, "w+");
 if (NULL == fp)
 {
 return FALSE;
 }
 fwrite(szBat, (1 + ::lstrlen(szBat)), 1, fp);
 fclose(fp);
 return TRUE;
}
BOOL DelSelf(int iType)
{
 BOOL bRet = FALSE;
 char szCurrentDirectory[MAX_PATH] = {0};
 char szBatFileName[MAX_PATH] = {0};
 char szCmd[MAX_PATH] = {0};
 // 获取当前程序所在目录
 ::GetModuleFileName(NULL, szCurrentDirectory, MAX_PATH);
 char *p = strrchr(szCurrentDirectory, '\\');
 p[0] = '\0';
 // 构造批处理文件路径
 ::wsprintf(szBatFileName, "%s\\temp.bat", szCurrentDirectory);
 // 构造调用执行批处理的 CMD 命令行
 ::wsprintf(szCmd, "cmd /c call \"%s\"", szBatFileName);
 // 创建自删除的批处理文件
 if (0 == iType)
 {
 // choice 方式
 bRet = CreateChoiceBat(szBatFileName);
 }
 else if (1 == iType)
 {
 // ping 方式
 bRet = CreatePingBat(szBatFileName);
 }
 // 创建新的进程, 以隐藏控制台的方式执行批处理
 if (bRet)
 {
 STARTUPINFO si = { 0 };
 PROCESS_INFORMATION pi;
 si.cb = sizeof(si);
 //指定wShowWindow成员有效
 si.dwFlags = STARTF_USESHOWWINDOW;
 //此成员设为TRUE的话则显示新建进程的主窗口
 si.wShowWindow = FALSE;
 BOOL bRet = CreateProcess(
 //不在此指定可执行文件的文件名
 NULL,
 //命令行参数
 szCmd,
 //默认进程安全性
 NULL,
 //默认进程安全性
 NULL,
 //指定当前进程内句柄不可以被子进程继承
 FALSE,
 //为新进程创建一个新的控制台窗口
 CREATE_NEW_CONSOLE,
 //使用本进程的环境变量
 NULL,
 //使用本进程的驱动器和目录
 NULL,
 &si,
 &pi);
 if (bRet)
 {
 //不使用的句柄最好关掉
 CloseHandle(pi.hThread);
 CloseHandle(pi.hProcess);
 // 结束进程
 exit(0);
 ::ExitProcess(NULL);
 }
 }
 return bRet;
}
int _tmain(int argc, _TCHAR* argv[])
{
 // 程序自删除
 BOOL bRet = DelSelf( 0 );
 if (FALSE == bRet)
 {
 printf("Selft Delete Error!\n");
 }
 else
 {
 printf("Selft Delete OK!\n");
 }
 system("pause");
 return 0;
作者:编程小鱼六六六原文地址:https://blog.csdn.net/yx5666/article/details/126905988

%s 个评论

要回复文章请先登录注册