熊猫烧香病毒分析报告
文章目录
- 熊猫烧香病毒分析报告
- 1.样本概况
- 1.1 样本信息
- 1.2 测试环境及工具
- 1.3 分析目标
- 1.4 主要行为概述
- 2.具体行为分析
- 2.1 主要行为
- 2.2 恶意代码分析
- 2.2.1 加固后的恶意代码树结构图
- 2.2.2 恶意程序的代码分析片段
- 3.解决方案
- 3.1 提取病毒的特征,利用杀毒软件查杀
- 3.2 手工查杀步骤
- 3.3 熊猫专杀工具
熊猫烧香病毒分析报告
1.样本概况
1.1 样本信息
病毒名称:熊猫烧香
所属家族:感染型蠕虫病毒
MD5值: 512301C535C88255C9A252FDF70B7A03
SHA1值: CA3A1070CFF311C0BA40AB60A8FE3266CFEFE870
CRC32: E334747C
1.2 测试环境及工具
测试环境:虚拟机Windows 7 32位
测试工具:火绒剑、PCHunter、PEiD、OllyDbg、IDA
1.3 分析目标
分析病毒具体行为,找到病毒行为的具体实现代码,了解病毒实现原理,评估病毒的威胁程度。
1.4 主要行为概述
病毒行为:
①自我复制样本到C:\Windows\driver\spo0lsv.exe目录下,运行spo0lsv.exe(样本)
②在每个目录下创建了Desktop_.ini,内容为当前日期
③在C盘根目录下创建autorun.inf文件,该文件指定了自动启动的文件为根目录下的setup.exe(即样本)
④对程序目录下的exe进行了感染,图标变为熊猫烧香,打开exe时自动打开病毒
⑤设置注册表启动项为C:\Windows\driver\spo0lsv.exe
⑥删除杀毒软件注册表启动项,关闭服务
⑦访问网站,下载恶意代码
2.具体行为分析
2.1 主要行为
第一部分:自我复制:
第二部分:感染文件
第三部分:自我保护
通过火绒剑和PCHunter监视病毒,发现病毒具有以下行为:
①自我复制样本到C:\Windows\System32\drivers\spo0lsv.exe目录下,运行spo0lsv.exe(样本)
②在每个目录下创建了Desktop_.ini,内容为当前日期
③在C盘根目录下创建autorun.inf文件,该文件指定了自动启动的文件为根目录下的setup.exe(即样本)
④通过火绒剑对程序目录下的文件进行了感染,图标变为熊猫烧香,通过PEID工具感染后exe文件和病毒文件信息相同,运行exe时会自动打开病毒文件。
⑤设置注册表启动项为C:\Windows\System32\drivers\spo0lsv.exe
⑥删除杀毒软件注册表启动项
2.2 恶意代码分析
2.2.1 加固后的恶意代码树结构图
该病毒的壳是FSG v2.0,原程序和脱壳后程序对比:
2.2.2 恶意程序的代码分析片段
恶意程序的主要功能框架:
①自我复制行为
②遍历文件,感染特定类型的文件,包括可执行文件,网页文件以及备份文件。
修改文件图标,修改PE文件内容,起始部分是病毒文件,中间插入了部分代码,末尾添加感染标识:“whboy”+原文件名+".exe"+原文件大小,修改原文件图标为熊猫烧香图标。
PE文件感染后
③设置第一个定时器
判断C盘的根目录下是否存在autorun.inf和setup.exe文件,若不存在则创建文件,并向autorun.inf文件写入内容,指定setup.exe为自启动文件,并且隐藏文件。
④第三个关键函数内有六个定时器
(1)修改病毒的注册表启动项,设置隐藏
(2)检测杀毒软件,关闭杀软进程,删除杀毒软件注册表自启动项
病毒会检测系统的安全服务和当时流行的杀毒软件,如防火墙、金山毒霸、卡巴斯基、江民等杀毒软件。
通过遍历进程,查找窗口等方式定时检测杀毒软件,检测到杀毒软件结束杀毒软件进程。
大部分使用结束进程API,发WM_QUIT消息结束杀软进程,针对某些杀毒软件使用虚拟按键的方式关闭进程,例如Pjf(ustc)冰刃。
(3)通过cmd命令删除共享
(4)网络异常,下载恶意代码
下载恶意代码行为
3.解决方案
3.1 提取病毒的特征,利用杀毒软件查杀
①病毒特征:字符串
xboy 、whboy、武汉男生感染下载者**
②Yara规则
rule vir_3601
{strings:$text_1="xboy "$text_2="whboy"
$text_3="***武*汉*男*生*感*染*下*载*者***"
condition:$text_1 or $text_2 or $text_3
}
③利用ClamAv查杀
3.2 手工查杀步骤
(1)利用PCHunter工具结束进程,并删除spo0lsv.exe文件
(2)清除启动项,关闭svcshare启动项
(3)删除autorun.inf和setup.exe
(4)清除每个盘符下的Desktop_.ini文件
(5)打开注册表,HKLM\Microsoft\Windows\CurrentVersion\Explore
Advanced\Folder\Hidden\SHOWALL\CheckValue,将CheckValue的值设为1。
3.3 熊猫专杀工具
熊猫烧香病毒感染文件只是做了一定的修改,并没有对文件进行加密,所以可以编写专杀工具清除病毒,恢复感染文件。其实就是将手工查杀步骤利用程序自动化完成。
专杀工具源码如下:
#include "pch.h"
#include <iostream>
#include <TlHelp32.h>
#include <tchar.h>
#include <strsafe.h>
#include <Shlwapi.h>#define VIRSIZE 0x7531 //熊猫病毒大小//************************************
// 功能: 查找熊猫病毒进程
//************************************
BOOL FindVirProcess(CString nProcessName,LPDWORD lpPid)
{PROCESSENTRY32 pe32;pe32.dwSize = sizeof(pe32);HANDLE nSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);BOOL nRet = Process32First(nSnapShot, &pe32);while (nRet){if (nProcessName == CString(pe32.szExeFile)){*lpPid = pe32.th32ProcessID;return TRUE;}nRet = Process32Next(nSnapShot, &pe32);}return FALSE;
}//************************************
// 功能: 删除病毒文件
//************************************
VOID DeleteVirFile(CString szPath)
{SetFileAttributes(szPath, FILE_ATTRIBUTE_NORMAL);DeleteFile(szPath);
}//************************************
// 功能: 获取PC盘符列表
//************************************
VOID GetDriverList(vector<CString> &DiverList)
{TCHAR szDrive[MAX_PATH];TCHAR szRootPath[MAX_PATH] = {};GetLogicalDriveStrings(MAX_PATH - 1, szDrive);TCHAR* lpPath = szDrive;while (*lpPath != 0) {_tcscpy_s(szRootPath, lpPath);szRootPath[2] = _T('\0');//szRootPath[-2] = L'\0';DiverList.push_back(szRootPath); //取出第一个盘符路径lpPath += _tcslen(lpPath) + 1;}
}//************************************
// 功能: 扫描文件
//************************************
VOID ScanFile(CString lpPath)
{//删除文件Desktop_.iniDeleteConfig(lpPath);//1. 构造路径CString szFilePath = lpPath;szFilePath += _T("\\*");//WCHAR szFilePath[MAX_PATH];//StringCbCopy(szFilePath, MAX_PATH, lpPath);//StringCbCat(szFilePath, MAX_PATH, L"\\*");//2. 第一次遍历WIN32_FIND_DATA wfd = { 0 };HANDLE hFile = FindFirstFile(szFilePath, &wfd);if (hFile != INVALID_HANDLE_VALUE){do{ CString szFullPath = lpPath;//3.1 判断是否是本级目录或上级目录if (!lstrcmp(wfd.cFileName, L".") || !lstrcmp(wfd.cFileName, L".."))continue;szFullPath += _T("\\");szFullPath += wfd.cFileName;//3.4 如果不是目录,获取详细信息if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){ScanFile(szFullPath);}else{//恢复文件RecoveryFile(szFullPath, wfd.cFileName);}} while (FindNextFile(hFile, &wfd));}
}//************************************
// 功能: 恢复感染文件
//************************************
void RecoveryFile(CString nFilePath, CString nFileName)
{int nVirType = 0;CString nLastName;nLastName = PathFindExtension(nFileName);nLastName.MakeUpper();if (nLastName == ".EXE" || nLastName == ".SCR" || nLastName == ".PIF" || nLastName == ".COM")nVirType = 1;else if (nLastName == ".HTML" || nLastName == ".HTM" || nLastName == ".ASP" || nLastName == ".ASPX" || nLastName == ".JSP" || nLastName == ".PHP")nVirType = 2;else return;//exe,scr,pif,com,htm,html,asp,php,jsp,aspx// 1.读取文件到内存HANDLE hFile = CreateFile(nFilePath,GENERIC_READ, FALSE, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INVALID_HANDLE_VALUE){printf("打开文件 %s 失败--%s\n", (CStringA)nFileName.GetBuffer(),(CStringA)nFilePath.GetBuffer());printf("错误代码--%d\n", GetLastError());return;}// 获取文件大小DWORD dwSize = GetFileSize(hFile, NULL);CHAR* pFile = new CHAR[dwSize]{};// 读取文件内容DWORD dwRead;SetFilePointer(hFile, 0, NULL, FILE_BEGIN); //设置文件指针ReadFile(hFile, pFile, dwSize, &dwRead, NULL); //读取文件// 关闭文件句柄CloseHandle(hFile);//恢复文件 病毒感染标识:whboy+原文件名+0x2E+(exe/PIF等)+0x02+原文件大小+0x01int i = 0;if (nVirType == 1) //可执行文件恢复{//获取原文件大小for (i = 0; i < 13; i++){if (*(pFile + dwSize - 13 + i) == (char)0x02)break; //0x02是分隔符}if (i == 13 || * (pFile + dwSize - 1) != (char)0x01) //0x01是结束符{//printf("未感染文件!%s\n", (CStringA)nFilePath.GetBuffer());delete[]pFile;return;}char nTemp[13]{};DWORD nExeSize = 0;size_t nCopySzie = 13 - i - 2;memcpy_s(nTemp, 13, (pFile + dwSize - 13 + i + 1), nCopySzie);sscanf_s(nTemp, "%d", &nExeSize);if (nExeSize <= 0){delete[]pFile;return;}printf("感染文件类型:%s,尺寸:%d\n", (CStringA)nLastName.GetBuffer(), nExeSize);char *NewFile = new char[nExeSize] {};memcpy_s(NewFile, nExeSize, (pFile + VIRSIZE), nExeSize);if (!DeleteFile(nFilePath)){printf("修复%s失败!%s\n", (CStringA)nLastName.GetBuffer(),(CStringA)nFilePath.GetBuffer());delete[]NewFile;delete[]pFile;return;}// 1.写入文件HANDLE hFile = CreateFile(nFilePath,GENERIC_WRITE, FALSE, NULL, CREATE_NEW,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);if (hFile == INVALID_HANDLE_VALUE){printf("写入文件失败\n");return;}DWORD dwWrite;WriteFile(hFile, NewFile, nExeSize, &dwWrite, NULL); //读取文件CloseHandle(hFile);if (dwWrite == nExeSize){delete[]NewFile;printf("修复%s成功!%s\n", (CStringA)nLastName.GetBuffer(), (CStringA)nFilePath.GetBuffer());}}else //网页文件恢复{CStringA nFileCode(pFile);if (nFileCode.Find("www.ac86.cn/66/index.htm") != -1){int nHtmlSize = dwSize - 76;char *NewFile = new char[nHtmlSize] {};memcpy_s(NewFile, nHtmlSize, pFile, nHtmlSize);if (!DeleteFile(nFilePath)){printf("修复%s失败!%s\n", (CStringA)nLastName.GetBuffer(),(CStringA)nFilePath.GetBuffer());delete[]NewFile;delete[]pFile;return;}HANDLE hFile = CreateFile(nFilePath,GENERIC_WRITE, FALSE, NULL, CREATE_NEW,FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INVALID_HANDLE_VALUE){printf("创建网页文件失败--%s\n", (CStringA)nFilePath.GetBuffer());return;}DWORD dwWrite;WriteFile(hFile, NewFile, nHtmlSize, &dwWrite, NULL); //写入文件CloseHandle(hFile);if (dwWrite == nHtmlSize){delete[] NewFile;printf("修复%s成功!%s\n", (CStringA)nLastName.GetBuffer(), (CStringA)nFilePath.GetBuffer());}}}delete[] pFile;pFile = nullptr;
}//************************************
// 功能: 删除配置文件
//************************************
void DeleteConfig(CString szPath)
{// 1.构造路径CString szFilePath = szPath;szFilePath += _T("\\Desktop_.ini");// 2.删除文件WIN32_FIND_DATA wfd = { 0 };HANDLE hFile = FindFirstFile(szFilePath, &wfd);if (hFile == INVALID_HANDLE_VALUE){return; //文件不存在}FindClose(hFile);DeleteVirFile(szFilePath);printf("删除Desktop_.ini成功--%ls\n", szFilePath.GetBuffer());
}int main()
{// 1.结束病毒进程,删除文件DWORD dwPid = 0;FindVirProcess("spo0lsv.exe", &dwPid);HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);TerminateProcess(hProcess, 0);DeleteVirFile("C:\\Windows\\System32\\drivers\\spo0lsv.exe");printf("完成----结束病毒进程\n");// 2.删除病毒自启动项//HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\svcshareHKEY hKey = NULL;int nError = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run\\", &hKey);if (nError != ERROR_SUCCESS) MessageBoxA(NULL, "打开注册表失败1", "提示", MB_ICONWARNING);RegDeleteValueA(hKey, "svcshare");RegCloseKey(hKey);printf("完成----删除病毒自启动项\n");// 3.恢复注册表CheckValue值//HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Folder\Hidden\SHOWALL\\CheckedValuenError = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\Folder\\Hidden\\SHOWALL\\", &hKey);if (nError != ERROR_SUCCESS) MessageBoxA(NULL, "打开注册表失败2", "提示", MB_ICONWARNING);DWORD nVal = 1;RegSetValueExA(hKey, "CheckedValue", 0, REG_DWORD, (CONST BYTE*)&nVal, sizeof(DWORD));RegCloseKey(hKey);printf("完成----恢复注册表CheckValue值\n");// 4.删除autorun.inf和setup.exeDeleteVirFile("C:\\autorun.inf");DeleteVirFile("C:\\setup.exe");printf("完成----删除autorun.inf和setup.exe\n");// 5.遍历文件夹,清除Desktop_.ini,恢复感染文件vector<CString> DiverList;GetDriverList(DiverList);for (UINT i=0;i<DiverList.size();i++){TCHAR* szRoot = DiverList[i].GetBuffer();ScanFile(szRoot);}/*TCHAR* szRoot = L"C:\\Virus";ScanFile(szRoot);*/printf("完成----清除Desktop_.ini,恢复感染文件\n");system("pause");
}