[病毒分析]WinDBG实战教学(1)


这里的实例选自《恶意代码分析与实战》第十章实验一
大家可以在这里下载哦

点击下载—提取码:8189

实验工具:
1、WinDBG
2、IDA
3、Dependency Walker

一、初始任务

我们将下载好的文件放到指定位置
C:\Windows\System32
在这里插入图片描述使用WinGDB 连接至虚拟机(CSDN中有很多关于WinDBG的初始教学,大家可以先看看)
出现下面的界面表示连接成功:
在这里插入图片描述

二、开始分析

第一步,我们使用Dependency Walker 做静态分析
在这里插入图片描述然后我们可以发现第一个DLL里面导入了这么几个函数

ControlService
CreateServiceA
OpenSCManagerA
OpenServiceA
StartServiceA

第二个DLL导入了这么几个函数
在这里插入图片描述内容很多,但是我们要清楚,我们最最应该关注的是Create和Write

第二步,我们打开IDA查看String
在这里插入图片描述在这里插入图片描述在上图红框中的文件地址,告诉了我们,这个程序会去调用这个sys文件

第三步,分析sys文件
在这里插入图片描述按照书上的说法,第一个函数KeTickCount是所有驱动都会包含的一个函数,这个可以忽略

然后第二个RtlCreateRegistryKey和第三个RtlWriteRegistryValue,看到这个Registry我们就大概知道这个操作是和注册表有关的操作,然后一个是Create一个是Write,所以这个是创建和写入注册表的操作

第四步,procmon检查
procmon的教学,我曾经发过一篇博客大家可以看看
Proncmon的基础教学,点击查看
在这里插入图片描述我们自己查看Procmon给我们反馈的消息,我们从中找到几个核心的东西:
在这里插入图片描述
在这里插入图片描述在程序的上部,我们可以看到:
在这里插入图片描述在运行过了Lab10-01.exe之后,起了一个线程,也就是Thread Create,然后加载了一个DLL,然后创建了一个文件,C:\WINDOWS\system32\Lab10-01.EXE-04045C98.pf,然后RegOpenKey打开一个键,结果是Read:在这里插入图片描述
在这里插入图片描述这个操作改变了键值,改变了一个加密用的种子值

三、分析代码

我们还是回到IDA中

在这里插入图片描述
这里首先调用了一个OpenSCManagerA,这里是:在指定的计算机上建立与服务控制管理器的连接,并打开指定的服务控制管理器数据库。

如果失败,返回的NULL,然后这里用test测试了返回值,test指令是和and类似的,如果返回的是NULL,test之后,结果为0,则ZF=1,JNZ不会跳转,继续执行,走红线,然后就返回了

如果没有失败,我们继续往下走
在这里插入图片描述往下走就是这里,之类调用了CreateServiceA这个函数,可以看出这个服务的名字就是Lab10-01,然后访问权限dwDesiredAccess是SERVICE_ALL_ACCESS,最后需要注意的就是lpBinaryPathName,这个的值是"C:\Windows\System32\Lab10-01.sys",意味着服务起来的时候会去加载这个二进制文件,一样的,这个函数调用失败会返回NULL
在这里,如果函数失败,返回NULL,test之后,ZF=1,然后JNZ不会跳转,所以函数失败之后,会继续走红线,也就这写代码。
在这里插入图片描述
这里调用了OpenServiceA,如果上面这个OpenServiceA失败,然后会继续通过StartServiceA来开启这个服务

这些操作,只要一个成功了,就会直接一个JZ跳转然后返回了,如果失败,则继续往下尝试另外的函数
在这里插入图片描述然后我们继续分析,这次我们分析Lab10-01.sys

我们找到驱动的入口点,然后查找

在这里插入图片描述

mov edi, edi
push ebp
mov ebp, esp

这些操作是在调用函数之前的初始化栈空间操作,如果你好好分析就会知道,这些操作会在栈上重新分配一些空间给要调用的函数,对我们分析来说,无关紧要,然后之后就调用了sub_10920,我们进去看看,这里执行的是驱动函数的一些必要操作。

在这里插入图片描述

然后我们退出来,看看下一个函数sub_10906

在这里插入图片描述上图中出现了一个函数的赋值,sub_10486,然后我们进去看看就会发现这个

在这里插入图片描述这个函数会调用RtlCreateRegistryKey这个内核函数来创建一个键在\Registry\Machine\SOFTWARE\Policies\Microsoft,然后设置为0

然后下一个调用是
在这里插入图片描述再下面也是一样的\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFire,然后写入的信息是wall\StandarProfile为0
在这里插入图片描述入参是这么几个
在这里插入图片描述

然后我们看看这个Path的路径是多少,在这里的ebx显示是这样的,他被赋值为aRegistryMach_2之后就没被改变过了

在这里插入图片描述
所以这里的Path的值就是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFire,然后值为wall\DomainProfile, 0

然后ValueName的值是edi,在IDA里查找最后改变edi的值

在这里插入图片描述

最上面那里一个mov赋值之后就没有改变过了,然后这个ValueName的值是一个dw类型的,也就是E

在这里插入图片描述

总结一下这个函数做了什么:
RtlWriteRegistryValue例程将调用方提供的数据以指定的值名称写入指定的相对路径。

这里会将\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFire\wall\DomainProfile的值写入成45h

四、WinDBG调试

问题:用户态的程序调试了ControlService函数,用Windbg设置一个断点,来观察ControlService的调试导致内核执行了怎么样的操作?

我们先在IDA中找到ControlService
在这里插入图片描述
在这里插入图片描述
然后找到地址为401080,我们在OD里面加载断点
在这里插入图片描述然后执行到这里
在这里插入图片描述
然后我们现在可以跳出虚拟机了,Windbg发送break然后暂停虚拟机的运行

在这里插入图片描述
我们已经暂停了虚拟机的执行,Windbg在等待我们的输入

我们输入!drvobj Lab10-01, 我在Win10物理机上做是有点慢,慢慢的才会出结果来,等一下
在这里插入图片描述

dt _DRIVER_OBJECT 81b7cf38

在这里插入图片描述我们查看在0x034偏移DriverUnload(驱动程序卸载)的这个地方的值,这里有个DriverUnload的函数,这个偏移的地址是0xf8aae486

下面我们在这个地址这里设置一个断点,来查看这里发生了什么(这个断点用物理机上的WinDbg设置)

bp 81b7cf38

在这里插入图片描述
这里在和大家说明一下,系统为我们分配的地址每次都是不一样的,大家要根据自己的实际情况进行复现。
下一步,我们回到虚拟机中,F9运行OD。
这里我们的断点已经被命中,然后我们继续,这时候虚拟机也已经暂停了运行,下面我们执行单步调试,WinDbg的单步调试对话框输入p就可以了。

在这里插入图片描述

我们一直使用P指令,可以看到一个块领空的全部汇编语句,如下

push ecx
push ebx
push esi
move esi, dword ptr [Lab10_01+0x780 f(f8aae780)]
push edi
xor  edi, edi
push offset Lab10_01+0x6bc(f8aae6bc)
push edi
mov  dword ptr [ebp-4], edi
call esi

这个时候我们需要指导call的这个esi究竟是什么函数
使用指令

u esi

在这里插入图片描述
RtlCreateRegistryKey调用,大家可以百度一下看看官方是如何定义这个函数的

有两个入参,第一个入参是edi,即RelativeTo=edi,第二个是offset Lab10_01+0x6bc(f8aae6bc),即Path=offset Lab10_01+0x6bc(f8aae6bc)

在这里插入图片描述
这里的RelativeTo的值为0,接下来我们看看Path的值,这里我们先用da命令
在地址f8aae6bc处的值的ASCII是\,当然,这样对查看单个地址上的数据比较有用,如果数据很多,要查看的话,我们用dc命令

在这里插入图片描述
在这里插入图片描述
这里的Path的值就是\Registry\Machine\SOFTWARE\Policies\Microsoft,然后后面就是全0的截断符了

然后下面又是一个相同的调用nt!RtlCreateRegistryKey,edi的值没有改变还是0,我们看看f7a54640的值

push offset Lab10_01+0x640(f7a54640)
push edi
call esi

在这里插入图片描述
注意这里下面被圈红的截断符(web渗透里面叫截断符’\00’,计算机里面叫文件结束符),这里我们得出的Path是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall

从字面意思应该可以大概知道这个注册表是关于防火墙的

继续下面的汇编代码
还是一个nt!RtlCreateRegistryKey调用,和上面两个片段类似

edi至今未变,我们看看Path的值
在这里插入图片描述
这里还未出现文件结束符,说明这里还有数据没有显示出来,我们跳到最后显示这个地址继续显示
在这里插入图片描述
我们可以得出这次调用的Path的值是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile

这里的esi还是未变,我们看看Path的值,如上图

依旧是一次未能显示全,我们往下跳
可得出Path的值就是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\StandardProfile

所以应该是调用了四次nt!RtlCreateRegistryKey(书中有误),然后依次创建的键路径在如下所示

\Registry\Machine\SOFTWARE\Policies\Microsoft
\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall
\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile
\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\StandardProfile

然后我们继续往下分析,下面的代码如下

mov  esi, dword ptr [Lab10_01+0x788(f8aae5a8)]
push 4
lea  eax,[ebp-4]
push eax
push 4
mov  edi,offset Lab10_01+0x4ee(f8aae50c)
push edi
push offset Lab10_01+0x5a8(f8aae788)
push 0
call esi

遇到一个call函数了,这里的第一句已经改变了esi,再也不是那个nt!RtlCreateRegistryKey

我们看看这个函数是什么

在这里插入图片描述
是nt!RtlWriteRegistryValue,向注册表里面写入值的内核函数

这里对我们来说有意义的参数,一个是Path,这个Path的值我们查查应该是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile
,然后ValueName的值是EnableFirewall
在这里插入图片描述
然后下一个是ValueData的值是,这里的eax的值是[ebp-4]的值,所以我们找ebp-4的值

在这里插入图片描述
在这里插入图片描述
所以这个eax的值是0,这里的意思就是将EnableFirewall这个的值设置为了0,意义就是从内核禁止了Windows的防火墙功能

我们看看Path的值应该是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\StandardProfile

在这里插入图片描述然后ValueName的值是EnableFirewall
最后是ValueData的值是0

所以这里还是通过内核改变注册表\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\StandardProfile的键EnableFireawll为0来关闭防火墙

这个程序的整体思路:程序运行之后会启动一个服务,然后通过运行一个驱动创建修改注册表的值,来关闭防火墙。

注意:\Registry\Machine的开头很怪异,,并不是我们常见的HKEY的注册表。当从内核态王文注册表时,\Registry\Machine就等同于HKEY_LICAL_MACHINE。同时我们需要知道,EnableFirewall的值为0,表示禁用Windows XP的防火墙。

希望大家可以有所收获,windbg是一个非常强大但是入手很难的工具,共勉!

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鹏华李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值