吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5142|回复: 2
收起左侧

[PC样本分析] 小白之病毒分析- 网吧某监控软件。

  [复制链接]
岁月静好。 发表于 2015-11-11 10:41
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
本帖最后由 岁月静好。 于 2015-11-11 13:25 编辑

前几天上传的样本,得到众基友指点后自己分析,第一次发分析帖流程可能有些混乱,大牛勿喷,有错误请指出,小白在学习中...在此感谢指点过我的人。


概述:
Jw.exe为一个自解压文件,启动后释放出AnnexPro.exe,MainPro.exe,SysStart.sys,mswinsock.dll,
MainProWbj.dll,CMClient,dll六个文件,详细分析了AnnexPro与MainPro两个文件,行为在下方都有详细说明,绿色部分为代码块,红色部分为关键说明。
相关文件:
AnnexPro.exe
MainPro.exe


行为预览:
Annexo.exe行为:

根据观察监控信息来看,Annexo.exe添加开机自启动,Annexo.exe创建互斥体检查是否启动MainPro.exe,如果发现进程被关闭则调用ShellExecuteA创建进程。如果自身进程被关闭,则调用ZwShutdownSystem关机(该为5秒检测一次),还有创建进程快照,检查窗口是否存在及文件是否完整等操作,下面流程未列出

0x1
mov edx,AnnexPro.0044FB0C ;ASCI"Global\Z_ANNEXPRO_ONE_FLAG"
CALL to CreateMutexA from AnnexPro.004069FE
pSecurity = NULL
InitialOwner = FALSE
MutexName = "Global\Z_ANNEXPRO_ONE_FLAG"

0x2
CreateMutexA
pSecurity = NULL
InitialOwner = FALSE
MutexName = "Global\AnnexPro_MainPro_DrvStart"
创建互斥体检查程序是否启动运行,判断信号互斥量是否存在,防止二次行为

0x3
OpenMutexA
         Access = 0x1F0001
         Inheritable = FALSE
         MutexName = "Global\Z_NEEDAUTOUPDATE_TWO_FLAG"
         打开与当前进程文件同名的信号互斥量,判断信号互斥量是否存在

0x4
CreateFileA
         FileName = "\\.\SysStart"
         Access = GENERIC_READ|GENERIC_WRITE
         ShareMode = 0
         pSecurity = NULL
         Mode = OPEN_EXISTING
         Attributes = 0
         hTemplateFile = NULL
         创建文件SysStart.sys,目录在system/dirvers

0x5
CreateFileA
         FileName = "C:\Documents and Settings\Administrator\桌面\1\log\\2015102810.txt"
         Access = GENERIC_WRITE
         ShareMode = FILE_SHARE_READ
         pSecurity = NULL
         Mode = CREATE_ALWAYS
         Attributes = NORMAL
         hTemplateFile = NULL
         创建文件log\\2015102810.txt,将取到的信息存入文件中
         文件格式:
        2015-10-28 10:25:03:==========Run==========
        2015-10-28 10:25:03:Last Build : 2015年8月6日14:01:14

0x6
ReadFile
         hFile = 000001A0 (window)
         Buffer = 00C7E898                    ;00C7E8E4  4D 5A  MZ                        
         BytesToRead = 40 (64.)
         pBytesRead = 00C7E8D8
         pOverlapped = NULL
         创建一个名为MainPro的文件,读取文件,Buffer内容4D 5A,PE结构,可执行文件
文件已dump出来

0x7
Call AnnexPro.004258B0 jmp to shell32.ShellExecuteA
ShellExecuteA最终调用会在CreateProcessW
CreateProcessW
         ModuleFileName = "C:\Documents and Settings\Administrator\桌面\1\MainPro.exe"
         CommandLine = ""C:\Documents and Settings\Administrator\桌面\1\MainPro.exe" "
         pProcessSecurity = NULL
         pThreadSecurity = NULL
         InheritHandles = FALSE
         CreationFlags = CREATE_NEW_CONSOLE|CREATE_UNICODE_ENVIRONMENT|CREATE_DEFAULT_ERROR_MODE
         pEnvironment = NULL
         CurrentDir = "C:\Documents and Settings\Administrator\桌面\1\"
         pStartupInfo = 00175D10
         pProcessInfo = 00175D5C
         创建进程启动MainPro.exe,当MainPro.exe进程不存在时则会继续进行创建。

Annexo.exe调用api的时候都是通过一个jmp跳到系统领空,而不是一般程序的直接调用,这样在导入表中就无法查找到这些重要的api,如下图所示:
图片1.png























MainPro.exe行为:
MainPro.exe启动联网后会随机创建进程,因此在CreateProcess等系列函数下断点,没有断下来,根据监控信息得知,Hook了NtCreateProcess,NtCreateProcessEx这两个函数,联网会触发收发包函数send,recv函数下断点,随机进程名称,随机进程路径在rand函数下断点。MainPro.exe在调用api的时候也是通过一个jmp跳到系统领空,而不是一般程序的直接调用,这样在导入表中就无法查找到这些重要的api。

0x1
RegOpenKeyExA
hKey = HKEY_LOCAL_MACHINE;主键
Subkey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run";子键
Reserved = 0x0;保留
Access = KEY_ALL_ACCESS;权限
pHandle = 0012FEF0
打开注册表HKEY_LOCAL_MACHINE->SOFTWARE\Microsoft\Windows\CurrentVersion\Run        看程序是否自动启动
数值名称:MicroBvd 数值数据:C:\WINDOWS\System32\AnnexPro.exe


0x2
程序启动时首先创建随机数,暂不知道有何作用
004190AC
Call dword ptr ds:[<&winmm.timeGetTime>]  ;记录开始时间
xor edx,edx                             ;edx寄存器清零
Mov ecx,03E8                           ;ecx = 0X3E8
Div ecx                                 ;ecx做除法
Push edx                               ;余数,将余数做参数
Call dword ptr ds:[<&msvcrt.srand>]         ;srand(edx)
Add esp,0x4
Call dword ptr ds:[<&msvcrt.rand>]          ;rand()

0x3
通用注入流程:
CreateProcess->GetThreadContext->ReadProcessMemory->ZwUnmapViewOfSection->VirtualAllocEx->WriteProcessMemory ->SetThreadContext->ResumeThread
怀疑使用的API:
MoveFileA GetMoudleHandleA CharNextA GetTempFileNameA GetTempPathA CreateDirectoryA
SHFileOperationA

Mov edi,dword ptr ds:[<&kernel32.GetProcAdress>]
Push dump.00433B54             ;EnumProcess 列出系统的所有进程,包括详细文件名以及引用的所有动态库文件
Push esi
Call edi                           ;Call GetProcAddress 查找指定DLL的导出函数地址

Push dump.00433B40             ;EuumProcessMoudles
Push esi
Call edi
Mov ebx,eax
Push dump.00433B28              ;GetMoudleFileNameExA
Push esi
Mov dword ptr ss:[esp+0xAC],ebx
Call edi

Push ecx
Push 0x1000
Push edx
Call ebp  EnumProcess

0x4
004039F1
Push eax
Push 0x0
Push 0x410
Call dword ptr ds:[<&kernel32.OpenProcess>];打开进程返回句柄,为后面使用

00403A17
Push ecx
Push 0x1000
Push edx
Push esi
Call dword ptr ss:[esp+0xB4] EnumProcessModules;枚举获取进程的所有模块

00403A3C
Push 0x104
Push eax
Push ecx
Push esi
Call dword ptr ss[esp+0x90] GetModuleFileNameExA;根据进程句柄获取进程文件名
这里循环遍历进程,取得所有进程的加载的模块信息以及进程文件信息

0x5
程序启动时send断下来
Call to send from CMClient.005429F4
Socket = 0x308
Data = 001CF7A0
DataSize = 97
Flags = 0
此处为Data内容
图片2.png

继续运行,在rand处断下,分析为第二段的内容,往下跟应该会有创建进程文件等操作
Push 0xFF ;255
Push eax
Call dword ptr ds:[0x42D800] ;ws2_32.gethostname 获取本机名称
Lea ecx,dword ptr ss:[esp+0x14]
Push ecx
Call dword ptr ds:[0x42D80C] ;ws2_32.gethostbyname

图片3.png
Call dword ptr ds:[0x42D11C];kernel32.GetComputerNameA
图片4.png

Call dword ptr ds:[0x42D7E8] ;ws2_32.socket
Mov edi,dword ptr ds:[0x42D7C4] ; ws2_32.WASCreateEvent
Call edi
Call dword ptr ds:[0x42D7E4] ;ws2_32.ntohs
Call dword ptr ds:[0x42D7F8] ;ws2_32.bind
上面部分是socket操作,取得本机的一些信息,下面创建线程,设置线程优先级,至此“随机进程”还未出现,操作应该还在后面
00419515   
mov edi,dword ptr ds:[0x42D10C] ; kernel32.CreateThread 创建线程
lea edx,dword ptr ss:[esp+0x8]
push ebx
push edx
push 0x0
push esi
push MainPro.0041ADC0
push 0x0
push 0x0
Call edi

Mov ebx,dword ptr ds:[0x42D198]  ;kernel32.SetThreadPriority 设置线程优先级
Push 0xF
Push eax
Mov dword ptr ds:[esi+0x164],eax
Call ebx

rand函数地址004198f5
字符串地址00434244“以连接到服务器”
思路:根据测试情况,MainPro.exe在连接服务器后会产生随机进程,因此在00434244出下断,说明已经连接服务器,创建进程的动作应该在后面,跟进。
此后的操作Call 004126A0
Call 004068A0
Call 00411C20
Call 004123A0
Call dword ptr ds:[0x42D108] kernel32.CreateProcessA在004125E6此处找到了进程创建操作,在这之上调用了GetSystemDirectory取得windows的系统目录。

IDA找到代码位置直接F5看操作。


v1处应为string(“xxx”),把v1的值拷贝给ComnandLine,之后调用CreateProcessA创建进程。
分析到此完成。


图片5.png





图片6.png


MainPro.exe启动后进程的的监控情况,驱动实现,原理:利用PsSetCreateProcessNotifyRoutine函数。


[C++] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
还原了SysStart.sys的部分代码
 
NTSTATUS sub_4010E0(PCWSTR SourceString,PCWSTR String1)
{
        UNICODE_STRING DestinationString;
         
        /*
        VOID
    RtlInitUnicodeString(
                                                        IN OUT PUNICODE_STRING  DestinationString,
                                                        IN PCWSTR  SourceString
    );
        */
        NTSTATUS var_28 = 0;
        UNICODE_STRING ValueName;
        RtlInitUnicodeString(&DestinationString,SourceString);
        RtlInitUnicodeString(&ValueName,SourceString);
         
        ObjectAttributes.Length                   = 0x18;
        ObjectAttributes.RootDirectory            = 0;
        ObjectAttributes.Attrbutes                = 0x40;
        ObjectAttributes.ObjectName               = &DestinationString;
        ObjectAttributes.SecurityDescriptor       = 0;
        ObjectAttributes.SecurityQualityOfService = 0;
         
        /*
        NTSTATUS
    ZwOpenKey(
                                OUT PHANDLE  KeyHandle,
                                IN ACCESS_MASK  DesiredAccess,
                                IN POBJECT_ATTRIBUTES  ObjectAttributes
    );
        */
        HANDLE KeyHandle;
        var_24 = ZwOpenKey(KeyHandle,0xF003,&ObjectAttributes);
        if(var_24 <= 0)
        {
                DbgPrint("ZwOpenKey Wrong\n");
                return;
        }
        else
        {
                SIZE_T NumberOfBytes;
        /*
        PVOID
        ExAllocatePool(
                                        IN POOL_TYPE  PoolType,
                                        IN SIZE_T  NumberOfBytes
    );
    */
                ExAllocatePool(0,NumberOfBytes);
         
        /*
        NTSTATUS
        ZwQueryValueKey(
                                                IN HANDLE  KeyHandle,
                                                IN PUNICODE_STRING  ValueName,
                                                IN KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass,
                                                OUT PVOID  KeyValueInformation,
                                                IN ULONG  Length,
                                                OUT PULONG  ResultLength
    );
        */       
        NumberOfBytes = 0x110;
        var_24 = ZwQueryValueKey(KeyHandle,&ValueName,2,KeyValueInformation,NumberOfBytes);
        if(var_24 >= 0)
        {
                 
        }
        else
        {
                DbgPrint("ZwQueryValueKey Wrong:%08x\n");
        }
         
        }
         
}
 
 
NTSTATUS sub_401450()
{
        HANDLE ThreadHandle;
        NTSTATUS v2;
        UNICODE_STRING DestinationString;
 
        KeInitializeEvent(&Event, SynchronizationEvent, 1u);
        RtlInitUnicodeString(&DestinationString, L"This is a string for test!\n");
        //创建系统线程
        v2 = PsCreateSystemThread(&ThreadHandle, 0, 0, 0, &ClientId, StartRoutine, &DestinationString);
        if ( ThreadHandle )
        {
                PsLookupThreadByThreadId(ClientId.UniqueThread, &Object);//查找ETHREAD
        }               
        if ( v2 < 0 )
        {
                DbgPrint(aTestCreatethre);//"[Test] CreateThread Test Failed!\n"
        }
         
        ZwClose(ThreadHandle);
        return KeWaitForSingleObject(&Event, 0, 0, 0, 0);
}
 
void StartRoutine(PVOID StartContext)
{
        KeSetEvent(&Event,0,0);
        while(!byte_4044CC)
        {
                dword_4044C0 = 1;
                sub_4013C0(5000);
                if ( dword_4044C0 == 1 && dword_404000 == 1 )
                {
                  if ( dword_4044C4 )
                  {
                        DbgPrint(aNtshutdownsyst);
                        //关闭计算机
                        NtShutdownSystem(0);
                  }
                  else
                  {
                        dword_4044C4 = 1;
                        DbgPrint(aFirstNtshutdow);//"First NtShutdownSystem\n"
                  }
                }
                if ( dword_404000 == 2 )
                {
                        sub_4013C0(5000);
                }         
        }
         
}

[C++] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
进程监控的代码。
#include <ntifs.h>
#include "ntddk.h"
#define MAX_PATH 256
  
// 获取进程路径
VOID GetProcessPath(ULONG eprocess, PUNICODE_STRING pFilePath)
{
        ULONG                        object;
        PFILE_OBJECT        FilePointer;
        UNICODE_STRING        name;  //盘符
  
        // EPROCESS -> SectionObject
        if(MmIsAddressValid((PULONG)(eprocess + 0x138)))
        {
                object = (*(PULONG)(eprocess + 0x138));
                // SECTION_OBJECT -> Segment
                if(MmIsAddressValid((PULONG)((ULONG)object + 0x014)))
                {
                        object = *(PULONG)((ULONG)object + 0x014);
                        // SEGMENT_OBJECT -> ControlArea
                        // 不是0x018
                        if(MmIsAddressValid((PULONG)((ULONG)object + 0x0)))
                        {
                                object = *(PULONG)((ULONG_PTR)object + 0x0);
                                // CONTROL_AREA -> FilePointer
                                if(MmIsAddressValid((PULONG)((ULONG)object + 0x024)))
                                {
                                        object=*(PULONG)((ULONG)object + 0x024);
                                }
                                else return ;
                        }
                        else return ;
                }
                else return ;
        }
        else return ;
  
        FilePointer = (PFILE_OBJECT)object;
        ObReferenceObjectByPointer(
                (PVOID)FilePointer,
                0,
                NULL,
                KernelMode);
        RtlVolumeDeviceToDosName(FilePointer->DeviceObject, &name); //获取盘符名
        RtlCopyUnicodeString(pFilePath, &name); //盘符连接
        RtlAppendUnicodeStringToString(pFilePath, &FilePointer->FileName); //路径连接
        ObDereferenceObject(FilePointer);                //关闭对象引用
}
  
VOID ProcessNotifyRoutine(
                IN HANDLE        ParentId,
                IN HANDLE        ProcessId,
                IN BOOLEAN        Create
    )
{
        NTSTATUS                status = STATUS_SUCCESS;
        PEPROCESS                pEprocess = NULL;
        UNICODE_STRING         uniPath;
  
        uniPath.Length = 0;
        uniPath.MaximumLength = MAX_PATH * 2;
        uniPath.Buffer = (PWSTR)ExAllocatePool(NonPagedPool, uniPath.MaximumLength);
  
        // 创建进程
        if (Create)
        {
                DbgPrint("*******----有----新----进----程----创----建----*******\r\n");
                //父进程
                DbgPrint("父进程信息\r\n");
                DbgPrint("        PID:  %d\r\n", ParentId);
                status = PsLookupProcessByProcessId(ParentId, &pEprocess);
                 if (NT_SUCCESS(status))
                {
                        GetProcessPath(pEprocess, &uniPath);
                        DbgPrint("        路径: %wZ\r\n", &uniPath);
                }
                // 进程
                DbgPrint("创建进程信息\r\n");
                DbgPrint("        PID:  %d\r\n", ProcessId);
                status = PsLookupProcessByProcessId(ProcessId, &pEprocess);
                if (NT_SUCCESS(status))
                {
                        GetProcessPath(pEprocess, &uniPath);
                        DbgPrint("        路径: %wZ\r\n", &uniPath);
                }
        }
        // 结束进程
        else
        {
                DbgPrint("*******----有----旧----进----程----退----出----*******\r\n");
                // 父进程
                //DbgPrint("父进程信息\r\n");
                //DbgPrint("        PID:  %d\r\n", ParentId);
                //status = PsLookupProcessByProcessId(ParentId, &pEprocess);
                //if (NT_SUCCESS(status))
                //{
                //        GetProcessPath(pEprocess, &uniPath);
                //        DbgPrint("        路径: %wZ\r\n", &uniPath);
                //}
                // 进程
                DbgPrint("退出进程信息\r\n");
                DbgPrint("        PID:  %d\r\n", ProcessId);
                status = PsLookupProcessByProcessId(ProcessId, &pEprocess);
                if (NT_SUCCESS(status))
                {
                        GetProcessPath(pEprocess, &uniPath);
                        DbgPrint("        路径: %wZ\r\n", &uniPath);
                }
        }
        ExFreePool(uniPath.Buffer);
}
  
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
        NTSTATUS status;
        DbgPrint("Stop Process Create/Delete Mon\r\n");
  
        status = PsSetCreateProcessNotifyRoutine(ProcessNotifyRoutine, TRUE);
    if (!NT_SUCCESS(status))
        {
        DbgPrint("Call PsSetCreateProcessNotifyRoutine Error!\r\n");
                DbgPrint("Status Code: 0x%08X", status);
    }
}
  
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,
                                        PUNICODE_STRING pRegistryPath)
{
        NTSTATUS status = STATUS_SUCCESS;
        DbgPrint("Start Process Create/Delete Mon\r\n");
  
        pDriverObject->DriverUnload = DriverUnload;
  
        status = PsSetCreateProcessNotifyRoutine(ProcessNotifyRoutine, FALSE);
    if (!NT_SUCCESS(status))
        {
        DbgPrint("Call PsSetCreateProcessNotifyRoutine Error!\r\n");
                DbgPrint("Status Code: 0x%08X", status);
        return status;
    }
  
        return status;
}

免费评分

参与人数 2热心值 +2 收起 理由
Mr.Mlwareson_V + 1 鼓励转贴优秀软件安全工具和文档!
Hyabcd + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

我只做我自己 发表于 2015-11-16 19:39
网吧有公安部门安装的监控软件,你可以分析分析,爆爆菊花啥的
pleianth 发表于 2015-11-23 12:02 来自手机
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-3-27 08:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表