吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4787|回复: 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++] 纯文本查看 复制代码
还原了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++] 纯文本查看 复制代码
进程监控的代码。
#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, 2024-4-25 21:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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