首页
社区
课程
招聘
[原创]默默无闻·恶意代码分析第七章
发表于: 2021-4-7 20:34 7879

[原创]默默无闻·恶意代码分析第七章

2021-4-7 20:34
7879

[原创]默默无闻·恶意代码分析Lab1

[原创]默默无闻·恶意代码分析Lab5

[原创]默默无闻·恶意代码分析Lab6

参照书籍:《恶意代码分析实战》;

系统环境:Windows7 x86

使用工具:WinHex、CFF、StudyPE+、Exeinfo PE、Resource Hacker、Depends Walker、OD、IDA、MSDN;

这一章节还是比较重要的,总结了在逆向Windows恶意代码中可能遇到的形式;

所以此贴以知识点总结为主;

1、Windows API常见类型

2、句柄

多说无益,首先要了解的是:

​ 1、每个进程内核有句柄表;

​ 2、系统有一个全局句柄表;

​ 3、而句柄就是指向这些表的指针,所以句柄是有两种情况的;

参考书籍《Windows 核心编程》

3、文件系统

根据《恶意代码分析实战》中列出的函数,更多的在之前和以后的帖子中,或者查询MSDN(最有效,,最详细)

这些函数都是常被恶意代码用到的函数,比如可以模拟系统加载PE,写成一个加载器;

4、特殊文件

Windows系统中的特殊文件类型,这些文件在目录中不会显示出来,某些特殊文件可以提供对系统硬件和内部数据更强的访问能力;

书中介绍了三种类型,分别是共享文件通过名字空间访问的文件备用数据流

4.1、共享文件

共享文件以\\serverName\share\\?\serverName\share开头命名的特殊文件;

4.2、通过名字空间访问的文件

名字空间可以被认为是固定数目的文件夹,每一个文件夹中保存不同类型的对象;

底层的名字空间是NT名字空间,以前缀\开始。

NT名字空间可以访问所有设备,以及所有在NT名字空间中存在的其它名字空间;

使用WinObj对象管理器名字空间查看器查看名字空间;

从Windows 2003 SP1开始,Device\PhysicalMemory从用户空间已经无法访问。但是可以从内核空间访问由此可见,反病毒要把内核学好才行。

4.3、备用数据流

备用数据流(ADS)特性允许附加数据被添加到一个已存在 的MTFS文件;

就是添加一个文件到另外一个文件中,额外数据在列一个目录时不会被显示出来,只有在访问流时,它才可见;

Malware作者喜欢ADS,因为它能被用来隐藏数据;

5、Windows 注册表

注册表用来保存操作系统与程序的配置信息,例如设置和选项;

恶意代码经常使用注册表来完成持久驻留或者存储配置数据

注册表术语:

5.1、注册表根键

两个最常用的根键是HKLMHKCU(这些键通常通过它们的缩写来引用)。

一些键实际是虚拟键值,提供一种引用底层注册表信息的方式:

​ 例如,HKEY_CURRENT_USER键实际上存储在HKEY_USERS\SID中,这里的SID是当前登陆用户的安全描述符;

​ 例如,一个常用的子健,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run,包含一系列值,这些值列举了当一个用户登陆时被自动启动的可执行程序。
根键是HKEY_LOCAL_MACHINE,它保存了SOFTWAREMicrosoftWindowsCurrentVersion以及Run子键;

5.2、Regedit

快捷键win+r,然后在运行窗口输入regedit,打开注册表编辑器;

5.2.1、自启动程序查找

image-20210407152317840

根据选框中的路径查找(这是用windows10本机查找的);

5.2.2、常用注册表函数

如果在实战中遇到Malware访问一些键值时,可以通过搜索引擎寻找相关信息;

5.2.4、使用.reg文件的注册表脚本

.reg作为扩展的文件包含一个人类可读的注册表数据;

运行.reg文件,它会自动通过合并文件包含的信息到注册表中,来修改注册表;(几乎像一个脚本)

实例:

image-20210407153808634

image-20210407162935721

这是Microsoft官网的教程:如何使用 .reg 文件添加、修改或删除注册表子项和值

6、网络API

这是Malware经常用到的东西了;

6.1、伯克利兼容套接字

最常使用的套接字,因为其功能在Windows和UNIX系统上是几乎一样的;

Windows系统中是由Winsock库实现的,主要在ws2_32.dll中,下表给出了对一些常用函数的描述;

WSAStartup函数必须要在其它网络函数之前被调用,以便为这些网络库分配资源;
当调试代码查找网络连接入口时,在WSAStartup函数中设置一个断点,是非常有效的方式;

6.2、网络的服务器和客户端

一个网络程序通常有两个端点:

​ 服务端:它维护一个打开套接字并等待入站连接;
​ 客户端:它连接到一个正在等待的套接字;

恶意代码可以是任意一个!!!

6.3、WinINet API

除了Winsock API以外,还有一个叫WinInetAPI的更高级的Windows API(这里的高级是指ISO/OSI网络体系结构和TCP/IP协议模型中的相对位置);

WinInet API实现了应用层协议,如HTTP和FTP,通过判断打开的是何种连接,来理解它的功能;

7、跟踪恶意代码的运行

7.1、DLL

DLL本身是不能运行的,但是它可以导出函数,给其它应用程序调用;

DLL的基本结构:

​ 1、dll和exe文件都使用PE文件格式,有一个专门字段(File_Header.Characteristics)描述具体是哪个文件;
​ 2、通常DLL导出函数,导出函数多,导入函数少;
​ 3、DLL的主函数是DllMain,它并不是导出函数,只是在PE中被描述为入口点。
​ 4、任何时候一个进程加载或卸载库,会创建一个新进程,或是一个已存在的线程结束时,DllMain函数会被调用来通知DLL,这个通知允许DLL来管理每个进程或线程的资源;
​ 5、多数DLL没有线程粒度的资源,并且它们忽略由线程活动引起DllMain的调用;
​ 5.1、如果DLL必须在线程粒度进行管理的资源,那么这些资源可以为分析师提供一些提示,来了解这个DLL目的;

恶意代码是如何使用DLL的呢?

将Malware保存到一个DLL文件,然后附加到其它进程;

任何程序都能使用系统上的Windows基础DLL程序,通过查看Malware的导入表中的Windows API,可以猜测实现了什么功能;

除了系统的基础DLL,还可以使用第三方的DLL;
例如:

​ 使用Mozilla Firefox DLL来连接服务器;
​ 自定义的DLL和Malware(exe文件)一同发布;

7.2、进程

恶意代码可以通过创建一个新进程,或修改一个已存在的进程,来执行当前程序之外的代码;

传统上,恶意代码包括它自己的独立进程(独立恶意行为程序);
现在更普遍的是将自身代码作为其它进程的一部分执行(导入表注入之类的操作);
这就好比,前者是一匹狼,后者是个披着羊皮的狼;

创建进程函数CreateProcess,MSDN中描述:

7.3、线程

这里我们学习操作系统的时候描述的更清楚,这里就简单描述;

一个进程中有多个线程;

进程是执行代码的容器,线程才是Windows操作系统真正要执行的内容;

相同进程中的不同线程共享内存空间,但是每个线程有独立的寄存器和栈,独享处理器;

线程上下文跳转

当一个线程运行时,它独享CPU,并且其它线程不能影响CPU或核的状态;
当一个线程改变CPU中某个寄存器值时,它不会影响其它线程;
操作系统在线程间切换之前,CPU中所有值都被保存在一个叫做线程上下文的结构体中;
操作系统加载新线程的线程上下文结构体,使这个线程在CPU中执行;

创建进程函数CreateThread,MSDN中描述:

微软还使用了纤程。纤程是被线程管理的;
可以简单的理解成:进程包含线程,线程包含纤程;

7.4、使用互斥量的进程间协作

一个和线程与进程相关的话题是互斥量(mutex);
内核中称为互斥门(mutant);
互斥量是全局对象,用于协调多个进程和线程;

同一时刻只有一个线程拥有一个互斥量,通过互斥量来控制共享资源的访问;

更多细节查看多线程编程相关书籍;

7.5、服务

恶意代码执行附加代码的另一种方式是将它作为服务安装。

Windows允许通过使用服务,来使任务作为后台应用程序运行,而不需要它们自己的进程或线程,代码被Windows服务管理器 调度和运行,但没有用户输入;

在Windows操作系统上的任何指定实践,都会有多个服务在运行;

服务是提供系统上持久化驻留的另外一种方式,因为它可以被设置成当操作系统启动时自动运行,甚至不会在任务管理器中作为进程显示出来;
net start命令可以列举处正在运行的服务。还可以通过Autoruns等工具查看更多细节

Windows操作系统支持多种服务类型,它们以独特的方式执行;

恶意代码最常用的是WIN32_SHARE_PROCESS类型,这种类型将这个服务的代码保存在一个DLL中,并且在一个共享的进程中组合多个不同的服务。
在任务管理器中,一个名叫svchost.exe进程的多个实例,它们在运行WIN32_SHARE_PROCESS类型的服务

WIN32_OWN_PROCESS类型有时也被使用,因为它在一个.exe文件中保存代码,而且作为一个独立进程运行;

本地系统上服务的信息被保存在注册表中,每个服务在HKLM\SYSTEM\CurrentControset\Service下面有一个子键;

image-20210407190605173

这里要说明的我是用Win10找的,用Win7效果一样;

image-20210407191132383

sc.exe使用官方文档

7.6、组件对象模型

微软组建对象模型(COM)是一个接口标准;
它使不同软件组件在不知道其它组件代码的接口规范时,互相之间可以进行调用;
分析使用COM的代码时,需要判断哪段代码会被作为一个COM函数进行调用运行;

更多细节请看《COM原理与应用》,这里只做一些总结;

CLSID、IID以及COM对象的使用

COM对象通过它们的全局唯一标识符(GUID),分为类型标识符(CLSID)以及接口标识符(IID),来进行访问。

Navigate函数允许一个程序启动Internet Explorer,并访问一个Web地址;

当一个程序调用CoCreateInstance函数时,操作系统使用注册表中的信息,来判断哪个文件包含被请求的COM代码;

对于在实战逆向中IDA Pro无法识别的COM组件函数,一个策略是检查头文件,以寻找在调用CoCreateInstance时指定的接口;这些文件包含在微软Visual Studio和平台SDK中,并且都能在互联网上找到;

例如:Navigate函数是在.h文件中的第12个函数,它对应的偏移0x2C处,所以在调用时就是+0x2C的偏移;

有些COM对象会被作为DLL实现,它们被加载到到COM客户端可执行文件的进程空间中;
当这个COM对象被安装成DLL加载时,CLSID的注册表项会包含子键InprocServer32,而不是LocalServer32;

COM服务器恶意代码

Malware实现了一个恶意COM服务器,使其被其它应用使用;

对于Malware来说,常用的COM服务器功能是通过浏览器帮助对象(BHO),这是Internet Explorer的第三方插件。
BHO没有限制,所以恶意代码作者使用它们在Internet Explorer进程中运行代码,这允许它们监控互联网流量、跟踪浏览器的使用,以及与互联网通信,而且并不使用它们自己的进程;

一个实现COM服务器的Malware通常很容易检测,因为导出了几个函数,包括DllCanUnloadNowDllGetClassObjectDllInstallDllRegisterServer,以及DllUnregisterServer,它们都必须由COM服务器软件导出;

7.6、异常:当事情出错时

异常机制允许一个程序在普通执行流程之外处理事件;

结构化异常处理(SEH)是Windows的异常处理机制。SEH是一个重要知识点,后续单独开一帖再补充吧

7.7、内核模式与用户模式

这个也是老生常谈的一个点了,内核模式(R0),用户模式(R3);

当一个Windows API函数操作内核结构体时,它会通过一个调用进入内核。在反汇编中SYSENTERSYSCALL或者INT 0x2E的存在,指明一个调用被使用进入到内核;

直接通过跳转从用户模式到内核模式是不可能的,这些指令使用查找表来定位一个预定义函数,从而在内核中执行代码;

所有运行在内核的进程共享资源和内存地址。内核模式代码有更少的安全检查。如果内核运行的代码执行并且包含无效指令,操作系统就不能继续运行,产生结果就是Windows蓝屏;

更多的内容,将后续单独开帖再做补充

7.8、原生API

原生API是用来和Windows进行交互的底层API,调用原生API函数可以绕过普通的Windows API;

这里的原始API指的是最接近内核的API接口,书中指的是Ntdll.dll
ntdll.dll的导出表中,同样的函数会同时有Nt前缀或Zw前缀;

关于Ntdll.dll的更多信息,查询在线资源

在分析Windows恶意程序时,Windows病毒的各种形式就显得尤为重要了;

光看书有点乏,就干脆写起了读书笔记,效果是好,就是进度有点慢了;

以上内容,欢迎大佬指点!

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2021-4-8 14:59 被平头猿小哥编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//