这个木马隐蔽性很强,内存中不存在任何明文字符串,很难用内存搜索去搜索一些明显字符串,内存的数据都是加密存在需要时才解密,然后立即释放,不会长期驻留在内存,所有的内容计算校验使用的是hash值来对比查找,而且还是用双重加密,给分析人员增加了不小的难度,
上次讲到此木马在内存里有个加密的pe文件存在,接下来我们就来讲解这个从内存里扣出来的pe文件到底怎么工作的。
在入口点,通过hash对比去查找ntdll.dll,kernel32.dll的模块句柄,而不是通过我们常用的方法GetMoudleHanlde()的方法去获取句柄,
看看serverlog_search_moudle这个函数的实现,在函数内部使用了[[[FS:[30]+0xc]+0xc]+0×30]的方法去获取模块的名字,在ring3层FS寄存器指向的是线程环境块,0×30的偏移即指向PEB(进程环境块),PEB的0xc就是指向LDR表,后面的偏移就是从LDR表中获取模块的BaseName,计算相应的hash对比去从LDR表中获取模块的句柄。
获取了模块首地址后,通过解密.data节段的加密导入表来获取相应的函数地址
下面是获取到的ntdll的对应函数表
下面是获取的kernel32的对应函数表
接下来就进入了init初始化的工作
首先会创建一个事件加一个互斥体
当这个mutex互斥体之前不存在时会再次把自身进程启动一遍,如果互斥体存在就进入的工作的函数里,这样也是为了多进程的方式。当进入工作函数server_get_info_and_timer时,就表示木马已经开始真正的工作了。工作初期木马会再次获取他所需的函数表,方式类似之前不再赘诉,他要获取advapi32.dll、ole32.dll、shell32.dll、crypt32.dll、urlmon.dll、wininet.dll的所需函数,如下:
然后木马会获取windows目录,然后计算系统目录所在的磁盘的磁盘id。
接下来就是取当前电脑的电脑+磁盘id的组合,并且根据磁盘id来计算当前电脑所要生成的服务程序的名字。
服务的名字是根据之前磁盘id, 在字符串“agent,app,audio,bio,bits,cache,card,cart,cert,com,
crypt,dcom,defrag,device,dhcp,dns,event,evt,flt,gdi,group,
help,home,host,info,iso,launch,log,logon,lookup,man,math,
mgmt,msi,ncb,net,nv,nvidia,proc,prop,prov,provider,reg,rpc,
screen,search“中计算出对应的字符来填充组合成所要生成的服务名和exe的名字。
得到本木马服务的exe名字后就计算系统目录里的木马exe的crc的值
接下来就是获取电脑名,并且会将电脑中的非0-9、a-z、A-Z的字符替换成X,并且最多只获取16个字符的名字,然后和磁盘id组合起来
接着木马就会使用CreateTimerQueueTimer函数创建一个Timer计时器,
流程就进入了serverlog_posturl_timer函数空间
根据当前的运行状态执行同的逻辑,case 1:时表示木马正准备初始化,然后设置状态为2,定时器执行到case 2:时就会将本木马exe创建成一个windows服务,服务名就是之前计算出来的service_name, 然后设置成状态3,进入case 3:会填充一些IP地址与端口,IP地址和端口直接写死在.data节,可以看到内存里内置了很多IP与端口,0x1BB即433端口,1F90即8080端口
Case 3还会初始化加密上下文
使用的rsa算法,导入了内存里的publickey,0×13即RSA_CSP_PUBLICKEYBLOB
Case 3执行完毕会设置成状态4,下次定时器的时候就进入case 4,case 4会把枚举当前电脑的进程信息,木马的exe的crc,电脑名磁盘id填充到待加密的缓冲区
然后对以上进行加密,再post到服务器的433端口
注意在发送到433之前,木马再一次进行了rsa加密
经过双重加密后,一次自定义加密+一次rsa加密后,使用post的方式发送到服务器的433端口。
然后木马通过InternetReadFile
函数获取服务器的返回结果,通过双重解密,一次rsa解密,外加一次自定义解密后,这个结果会执行各种流程,其中有一个最重要的流程是从远程服务器去下载exe,并且执行。
如果有更新的木马会调用start_download_exe函数去实现自我更新
到此基本上木马所有主要工作流程都已经分析完毕,这个木马隐蔽性很强,内存中不存在任何明文字符串,很难用内存搜索去搜索一些明显字符串,内存的数据都是加密存在需要时才解密,然后立即释放,不会长期驻留在内存,所有的内容计算校验使用的是hash值来对比查找,而且还是用双重加密,给分析人员增加了不小的难度。