[toc]
#运行效果
##查壳
### 静态分析
####基础动态分析
##### 动态分析
运行效果
拿到了样本,在虚拟机中运行了一下,结果如下
每隔一段时间就会启动浏览器,访问一个固定的网址。访问的是wormvirous这个网址,推测可能是个加载器或者后门,我们打开任务管理器发现找不到进程,恢复快照到虚拟机感染病毒之前的状态,下面开始来分析
查壳
无壳
静态分析
strings查看字符串
这里看到了sleep函数,源程序应该调用了sleep函数睡眠一个定长时间然后唤醒,这也是为什么网页间隔一段时间弹出来的原因,DeviceIoControl可以通过设备句柄向内核驱动发送数据,CreateFileA表明创建了一个文件,CloseServiceHandle StartServiceA CreateServiceA OpenSCManagerA 告诉我们这个程序创建并启动了一个服务,OleUninitialize与OleInitialize表明可能调用了COM库,CoCreateInstance表明可能创建与指定的CLSID关联的类的单个未初始化对象。GetOEMCP返回操作系统的当前原始设备制造商的代码页标识符。
在C:\Windows\System32\目录下创建了virousal.sys文件,下面分析该驱动
IoGetCurrentProcess调用表明这个驱动可能修改正在运行的程序,或者需要该进程的信息。
这里我们看到了网址和驱动安装的目录
dependencewalker可以看到导入函数,我们用strings工具已经分析过了,这里可以验证一下
驱动程序
基础动态分析
打开processexplorer运行程序,发现列表中没有forge进程,和任务浏览器一样,只有浏览器进程,说明用了进程隐藏技术,
processname过滤forge.exe,procmon一片空白
动态分析
因为程序没有在WInDBG和OllyDbg的进程列表中显示,所以我们也不能附加一个调试器到进程。
将可执行文件载入IDA
这里,从OpenSCManagerA到DeviceIoControl之间一系列的函数调用,主要是加载和发送请求到内核驱动函数,程序创建了一个叫做Process Helper的服务,它负责加载内核驱动 C:\Windows\System32\virousal.sys,然后启动了Process Helper服务,加载virousal.sys到内核并且打开了句柄\\.\ProcHelper,打开了一个由ProcHelper驱动创建的内核设备句柄继续往下看
这里是一个COM对象的使用,在分析strings的返回结果的时候我们就猜测到了,这里验证了我们的猜想,除此之外,还有一个对ecx+0x2c的调用,
DeviceIoControl将控制代码直接发送到指定的设备驱动程序,使相应的设备执行相应的操作,这里参数LpOutBuffer和LpInBuffer都为0,意思是这个请求没有发送任何信息到内核驱动,而且内核驱动也没有反馈任何信息,这个DeviceIoControl干嘛了呢
下面初始化了COM,调用OleInitialize和CoCreateInstance获得一个COM对象,返回的COM对象被保存在栈上的一个变量中,IDA将它标识为ppv,查看CLSID以及IID判断这个程序使用了COM的什么功能
判断会调用哪个程序,在注册表中查找这个CLSID,这个IID是IWebBrowser2,这个CLSID对应Internet Explorer
40110f处eax被解引用ecx指向这个COM对象的基地址,40111e处,对象中偏移0x2c处的函数被调用,IWebBrowser2接口的偏移0x2c处是Navigate函数,这个函数将Internet Explorer的网址导航到wormvirous这个网址,之后会睡眠一段时间,然后循环。
将内核文件加载入IDA
跟到sub_10706
光标处调用了IoCreateDevice,创建了一个名为\Device\ProHelper的设备
然后在光标处调用了IoCreateSymbolicLink函数,创建了\DosDevices\ProcHelper的符号连接,用来供用户态的应用程序访问
sub_10666
sub_1062A主要负责收尾工作
用WinDBG进行内核调试
已知设备名查找设备对象
设备对象: 81873030 驱动对象: 81f9f680
驱动对象包含所有函数的指针当用户空间的程序访问设备对象时调用这些函数
分析一下MajorFunction
一共28个,驱动代码都是在这里完成的,表中的每一项表示驱动可以处理的不同类型的请求,包括我们要找的恶意代码
这里有多个一样的 0x804f454a
查看一下是什么函数
这个函数为IopInvalidDeviceRequest,它处理驱动无法处理的非法请求
查看其他函数
偏移0和偏移2处的 f8d95606 偏移14处的 f8d95666
上网百度了一下MajorFunction对应的函数,如下
查看一下f8d95606处的函数
它只调用了IofCompleteRequest函数然后返回.
再看一下f8d95666处的函数
这里WinDbg卡死了,重启了一下,
查看DeviceIoControl的代码
查看到IDA的映射
DeviceIoControl做的第一件事就是调用IoGetCurrentProcess,它返回DeviceIoControl进程的EPROCESS结构,然后访问EPROCESS 结构0x88处的数据,然后在10682处又访问了0x8c处的数据
我们在WinDBG中查看一下EPROCESS的结构
0x88处是_LIST_ENTRY结构,0x8c处位于_LIST_ENTRY结构体中,_LIST_ENTRY结构是一个双向链表,BLINK指向链表中的前一项,FLINK指向链表中的下一项
结构如下,
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink; // 指向下一个节点
struct _LIST_ENTRY *Blink; // 指向前一个节点
} LIST_ENTRY, *PLIST_ENTRY;
0x8c处是下一个节点的指针,看下程序是如何操作的
第一行取指向下一项的指针,第三行获取链表中指向前一项的指针,第四行覆盖BLINK,使其指向前一项,在此之前下一项的BLINK指向当前项.
第四行覆盖BLINK指针使它跳过了当前指针,下面三行执行相同的步骤,修改了前一个EPROCESS和后一个EPROCESS结构,使前一个的FIINK指向下一个EPROCESS的_LIST_ENTRY结构,使后一个EPROCESS的BLINK指向前一个的_LIST_ENTRY结构,这里注意一下,不管是BLINK还是FIINK,都不是指向EPROCESS的开头,而是指向EPROCESS中的_LIST_ENTRY结构,所以如果想得到EPROCESS头的话还需要将BLINK或者FIINK的值减去一个数.
当OS遍历进程链表时,隐藏进程总是被跳过,这也是我们在任务管理器中看不到进程的原因,任务管理器也是基于遍历链表取得进程的.有些第三方工具可能也是基于这个原理查找进程的,当然隐藏进程的方法也不止这一种.
(字草勿喷,呃呃)
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法