明翰恶意软件分析笔记V0.1(持续更新)

文章目录


恶意软件分析

易攻难守,
恶意代码很的很少,
防御代码写的多。

有的恶意软件,删了之后还会自己重新安装。

分析恶意软件可能需要花很长的时间,
可能持续1个月。

恶意软件可能有多个部分,不止一个文件,
内部文件可以转移。

你可以只能发现第2部分,却发现不了第1部分,
第2部分被清除后,第1部分可能会重新初始化第2部分。

恶意软件可以嵌入正常软件组件中,并被传播。
恶意软件的组件可以休眠一段时间,不运行,不被发现,
需要被特定的前置所触发、引发。

域名可以随机生成吗?怎么弄?
用随机域名来增加跟踪的难度,

起一些与正常软件&文件相似的名字来迷惑用户,
看日志时容易忽略。

可能会触发给一个DNS服务发请求,
可能得到IP地址和值,拿值后触发恶意软件的其他部分去通过HTTPS和内置地址去下载一些东西。

检查本机的DNS网络记录,
如果有定点往1个高仿的域名发请求,
可能就是中了恶意软件。

可以把一些恶意文件隐藏在系统文件夹中。

所有的恶意软件分析的顺序和步骤都是一样的。

不要把恶意软件放到一个文件夹里,
然后就不管了,
可能会被误点击。

把相关文件放进压缩包并设置一个简单密码,
不会被杀毒软件扫描到以及误操作。

一些常规软件也可以用于攻击,
这节课主要是在windows上进行的。

我们会用拿到一些分析软件,有一些基于Linux的,
有一些是基于Windows的。

Analysing the malware to understand what it does, how it got onto the system, what has it changed (what does it done ), what’s its purpose, who put it there? how it works, how to identify it, and how to defeat or eliminate it

有C,C++,汇编的经验会更好。

汇编需要能看懂和理解基础框架,
我们有工具,你不需要看的很流利,

恶意软件的作者可能会做一些加密,迷惑,
阻止我们去分析去阅读。

还可能侦测到你用特定的软件,
那恶意软件就不启动、退出、或休眠。

最后我们要去看在windows上,
X86、AMD64的机器码。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-edWQLpTQ-1630045248945)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p418)]

恶意软件能做什么

创建、修改、删除文件,包括删除自己,
对注册表的新增或修改,

可以把注册表里加一些东西,
让系统再调用正常文件时也把恶意文件调用。

自身形态千变万化

计算机病毒可以导致硬件故障,
例如伊朗核设施被入侵后导致离心机出现问题等。

国家之间经常进行这种网络攻击去瘫痪对方的系统。

病毒可以从一个电脑复制到另一台电脑,
会删文件,破坏硬盘等等。

恶意代码经常使用一些合法的dll或程序库来帮助自己完成目标。

恶意代码类型

先猜它是什么类型,能做什么,
然后去验证自己的猜想,可以加速分析过程。

一个恶意软件会横跨多个类型,可能会有键盘记录器来收集密码,同时发垃圾邮件+自我传播。

有些病毒是大众的,
有些病毒是专门为你而做的。

像勒索软件这样一般是大众传播,尽量多的感染更多的机器,比较简单,容易被杀毒软件查杀,
但特制恶意软件会更复杂,更难搞,杀毒软件无法帮你防御这种特制的东西。

  • 木马
    会伪装成某个东西的软件,你从网上下载游戏、或PDF,可能会下载到你不想要的东西。

  • 计算机病毒,蠕虫
    Worm or virus,自我复制,感染其他计算机,

  • 垃圾邮件
    Spam-sending malware,在被害者的主机上发送大量垃圾邮件,卖这个发送服务可以赚钱。

  • 间谍软件
    Information-stealing malware,监视用户的一举一动,包括记录各种账号密码等信息、尤其是邮箱、银行卡信用卡等,将这些敏感信息发送给攻击者。可以使用:sniffers, password hash grabbers, and keyloggers。

  • 勒索软件
    Scareware,恐吓受害者,并勒索他们购买。也可能是加密你所有的文件让你支付比特币,也可能是告诉你你浏览了恶意网站让你支付罚款等。

  • 僵尸网络
    Botnet,取自机器人robot的后半部分和网络network的前半部分。因此,僵尸网络的表面意思是由机器人组成的网络。允许控制者访问系统,执行命令从控制命令服务器中。

  • 下载器
    Downloader,只用来下载和安装其他恶意代码,获得系统访问后,先安装这个。

  • 启动器
    Launcher,用来启动其他恶意代码,用一些非传统手段来保证隐秘性。

  • 内核套件
    Rootkit,嵌入进系统,它的功能是在安装目标上隐藏自身及指定的文件、进程和网络链接等信息,比较多见到的是Rootkit一般都和木马、后门等其他恶意程序结合使用。持久并毫无察觉地驻留在目标计算机中,对系统进行操纵、并通过隐秘渠道收集数据的程序。Rootkit的三要素就是:隐藏、操纵、收集数据。“Rootkit”中root术语来自于unix领域。由于unix主机系统管理员账号为root账号,该账号拥有最小的安全限制,完全控制主机并拥有了管理员权限被称为“root”了这台电脑。然而能够“root”一台主机并不意味着能持续地控制它,因为管理员完全可能发现了主机遭受入侵并采取清理措施。因此Rootkit的初始含义就在于“能维持root权限的一套工具”。
    简单地说,Rootkit是一种特殊的恶意软件,它的功能是在安装目标上隐藏自身及指定的文件、进程和网络链接等信息,比较多见到的是Rootkit一般都和木马、后门等其他恶意程序结合使用。Rootkit通过加载特殊的驱动,修改系统内核,进而达到隐藏信息的目的。rootkit介绍Rootkit是一种奇特的程序,它具有隐身功能:无论静止时(作为文件存在),还是活动时,(作为进程存在),都不会被察觉。换句话说,这种程序可能一直存在于我们的计算机中,但我们却浑然不知,这一功能正是许多人梦寐以求的——不论是计算机黑客,还是计算机取证人员。黑客可以在入侵后置入Rootkit,秘密地窥探敏感信息,或等待时机,伺机而动;取证人员也可以利用Rootkit实时监控嫌疑人员的不法行为,它不仅能搜集证据,还有利于及时采取行动!
    Rootkit 的目的在于隐藏自己以及不被其他软件发现。它可以通过阻止用户识别和删除攻击者的软件来达到这个目的。Rootkit 几乎可以隐藏任何软件,包括文件服务器、键盘记录器、Botnet 和 Remailer。许多 Rootkit 甚至可以隐藏大型的文件集合并允许攻击者在您的计算机上保存许多文件,而您无法看到这些文件。
    Rootkit攻击方式多针对类似敏感数据剽窃这样的环节,那么某企业或政府组织“中央服务器”一类设备自然是植入Rootkit的首选目标,可这样的主机设备往往防护严密,不能轻易得手。我们知道数据并不是静止的存放在服务器中,它往往在机构的网络中流动。机构中级别较高的人员常会拥有对这些设备数据的读写权限,但他们所拥有的个人电脑的防护级别却通常比中央服务器要低,这就会给剽窃数据的黑客以可趁之机——将Rootkit程序植入相关人员的个人电脑,并默默的安家,不时地传回重要数据。

  • 后门
    Backdoor,后门是指绕过安全控制而获取对程序或系统访问权的方法。后门的最主要目的就是方便以后再次秘密进入或者控制系统,执行命令。主机上的后门来源主要有以下几种:
    攻击者利用欺骗的手段,通过发送电子邮件或者文件,并诱使主机的操作员打开或运行藏有木马程序的邮件或文件,这些木马程序就会在主机上创建一个后门。攻击者攻陷一台主机,获得其控制权后,在主机上建立后门,比如安装木马程序,以便下一次入侵时使用。还有一种后门是软件开发过程中引入的。在软件的开发阶段,程序员常会在软件内创建后门以方便测试或者修改程序中的缺陷,但在软件发布时,后门被有意或者无意忽视了,没有被删除,那么这个软件天生就存在后门,安装该软件的主机就不可避免的引入了后门。大多数后门设法躲过日志,大多数情况下即使入侵者正在使用系统也无法显示他已在线。后门的引入无疑会形成重大安全风险。知道后门的人,日后可以对系统进行隐蔽的访问和控制,而且后门也容易被入侵者当成漏洞进行攻击。

1. 基础静态分析

Basic analysis, just looking at the ‘properties’ of the malware.

分析目标文件的程序指令与结构来确定其功能是什么。

Static Analysis — Looking at the Malware ‘at Rest’
不会去运行恶意程序,而是把程序放到一个特定的分析软件中,展示可运行文件的不同部分。

基础静态分析会有报告生成,
给动态分析留下线索,
理清思路,留下逻辑框架。

通过基本静态分析可以简单快速地判断出某个文件是否是恶意的,但对待高端的恶意代码往往无效。

先分析一下正常软件,再分析一下恶意软件,
看看有什么显著的区别。

反病毒引擎扫描【工具】

VirusTotal,是一个提供免费的可疑文件分析服务的网站。

对一个文件进行多种反病毒引擎扫描是有必要的,因为大家用的特征库都不一样。

https://www.virustotal.com

恶意代码作者可以很轻易的修改自己的代码,
躲过杀毒软件的特征引擎扫描。

一些特定的恶意代码并不在杀毒软件的特征库中,没办法被察觉到。

一些新型恶意代码会绕过检验。

Imports
看引入了哪些函数哪些windows的API

可以看到文件的hash

https://www.virustotal.com/gui/file/cc695909a072cb8c1da4dbb69385737465f59c31c12c0253a97516d4cf34105c/details

https://www.virustotal.com/gui/file/be1a5327e00826b456c8e8188e5a45e343d2d730320cc46fdc96347e472e5d12/details

Name显示曾经使用过的名字,
恶意软件会经常改名字,
不要用文件名来判断,
用文件的哈希值来判断。

恶意代码的指纹

使用哈希来识别恶意代码,
文件哈希:对整个文件的内容运行一个算法,
并根据内容生成一个"唯一"的数字(哈希值),
用来唯一标识文件。

256位长,可能会发生哈希碰撞,
2个文件的哈希完全一致,比较少见。

可以用这个VirusTotal软件看哈希,
也可以用系统命令

shasum -a 256 /Users/yangminghan/Downloads/tools/Discord.dmg

MD5与SHA-1算法比较常见。

可以拿这个哈希值当标签,或与他人共享,帮助他们识别代码,或在线搜索,看这个恶意代码是否被破解。

查找字符串【工具】

从文件中的字符串列表,函数,
文件头信息中发掘有用信息。

定义在程序中的字符串可以发现这个软件主要是负责做什么的,与操作系统的哪部分进行通信,可以猜出这个软件要做什么,例如调用了Windows API的XXX钩子,有可能是用来记录日志的。

可以通过软件分析文件里的字符串,
通过字符串来判断出目标软件的目的。

Windows同时使用ASCII和Unicode字符,
因此需要寻找这两种类型的字符串。

可以用程序(名字叫strings)来找到这些字符串。

https://docs.microsoft.com/en-gb/sysinternals/downloads/strings

• Looking at strings can reveal various things about the program
• Filenames
• Registry Keys
• Network addresses
• Error messages (these can be very helpful)
• Names of functions called…

也可能查出一些没有意义的字符串,忽略就好,
如果一个字符串很短又不是一个单词的话,
可以忽略掉。

通过错误信息就能猜出大概要实现什么功能,
例如邮件错误,
就知道作者想发邮件并且是用windows自己的邮件服务。

在使用strings软件时,可以设置一些参数去指定一些功能让你更方便查找信息,可以把信息导出成文本文件。

strings -n 5 C:\Windows\System32\kbd101a.dll

加壳

恶意代码作者会经常使用加壳、加密、模糊化(可以用其他程序模拟解密过程,详细看视频)技术让他们的代码更难以检测或分析,就没有或很难找到字符串信息。

正常文件的字符串会很多,
加壳后的文件会被压缩,字符串会很少,
可以证明如果字符串很少的软件,大部分是恶意的。

加壳代码一般会包含LoadLibrary(),GetProcAddress()函数,
用来加载和使用其他函数功能。

作者拿到原始文件后进行压缩,
导致文件内的字符串等信息都不可见,
之后往文件开头加入一段机器码,
stub,文件仍然是可执行的。

运行程序时,会先运行一小段脱壳代码用来解压,
stub里的代码负责解压文件,
把文件恢复正常大小后再去运行。

黑客可以对EXE和DLL文件加壳。

PEiD【工具】

使用PEiD去是否文件被加壳,
以及检查加壳器的类型,编译器类型。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BfGuXidL-1630045248948)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p424)]
识别出加壳器,UPX加壳工具非常流行。

当文件被加壳后,你必须进行脱壳才能继续分析。
UPX的脱壳比较简单,下载upx.sourceforge.net,运行命令:upx -d xxx.exe

e.g. by using UPXPacker https://upx.github.io

注意,很多PEiD插件会在没有警告的情况下去运行恶意代码,因此一定要在虚拟机上进行,并且用最新版。

PEiD(PE Identifier)是一款著名的查壳工具,其功能强大,几乎可以侦测出所有的壳,其数量已超过470种PE文档的加壳类型和签名。

好像只能用于32位文件。

Can use the program PEiD to detect if a file has been packed or not.

You can use PEiD to detect the type of packer or compiler employed to build an application, which makes analyzing the packed file much easier.

Development and support for PEiD has been discontinued since April 2011, but it’s still the best tool available for packer and compiler detection.

In many cases, it will also identify which packer was used to pack the file.

PE文件格式

可移植的可执行文件,PE(Portable Executable)文件格式是Windows操作系统上运行的可执行文件的总称,包括可执行文件、对象代码、和DDL所使用的标准格式,
常见的有DLL,EXE,OCX,SYS(驱动程序),VXD,VDM等。

PE文件格式是一种数据结构,包含为Windows操作系统加载器管理可执行代码所必要的信息。

文件格式可以揭示出很多关于程序功能的信息。

PE文件以文件头开始,其中包括代码信息,应用程序类型,所需的代码库与空间要求,这些信息非常有价值。

可移植性(Portable)是指在任何机器(Intel 386 、MIPS 、Alpha 、Power PC 等)上的Microsoft Windows操作系统都可以使用相同的可执行文件格式,指该文件格式的通用性,使得程序加载器以及程序开发工具不需要针对每一个新的操作系统重写。

Portable是指对于不同的Windows版本和不同的CPU类型上PE文件的格式是一样的,当然CPU不一样了,CPU指令的二进制编码是不一样的。
只是文件中各种东西的布局是一样的。

PE文件使用的是一个平面地址空间,所有代码和数据都合并在一起,组成一个很大的结构。

PE是一种用于可执行文件、目标文件和动态链接库的文件格式,主要使用在32位和64位的Windows操作系统上。

PE文件格式封装了Windows操作系统加载可执行程序代码时所必需的一些信息。这些信息包括动态链接库、API导入和导出表、资源管理数据和线程局部存储数据。

PE(“portable executable”,可移植的可执行文件)文件格式,是微软WindwosNT,Windows95和Win32子集中的可执行的二进制文件的格式;在WindowsNT中,驱动程序也是这种格式。它还能被应用于各种目标文件和库文件中。

PE文件格式结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EN9xQAhG-1630045248951)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p422)]

简化结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FVpYfTn0-1630045248953)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p423)]

https://baike.baidu.com/item/PE%E6%A0%BC%E5%BC%8F/9812617?fr=aladdin

https://blog.csdn.net/shitdbg/article/details/49734495

https://blog.csdn.net/qq_30145355/article/details/78859214

https://blog.csdn.net/evileagle/article/details/11693499

https://blog.csdn.net/weixin_34375054/article/details/85566610?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control

https://blog.csdn.net/rivershan/article/details/15783?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control

https://blog.csdn.net/rivershan/article/details/15783?utm_medium=distribute.pc_relevant.none-task-blog-searchFromBaidu-6.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-searchFromBaidu-6.control

https://blog.csdn.net/HackerJLY/article/details/3257207?utm_medium=distribute.pc_relevant.none-task-blog-searchFromBaidu-12.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-searchFromBaidu-12.control

https://wiki.osdev.org/PE

https://blog.csdn.net/lvzhuyiyi4/article/details/8059072?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-2&spm=1001.2101.3001.4242

文件头 PE header

PE files begin with a header that includes information about the code, the type of application, required library functions, and space requirements. The information in the PE header is of great value to the malware analyst.

https://blog.csdn.net/StriveScript/article/details/6279488

https://www.77169.net/html/271468.html

https://www.sohu.com/a/278839463_653604

https://www.y4f.net/71203.html

https://bbs.pediy.com/thread-21932.htm

https://zhuanlan.zhihu.com/p/31967907

https://www.cnblogs.com/mfm11111/archive/2009/04/18/1438474.html

https://www.cnblogs.com/mfm11111/archive/2009/04/18/1438848.html

https://www.4hou.com/posts/5QnB

https://www.cnblogs.com/qintangtao/archive/2013/01/11/2857179.html

https://my.oschina.net/u/4293620/blog/3809007

https://www.hetianlab.com/expc.do?ec=ECID172.19.104.182015051313294800001

PE文件头比只查看导入函数提供更多的有价值的信息,
PE文件格式包含一个PE文件头,
后面跟着一系列的分节,
文件头中包含了有关文件本身的元数据,
之后每个分节都包含着有用信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5SNmBTL0-1630045248954)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p433)]

Dos MZ Head与Dos stub和称Dos文件头,
PE文件的第一个字节起始于MS-Dos头部,
被称作IMAGE_DOS_HEADER,
紧随Dos stub的是PE文件头(PE header),
PE Header是PE相关结构NT映像头(IMAGE_NT_HEADERS)的简称,
其中包含了许多PE装载器用到的重要字段。

PE头表示为结构体IMAGE_NT_HEADERS,
其中IMAGE_NT_HEADERS中包含着另外两个结构体:
1.IMAGE_FILE_HEADER,包含一些底层的硬件物理信息,不是特别常用。
2.IMAGE_OPTIONAL_HEADER32,包含了关于PE文件逻辑分布的信息,这个结构体是PE中最大的结构体,其中比较重要的几项:

  1. 入口点,Entry Point;
  2. 文件偏移地址,File Offset;
  3. 虚拟地址,Virtual Address,简称:VA,文件被载入虚拟空间后的地址;
  4. 基地址,ImageBase;
  5. 相对虚拟地址,Relative Virual Address,简称:RVA,代码在内存中相对于基地址的偏移,RVA = VA - ImageBase;
  6. AddressOfEntryPoint(RVA):这是PE文件开始执行的位置,通常会落在 .text section.此域适用于exe或dll。A pointer to the entry point function, relative to the image base address. For executable files, this is the starting address. For device drivers, this is the address of the initialization function. The entry point function is optional for DLLs. When no entry point is present, this member is zero.

PE装载器准备运行的PE文件的第一个指令的RVA。
若您要改变整个执行的流程,
可以将该值指定到新的RVA,
这样新RVA处的指令首先被执行。

  1. BaseOfCode(RVA):where does Windows start loading the program into memory. base代表开头,后面跟着其他的东西。
    代码段的开始地址,表示程序中的Code Section从何开始。Code Section通常在Data Section之前,在PE表头之后。微软链接器所产生的exes中,此值通常为0x1000。Borland 的TLINK32则通常指定此值为0x10000。因为预设情况下TLINK时以64k为对齐粒度的,而MS用的是4k。A pointer to the beginning of the code section, relative to the image base.

在X86系统中,
每个内存页的大小是4KB,即0X1000个字节。

一些基础:

内存中使用VA(Virtual Address,虚拟地址)来表示位置。文件加载到内存时,情况就会发生变化(节区大小、位置等)。

在运行一个可执行文件时,将它装载入内存中,主要就是将一个PE文件的某一部分映射到地址空间中。这样,PE文件的数据结构在磁盘和内存中就是一样的了(windows加载器遍历PE文件并决定文件的哪一部分被映射)。

文件偏移地址(或物理地址):当PE文件存储在磁盘上时,各个数据的地址。一般我们用16进制编辑工具打开后显示的就是。

虚拟地址:由于Windows运行在保护模式下,所以程序访问存储器所使用的逻辑地址就是虚拟地址,简称VA,又称为内存偏移地址。

虚拟地址为什么一定要转化为物理地址的原因:
计算机中的物理内存是字节的线性数组,每字节具有一个唯一的物理地址;程序中的地址是由两部分构成的逻辑地址。这种逻辑地址并不能直接用于访问物理内存,而需要使用地址变换机制将它变换或映射到物理内存地址上。内存管理机制即用于将这种逻辑地址转换成物理内存地址。那么我们要修改时,就需要将物理地址映射到虚拟地址了。

基地址,程序运行时,被映射到程序指定内存处。内存处的起始地址就是基地址。

相对虚拟地址(RVA):是指相对于基地址的偏移量。RVA 代表相对虚拟地址。简言之,RVA是虚拟空间中到参考点的一段距离。我打赌您肯定熟悉文件偏移量: RVA就是类似文件偏移量的东西。当然它是相对虚拟空间里的一个地址,而不是文件头部。

RELATIVE VIRTUAL ADDRESS
• This works, but slightly complicated by the fact that the addresses are all
stored in memory as Relative Virtual Addresses

• Need to add the address of the base of the DLL onto them before using
them

• To both the name pointers and the address of the function

• If disassembling shell code, keep an eye out for techniques like this…

为什么PE文件格式要用到RVA呢? 这是为了减少PE装载器的负担。因为每个模块多有可能被重载到任何虚拟地址空间,如果让PE装载器修正每个重定位项,这肯定是个梦魇。相反,如果所有重定位项都使用RVA,那么PE装载器就不必操心那些东西了: 它只要将整个模块重定位到新的起始VA。这就象相对路径和绝对路径的概念: RVA类似相对路径,VA就象绝对路径。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AIrGUFsW-1630045248955)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p484)]

ImageBase:
是程序被载入到内存的地址

The preferred address of the first byte of the image when it is loaded in memory. This value is a multiple of 64K bytes. The default value for DLLs is 0x10000000. The default value for applications is 0x00400000, except on Windows CE where it is 0x00010000.

ImageBase包含了什么?
Where the program has been compiled to be loaded to. Contains the address to load the program.

什么是Image?
映像,加载到内存中的PE文件。

ImageBase是映像的基地址,这个基地址是建议,对于DLL来说,如果无法加载到这个地址,系统会自动为其选择地址。

Assuming the program is not relocated when loaded, where will the program start executing code?

The memory location where the first instruction will be placed can be found using the following formula: EP (Memory) = AddressOfEntryPoint + ImageBase

A说法
基地址,PE文件的优先装载地址。比如,如果该值是400000h,PE装载器将尝试把文件装到虚拟地址空间的400000h处。"优先"表示若该地址区域已被其他模块占用,那PE装载器会选用其他空闲地址。

B说法
ImageBase是程序在虚拟空间中被装载的位置,exe加载到内存的时候,所在的地址???

C说法
ImageBase是程序载入内存的初始地址,也就就整个PE文件的最前面入口地址,通过这个地址可以定位到PE的任何结构数据???

D说法
指出文件的优先装入地址。也就是说当文件被执行时,如果可能的话,Windows优先将文件装入到由ImageBase字段指定的地址中,只有指定的地址已 经被模块使用时,文件才被装入到地址中。链接器产生可执行文件的时候对应这个地址来生成机器码,所以当文件被装入这个地址时不需要进行重定位操 作,装入的速度最快,如果文件被装载到**地址的话,将不得不进行重定位操作,这样就要慢一点。

对于EXE文件来说,由于每个文件总是使用独立的 虚拟地址空间,优先装入地址不可能被模块占据,所以EXE总是能够按照这个地址装入,这也意味着EXE文件不再需要重定位信息。对于DLL文件来说, 由于多个DLL文件全部使用宿主EXE文件的地址空间,不能保证优先装入地址没有被的DLL使用,所以DLL文件中必须包含重定位信息以防万一。因 此,在前面介绍的 IMAGE_FILE_HEADER 结构的 Characteristics 字段中,DLL 文件对应的 IMAGE_FILE_RELOCS_STRIPPED 位总是为0,而EXE文件的这个标志位总是为1。

在链接的时候,可以通过对link.exe指定/base:address选项来自定义优先装入地址,如果不指定这个选项的话,一般EXE文件的默认优先装入地址被定为00400000h,而DLL文件的默认优先装入地址被定为10000000h。

E说法
提供整个二进制文件包括所有头的优先(线性)载入地址(‘ImageBase’,“映象文件基址”)。这是一个文件已被链接器重定位后的地址(总是64KB的倍数)。如果二进制文件事实上能被载入这个地址,那么加载器就不用再重定位文件了,也就节省了一些载入时间。
优先载入地址在另一个映象文件已被先载入那个地址(“地址冲突”,在当你载入好几个全部按照链接器的缺省值重定位的DLL文件时经常发生)时,或者该内存已被用于其它目的(堆栈、malloc()、未初始化数据、或不管是什么)时,就不能用了。在这些情况下,映象文件必须被载人其它的地址,并且需要重定位(参见下面的“重定位目录”)。如果是一个DLL文件,这么做还会产生其它问题,因为此时的“绑定输入”已不再有效,所以使用DLL的二进制文件必须被修正----参见下面的“输入目录”一节。

F说法
当PE文件被装载到内存空间中去时,ImageBase指出文件的优先装入地址。执行PE文件时,PE装载器先创建进程,再将文件载入内存,然后把EIP寄存器的值设置为ImageBase + AddressOfEntryPoint。

AddressOfEntryPoint(RVA)
程序入口,程序最先被执行的代码起始地址,文件被执行时的入口地址,如果在一个可执行文件上附加了一段代码并想让这段代码首先被执行,那么只需要将这个入口地址指向附加的代码就可以。

对于exe这个地址可以理解为WinMain,对于dll个地址可以理解为DllMain,如果是驱动程序,可以理解为DriverEntry。当然,实际上入口点并非是WinMain,DllMain和DriverEntry,在这些函数之前还有一系列初始化要完成。

程序在内存中展开的真正入口:
标准PE头后0x10 AddressOfEntryPoint + 标准PE头后0x1C ImageBase

DLL文件结构

• Once we’ve found the address where the DLL has been loaded

• Can then parse the PE file format (in memory) to find the address of
any functions of interest

• PE has several tables we need to consult

• Main table of interest is the Export Address Table
• Contains the address of each function

• But it is indexed by ordinals — need to find the ordinal for the function of interest

Ordinal is just a number
Export table might not necessarily start at ordinal 1 — need to consult the base ordinal details

https://docs.microsoft.com/en-us/windows/win32/debug/pe-format

DLL表

• Another table is the Export Name Pointer Table — list of the names of functions

• Can search this to find the function name (manually!)

• But the index into this table is not the ordinal

• Fortunately, there is another table we can use — Export Ordinal Table

• Can use the index of the name in the Export Name Pointer Table

• To find the ordinal in the Export Ordinal Table

• Then use that ordinal in the Export Address Table to find the address

Remember you don’t know where strcmp is so you’ll need to provide your own…

Can be done quickly by reading longwords and comparing with constants in m/code
e.g. the constant 0x50746547 would match the first four bytes of GetProcAddress

This section records the exports of the image (yes, EXEs can export things). This takes the form of:

The export address table: an array of length N holding the addresses of the exported functions/data (the addresses are stored relative to the image base). Indexes into this table are called ordinals.

The export name pointer table: an array of length M holding pointers to strings that represent the name of an export. This array is lexically ordered by name, to allow binary searches for a given export.

The export ordinal table: a parallel array of length M holding the ordinal of the corresponding name in the export name pointer table.

http://blog.omega-prime.co.uk/2011/07/04/everything-you-never-wanted-to-know-about-dlls/

A piece of code is being delivered by an exploit (such as a buffer overflow) to a remote machine, explain how the exploit might make use of the Portable Exe- cutable header structure of DLLs to call Windows API functions.

Code will need to find the address of Windows API manually by walking the PE file format
• Can find the start of a DLL, by using the PEB to find the DLLs.
• Once the correct DLL has been found, we can use the PE file format to find
• Export Name Pointer Table to find the name of function
• Map offset of the function in name in the Export name table to ordinal in Export ordinal Table
• Then use the ordinal to find address of function in the Export Address Table
• Call the address to execute function

访问DLL有2种形式:
in the standard fashion (using LoadLibrary)
manually via the Process Environment Block

分节(Section)

PE文件格式把可执行文件分成若干个数据节(section ),不同的资源被存放在不同的节中。
一个典型的PE文件中包含的节如下。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5b3wemqf-1630045248956)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p428)]

.text(代码段)

一般来说,这是唯一可以让CPU执行指令的section,
也是唯一包含代码的section

由编译器产生,存放着二进制的机器代码,
也是我们反汇编和调试的对象。

默认的代码区块,它的内容全是指令代码,
链接器把所有目标文件的text块连接成一个大的.text块,
使用Borland C++,
编译器产生的代码存放在CODE的区域里。

可读、可执行

.rdata(数据段)

通常包含导入导出函数信息,
与Dependency Walker和PEview所获得的信息是相同的,
还可以存储程序所使用的其他只读数据。

资源数据段,程序用到什么资源数据都在这里(包括自己打包的,还有开发工具打包的)

默认只读数据区块,但程序中很少用到该块中的数据,一般两种情况用到,一是MS 的链接器产生EXE文件中用于存放调试目录,二是用于存放说明字符串,如果程序的DEF文件中指定了DESCRIPTION,字符串就会出现在rdata中

.data(数据段)

包含了程序的全局数据,本地数据并不存储在这里。
存放初始化的数据块,
如宏定义、全局变量、全局常量、静态变量等。

默认的读/写数据块

有些文件中还会包含.idata和.edata节,
来存储导入导出信息。

.idata(数据段)

.idata包含可执行文件所使用的外来的DLL函数、文件、数据等信息,即输入表。

导入函数的代码段,存放外部函数地址。(当然还有 edata,导出函数代码段,但不常用)

将.idata区块合并成另一个区块已成为一种惯例,
典型的是.rdata区块,默认的,
链接器只在创建一个Release模式的可执行文件时才能将idata合并到另外一个区块中。

.edata(数据段)

输出表,当创建一个输出API或数据的可执行文件时,
连接器会创建一个.EXP文件,这个.EXP文件包含一个.edata区块,其会被加载到可执行文件中,
经常被合并到.text或.rdata区块中

.rsrc

存放可执行文件所使用的的资源,这些内容并不是可执行的,比如图标、图片、菜单项、字符串等。

字符串可以存储在.rsrc,或中程序中。
在.rsrc中经常存储的字符串是为了提供多语言支持的。

包括模块的全部资源,这个区块是只读的,
无论如何不应该把它命名为.rsrc以外的名字,
也不能合并到其他的区块里。

.reloc

可执行文件的基址重定位,基址重定位一般仅Dll需要的

Contains information for relocation of library files

未整理

.bss
未初始化的数据,很少在用,取而代之的是执行文件的.data区块的的VirtualSize被扩展大的空间里用来装未初始化的数据.
.crt
用于C++ 运行时(CRT)所添加的数据
.tls
TLS的意思是线程局部存储器,用于支持通过_declspec(thread)声明的线程局部存储变量的数据,这包括数据的初始化值,也包括运行时所需要的额外变量

.sdata
相对于全局指针的可被定位的 短的读写数据
.pdata
异常表,包含CPU特定的IAMGE_RUNTIME_FUNTION_ENTRY结构数组,DataDirectory中的IMAGE_DIRECTORY_ENTRY_EXCEPTION指向它.
.didat
延迟装入输入数据,在非Release模式下可以找到

PE View【工具】

使用PE View可以查看PE文件格式中的PE头和section信息。

Windows使用PE格式来存储文件和程序,
通过PE View,可以看到程序的文件结构,
都是人类能看得懂的东西,而不是一堆16进制数据。

里面的信息是可以被篡改的,不一定100%正确。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ooXrFCfL-1630045248958)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p429)]

IMAGE_NT_HEADERS(可以看Section数量,后面可以看每个section的详细内容,时间,64还是32位文件等)

1显示PE文件头信息,
前面的IMAGE_DOS_HEADER与MS-DOS-Stub Program没有价值,
不用看。Signature不用看。

2显示关于文件的基本信息。
3显示编译时间,这里可以作假,很老的编译时间意味着古老的攻击,也许杀毒软件可以cover的住。但Delphi程序的编译时间统一为1992-6-19。

IMAGE_OPTIONAL_HEADER(可选映像头)包含:

程序执行入口,AddressOfEntryPoint。
指出文件被执行时的16进制的入口地址,
这是一个RVA地址,
如果在一个可执行文件上附加了一段代码并想让这段代码首先被执行,
那么只需要将这个入口地址指向附加的代码就可以了。

Subsystem,子系统,指出是控制台程序是IMAGE_SUBSYSTEM_WINDOWS_CUI还是图形界面程序IMAGE_SUBSYSTEM_WINDOWS_GUI。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ac6t8Xid-1630045248961)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p430)]
IMAGE_SECTION_HEADER,
节名称发生变化是可以的,理论上都是一致的。
1的虚拟大小表示在加载过程中需要分配多少空间给1个section。
2的原始数据大小表示在磁盘上这个section的大小规模,
这2个值应该是相等,表示硬盘与内存相同,
有小差别是正常。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O0NzLUEs-1630045248963)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p431)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uo39UpZu-1630045248964)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p432)]

查看SECTION .rdata,[IMPORT/EXPORT]Address Table表示导入导出函数列表

PE Studio【工具】

非教材

PeStudio是一款验证应用程序的免费工具,
适用于开发者、测试员和维护、分析人员。

列出某一个应用程序使用的所有DLL库,字符串等信息。
验证应用程序是否过时,并存在潜在安全风险。

可以直观显示被标记为黑名单的导入导出函数。

PE Viewer【工具】

非教材

Resource Hacker【工具】

老师没提过,如果有用到需要再看那本书,在1.8.2章节

用于分析.rsrc节,资源相关。

链接库与函数

关于可执行文件,
我们能收集到的最有用的信息之一是它所导入的函数列表。

在PE文件头中找到的信息可以看到链接了哪些库。

DLL文件

一般来说,DLL文件没法自已独立运行,
需要被EXE程序调用。

DLL(Dynamic Link Library)文件,又叫动态链接库文件。

静态库和动态库的区别是:
静态库在程序的链接阶段被复制到了程序中;

动态库在链接阶段没有被复制到程序中,
而是程序在运行时由系统动态加载到内存中供程序调用。

使用动态库的优点是系统只需载入一次动态库,
不同的程序可以得到内存中相同的动态库的副本,
因此节省了很多内存,
而且使用动态库也便于模块化更新程序。

DLL和EXE文件一样,
其中包含的也是程序的二进制执行代码和程序所需的资源(比如图标、对话框、字符串等),可是为什么要把代码放在DLL里面,而不是做成EXE呢?

其实DLL中的代码是以API函数形式出现的,通俗地说,DLL中包含的程序代码都被做成了一个个小模块,
应用程序通过按下所需DLL中特定的按钮,
来调用DLL中这个按钮所代表的功能。

在使用“记事本”等程序时,如果要保存文件或打开文件,就会弹出通用文件对话框,让我们选择文件位置。
这就是调用了系统底层DLL中的通用对话框界面。

Windows系统使用DLL文件来实现操作系统的[方法/函数/功能],在DLL文件中可以调用Windows的API供我们编程使用,Win32 API,64等。

当程序加载时,你的pre-code连接程序与功能,
通过PE文件,我们可以看到哪些函数被引用,

库文件一般指计算机上的一类文件,分两种,
一种是静态库,另一种是动态库即

在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为共享DLL文件。

可以简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数或类。在库文件的发展史上经历了“无库-静态链接库-动态链接库”的时代。静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,库中的指令都被直接包含在最终生成的可执行文件中了。但是若使用动态链接库,该库文件则不必被包含在最终可执行文件中,可执行文件执行时可以“动态”地引用和卸载这个与可执行文件独立的库文件。

①扩展应用程序

由于DLL能被应用程序动态载入内存。所以,应用程序可以在需要时才将DLL载入到内存中,这让程序的可维护性变得很高。比如QQ的视频功能需要升级,那么负责编写QQ的程序员不必将QQ所有代码都重写,只需将视频功能相关的DLL文件重写即可。

②便于程序员合作

这个和我们最终用户关系不大,仅供了解。我们都知道编程工具有很多,比如VB、VC、Delphi等,如果好几个人合作来编写一个大的程序,那么可能有的人用VB,有的人用VC,每人负责的部分所使用的编程语言都不同,究竟放在哪个编译器中进行编译呢?这就好比一群来自各个国家的人在共同编写一篇文章,如果他们所使用的语言都不同,写出来的文章怎么可能凑到一起呢?而有了DLL后,可以让VC程序员写一个DLL,然后VB程序员在程序中调用,无需为怎么将它们都编译为一个单独的EXE而发愁了。

③节省内存

如果多个应用程序调用的是同一个动态链接库,那么这个DLL文件不会被重复多次装入内存中,而是由这些应用程序共享同一个已载入内存的DLL。就好比一个办公室中,很少会为每一个员工配置一台饮水机的,而是在一个公共位置放上一个饮水机,所有需要喝水的职员都可以共用这台饮水机,降低了成本又节约了空间。

④共享程序资源

包括刚才提到过的通用文件对话框在内,DLL文件提供了应用程序间共享资源的可能。资源可以是程序对话框、字符串、图标,或者声音文件等。

⑤解决应用程序本地化问题

在下载了某个程序的汉化包后,打开汉化说明,经常可以看到用下载包中的DLL文件覆盖掉程序原来的DLL,汉化就完成了。这些程序都是将执行代码和应用程序界面分开编写了,所以汉化者只需简单地将其中和程序界面相关的DLL汉化并发布即可。

静态、运行时、动态

代码库可以被静态,运行时,动态链接。

静态链接:所有当前代码库中的代码都会被复制到可执行程序中,这会增大可执行程序的体积。难以区分是否被静态链接过,因为PE文件头没有显示相关信息。

运行时链接:在恶意代码中很常用,只有在需要使用函数时,才链接到库。

动态链接:程序启动时链接。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rJVzoaJw-1630045248970)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p425)]

Dependency Walker【工具】

使用Dependency Walker查看可执行文件的动态链接函数。

可以查看exe程序使用的DLL及函数,
DLL文件里有多少个函数,
以及EXE调用了哪个DLL的哪些函数?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xlie3JL9-1630045248971)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p426)]

2显示了程序导入的DLL列表,点击2后,
在3处显示导入的函数列表。

4显示这个DLL中所有可被导入的函数,对我们不是特别有用,3,4的列中有序号,可执行文件可以根据序号,而不是根据名字来导入函数。

当根据序号来导入函数时,
函数名字不会在可执行文件中显示,
对于我们分析来说会变难。

可以在4中通过查找序号,
来找出到底导入的是哪个函数。

5、6显示运行程序时装载的DLL版本额外信息和报告的错误。

会展示给我们程序用到所有的函数,
以及这些函数在哪里被引用。

有一些函数是直接调用,有一些函数是间接调用。

Dependency Walker是Microsoft Visual C++ 中提供的非常有用的PE模块依赖性分析工具。

主要功能如下:
查看 PE 模块的导入和导出函数。
动态剖析 PE 模块的模块依赖性。
解析 C++ 函数名称。

官方下载:http://www.dependencywalker.com/

在程序左侧的树状栏中就列出了这个DLL使用了哪些其他DLL的功能函数(原来DLL中还可以调用其他DLLO),
而右侧的两个分栏列表分别显示了函数输入及输出表,
函数输出表即为该DLL提供给其他EXE或者DLL调用的函数的总列表。

函数输出表的Function栏中即为输出函数的名称(见图1),在QQZip.dll中共发现了2个函数:Unzip、Zip。因此可以判断该DLL在QQ程序中负责压缩和解压缩的任务。

https://www.pianshen.com/article/2385335/

导入函数

导入函数如果比较多的话,代表没有被加壳,
但只有少数的导入函数对我们来说是有意义的。

WINDOWS IMPORTS
• The imported functions from the Win32 API can tell us a lot about what the program potentially does
• Can use several tools to list the imports in a PE file
• At the very least, they should pose some questions to direct further analysis
• As you become more proficient, you will start to recognise various imports and the potential behaviour they indicate
• But at the start you’ll end up having to look up the functions in the documentation (see MSDN)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lXk5lHPL-1630045248974)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p421)]

Example taken from Practical Malware Analysis, p19
Explain the W/A suffix… whether the function takes ASCII or Unicode chars
Demo where to find documentation

https://docs.microsoft.com/en-us/windows/win32/api/

看完了imports里的东西,要问自己一些问题:

QUESTIONS ARISING
• It’s searching for files — which files and why?
• It’s creating/manipulating files — which files and why?
• It’s hooking into Windows — what for?
• It has a GUI — how do we activate it, what options does it give?
• Potentially via a hot key (see RegisterHotKey()) — which key combo?
• Does the .rsrc section contain something interesting?

导出函数

与导入函数类似,DLL与EXE的导出函数,是用来与其他程序或代码进行交互时所使用的。通常,1个DLL会实现若干个函数,然后将他们导出,使得别的程序可以导入并使用这些函数。

PE文件中包含一个文件中导出了哪些函数的信息。因为DLL文件本身就是实现一些导出函数然后被exe可执行文件使用的,因此导出函数在DLL文件中是最常见的,而在exe文件中却很少见。

将一些函数导出来让其他人用,在PE文件中可以看到这些信息,详略。

2. 基础动态分析

Dynamic Analysis — Looking at the malware ‘as it runs’

在文件运行时去用工具分析,
观察与监控系统中的行为,
它都干了什么,通过工具看到去对比静态时的字符串,有很大的差异。

恶意软件作者发现有其他特殊的软件在运行,
则就什么都不做,因此我们需要使用crabber?

但对待高端的恶意代码往往无效。

先静态,后动态,在静态走到不能走之后再做动态分析。

沙盒

简单但粗糙

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wAduBV2p-1630045248977)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p445)]
模拟一个虚拟的环境,沙盒可以自动做上面的事情,
还可以生成报告,

Cuckoo Sandbox

Hybrid analysis,帮你运行恶意文件,并生成报告。
https://www.hybrid-analysis.com/

Including doing some static analysis

沙盒有一些缺点,详略

运行恶意代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SLe2R3lU-1630045248978)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p438)]
cl arguments should be visible as strings in the static analysis

通常可以通过命令行输入命令或双击EXE文件去运行文件,
DLL有点特殊,可以用rundll32.exe进行运行。

C:>rundll32.exe DLLname, Export arguments

Export arguments必须是DLL导出函数列表中的函数名或序号(例如#1,#5)。

Process Monitor【工具】

进程监视器,监控所有运行的进程、线程、注册表、文件系统、网络、系统调用等等。

展示一个被监视的事件列表,
告诉你相关的程序在系统中做了什么,
调用哪个windows的API。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0omycD5a-1630045248979)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p453)]

点capture,取消或开启监控,一般几分钟就可以。
所有的系统调用都会被捕获,
时间长了会导致内存不足,虚拟机崩溃。

在进行监控分析之前,
先暂停捕获,File->Capture Events
先clear一下屏幕,Edit->Clear Display

可以使用filter来进行过滤,不然内容太多了,
并不能阻止消耗内存。

可以换背景图来尝试变化。

需要有耐心,可能会有很多事件。
不应该被记录网络行为,因为微软的兼容性原因。

Process Explorer【工具】

微软的免费产品,有点像高级的windows任务管理器,
监视系统上所有活跃的进程、被进程载入的DLL、
各种进程属性和整体系统信息。

进程之间是有层级树状结构的,进程,子进程。

视图每秒更新一次,默认情况下,服务是粉色,
进程是蓝色,新进程是绿色,被终止进程是红色。
绿色与红色是临时的,

双击xxx.exe,可以看其他详细信息。

可以在Strings模块上比较字符串,
可以选择Image在硬盘,Memory在内存,
如果有很大不同,代表发生了进程替换。

点击verify按钮,检查是否有被修改过,
是否具有微软的签名认证,
恶意代码经常替换windows认证文件并试图隐藏,
这个功能可能会失效,详略。

恶意软件可能会在运行时进行伪装,
先打开一个无害的应用例如Chrome,
之后在内存中替换成恶意代码,
外表上看依然是在运行Chrome,
这样查看内存的字符串就变得很有意义,
可以进行对比。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Sj1ov28-1630045248980)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p454)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1o889G45-1630045248982)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p455)]

Regshot

对注册表进行快照比较,对比2个快照,
看看差距在哪里。

先1st shot,再运行恶意代码,
之后再2nd shot,再看差别,需要有耐心。

可以用更换背景图片来测试。

模拟网络

详略

网络监听

详略

tcpdump or WireShark

不想让病毒通过网络传播感染其他机器,
需要使用隔离的网络环境:

FakeNet-NG
https://www.fireeye.com/services/freeware/fakenet-ng.html

The approach below runs completely outside the VM, and as such requires multiple VMs to be setup. It is likely that you may need to use both approaches.

But it is also relatively straight-forward to build an isolated LAN environment for testing, this page contains details of how to implement an isolated LAN environment.

Golden Rule: Check you are isolated before you run anything! traceroute/ping are your friends here.

Isolated Network Environments

Lots of malware makes network connections to local and remote machines. Can be instructive to watch this traffic to see what is happening.
e.g. by using tools such as tcpdump or WireShark

However, we do not want the malware to infect other computers or phone home, so we need to be able to run it within an isolated network environment.

Relatively straight-forward to build an isolated LAN.

Virtual Machine Hypervisors allow us to create virtual network switches, and to connect VMs to these switches. It is optional whether these switches are then connectd to the host computer, or the wider network environment (Internet). If we only connect the VMs to the virtual network switch, we create a contained network environment that allows the VMs to talk to each other, but nothing else.

But we want to be able to see traffic going to remote machines on the Internet…

Need to build an isolated ‘Internet’…

Not as hard as it sounds!

We only have to ensure that the VM can send/receive packets to the addresses it tries to, we don’t have to emulate the whole Internet!

The routes packets take across the Internet can change, so even if the malware author were to know the IP address of the instituion it is unlikely they’d be able to detect that something had changed.

Can always introduce network latency to the connection to simulate travel over the open Internet.

The following assumes that you are building this using virtual machines, but the same principles apply if you want to build it using real hardware (e.g. to watch malware on a phone handset via an isolated wireless network).

There are also some tools, such as FakeNet-NG, that can be used to simulate the network from within the test VM. The approach below runs completely outside the VM, and as such requires multiple VMs to be setup. It is likely that you may need to use both approaches.

This page details how to setup the environment for malware analysis, there are many tutorials available online that detail how to configure Linux/OpenBSD/etc. as routers, DHCP servers or DNS servers and so that information is not duplicated here. The links above are purely given as examples and were the first hits I came across on google… Other documentation is available — google it 😃

Golden Rule: Check you are isolated before you run anything! traceroute/ping are your friends here

Isolated Internet Topology

Aiming for a topology similar to the one shown in the following diagram:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OXEHnmmd-1630045248983)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p915)]
Technically, only the VMs in the dashed box need to be completely isolated, but I’d advise caution and connect the other bits to the real Internet only when needed.

Three main components of the network.

Isolated Network

(represented by the dashed box)

This is where we run our isolated VMs, important that this network does not connect to the host machine in anyway.

Notice, I’ve assigned this an IP range in an RFC1918 space but this is entirely optional — remember this network is not on the Internet so we can use any IP addresses we like 😃

Need to create this as a separate isolated network in the hypervisor. Using VMWare as an example, this is a two step process, which mimics the physical process of setting up a network:

  1. Create a new network (under Preferences)
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-89CwKIXa-1630045248985)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p916)]

Ensure that all the options are turned off, we do not want the host computer to be able to access this and we’ll provide DHCP/DNS via our router.

  1. Attach the isolated VMs’ NICs to this network alone:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9hCTLri5-1630045248986)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p917)]

Make sure this is the only NIC in these VMs otherwise they’ll be able to talk to the real internet.

Other Hypervisor environments (VirtualBox, Hyper-V, etc.) offer similar facilities.

Router VM

Routes packets from the isolated network to elsewhere.

Standard VM, could run Windows, Linux, (Free|Open|Net|Dragonfly)BSD etc. — any OS that can route packets.

You may need to enable packet fowarding with sysctl.

My preference here is to use OpenBSD.

Designed to be secure by default!

Also has some nice networking features (such as allowing multiple virtual routing tables) that can be useful as setups get more advanced…

Also pf, OpenBSD’s firewall, is much simpler to configure than iptables IMO!

Will have multiple (virtual) NICs.

One in the isolated network.

One to connect to the network containing any services being provided to the isolated network.

Note down the MAC addresses of these NICs when creating them — very useful to help find which NIC is which in the router OS.

Provides DNS/DHCP services to our isolated network
Need to be able to provide both a recursive DNS server for isolated VMs to use
li>

DNS server logs will tell us what domains our machines are looking at.

Can be clever and return a honeypot address for all domains queried.

But watch out for malware that checks for this!

Do you want this to fetch real addresses from the Internet? Interesting question, DNS can be used as a back channel for communication.

And also, an authorative DNS server so we can add/override our own entries.

Lots of software options here, but I’d probably start with djbdns for DNS…

Install WireShark, tcpdump etc.

Can be used to sniff traffic leaving the isolated network. Depending on the implementation of the hypervisor, you might be able to sniff all network traffic on the isolated network.

Note that it is possible to use tcpdump from the command line in the router VM to capture network packets to a file which can then be opened on another machine in WireShark for later perusal.

Even if hypervisor doesn’t let you sniff all traffic on the isolated network, it is possible to architect your network around this (create an individual isolated network for each VM and bridge together in the router…)

VMs to provide copies of Internet Serviecs

These are optional, you don’t necessarily need them.

Again exist on a separate isolated network in your hypervisor. Create this in the same manner as before.

Again, the diagram shows I’ve used RFC1918 IP addresses here. Note though that I chose a vastly different set of IPs to make it clear which network is which!

Probably makes sense to use static IP allocation here, so you know which VM is providing which service.

Can use whatever OS you like.

Setup services as normal, e.g. use Apache WWW server to create a ‘Fake Google’…

Remember: we don’t need to duplicate all the functionality of the service, only the parts the malware acccesses.

Again we would probably develop this iteratively. Run the malware, see what it accesses, set up a duplicate server, then rerun the malware.

Configure DNS server on router to provide the server’s IP for any domain (e.g. www.google.com should return 192.168.42.23 for our ‘Fake Google’ example in the diagram above).

Some machines will attempt to connect directly to a known IP, e.g. to 172.217.23.14 (instead of www.google.com)

This is relatively straight-forward to cope with.

Set up the desired IP as an alias on the loopback interface of the machine providing the service with a netmask of 255.255.255.255 (/32), so for the example in the diagram, we’d create the alias using:

Linux: ip -4 addr add 172.217.23.14/32 dev lo.
OpenBSD: ifconfig lo0 inet alias 172.217.23.14 netmask 255.255.255.255.

Tell the router to route packets to that IP, to the IP address of the VM providing the service.

OpenBSD: route add 172.217.23.14/32 192.168.42.23.

Route will now send any packets for 172.217.23.14 to the correct VM.

Turn on packet forwarding on the VM providing the service, via sysctl, otherwise the VM won’t answer the packets.

Same approach will work for SSL/TLS encryped connections, but you’ll need to add your signing certificate to the infected VMs.

Will probably end up adding more services as you see what the malware tries to access.

Run them on separate VMs and build up a library of common services to reuse (via VM snapshots/clones).

Could also allow some packets to access the real Internet, but be careful! (Add another virtual NIC to the router VM that is connected to the Internet).

未整理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2fmZpsap-1630045248986)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p434)]
Instructions encode the algorithms
Manipulate data, change values in memory, update the values in registers

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3KwG4Bwt-1630045248987)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p435)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tCSxjIrR-1630045248988)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p436)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LH1Ct500-1630045248988)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p437)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e9YIqXe7-1630045248989)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p439)]
Stuxnet’s 21 DLL exports
Taken from the Symantec analysis report on Stuxnet
W32.Stuxnet Dossier by Nicolas Falliere, Liam O Murchu, and Eric Chien

Often DLL behaviour is contained within a DllMain function — called when the DLL started

DllMain与DllEntryPoint:
没有区别,VC++的工程里入口函数叫DLLMain,
在其它编译器里叫DllEntryPoint。

DllEntryPoint:
A DLL entry point, typically called DllMain

DllMain: The DLL entry point. The name DllMain is a placeholder for the library-defined function name. The DirectShow implementation uses the name DllEntryPoint.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XkIyq3b7-1630045248990)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p440)]
第一种可以用工具或写程序完成,不用人眼一个个看。
第二种是运行时监控+打日志

First one is a bit like the old ‘spot the difference’ game
Last one won’t necessary tell us what the program does, but we can use it to see if the program has been monkeyed about with Look at process memory space exploration in the lab

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-klfbRtSh-1630045248996)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p441)]
A bit like ‘spot the difference’
What do we mean by state — files, registry etc. see if any have changed Fortunately we can automate this

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QsOdpuxE-1630045248997)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p442)]

Our static analysis might reveal ‘files of interest’ — if so we can start off by just looking at them — but we might miss something Hashes will tell us which files have changed, but we wouldn’t have the original file to compare with.
e.g. by using a tool such as Regshot

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DGqhdvqe-1630045248998)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p443)]
It might not always do the same thing each time it is run Enables us to confirm our suspicions, for example
if static analysis suggested this was a key logger
Dynamic analysis might reveal the file that’s created containing the logged keys
Can then rollback and run again typing in a specific message to search for in the created file to confirm
What are the limitations of this approach… — get them to think

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kWKgXiNH-1630045249002)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p444)]
What if the malware changes something Then restores the original value
Saw that with SolarWinds — changed the DLLHost.exe registry key Then put it back afterwards
rootkits can hide files from programs running
But not if we look at the file system externally,我们可以看看感染系统之外的的disk image,这样就能看到被rootkit隐藏的信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TijEmcEW-1630045249003)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p446)]
Outside world == anything outside the program

Network easy to intercept Win32 API calls harder

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UrOpPyG0-1630045249004)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p447)]
Assuming we let it talk to the internet
We can feed in our own packets and create a fake internet for the malware to talk to, capturing the data it sends and feeding in our own replies Or proxy the connections to see what it is talking to (And how)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Unmt9alk-1630045249006)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p448)]

使用软件Process Monitor,可以监控每一次windows API的调用,甚至能看到参数传递。

IF networking is easy to monitor, monitoring API calls is harder Look at the tools on Wednesday

WIN32 API CALLS
我们的程序调用Windows的打开进程API,
在中间加入监听器。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YdXLwzkB-1630045249009)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p449)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rgZLlCYv-1630045249010)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p450)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xzZWAChA-1630045249012)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p451)]
e.g. might see that malware makes a DNS lookup to somewhere
Then go and rerun it (from the same starting point) logging connections made to that machine Then find out that the data uses encryption (such as HTTPS)
So run it again using something

3. 高级静态分析

使用逆向工程,将程序拆开,反汇编,看代码,去分析。

学习难度比较高,需要掌握汇编语言,
代码结构,windows操作系统等知识点。

恶意软甲分析是逆向工程的一部分,
拿到1个恶意软件后,通过逆向工程,
可以知道它做了什么,而不是去分析它的源代码。

做软件的流程:
先有想法,用汇编or高级编程语言(例如C)实现,
可以用一些库来帮助自己节省时间。

之后编译器把代码转换成机器码,
这样操作系统才能识别,程序才能运行。

逆向工程分析软件的流程:
我们先拿到机器码或用VB写的脚本、Java脚本,
这些脚本一般会被禁止反编译或被打乱,
所有的变量都被改写成短名称,
空格被删掉,让读者难以理解与阅读。

通过这些脚本或机器码来分析软件做了什么,
之后才去了解里面有什么。

将恶意文件装载到反汇编器中,查看程序指令,
这些指令是被CPU执行的,看看到底它做了什么事情。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n809PW6N-1630045249015)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p459)]

机器码

高级编程语言通过编译器可以编译成机器码。

机器码可以被CPU直接读取并执行的机器指令,
人类不可读,不支持跨平台,
不同种类的CPU执使用的机器码不一样,
机器码的种类也有很多。

操作码 opcode

机器码由操作码(opcode)组成,
操作码是一些十六进制形式的数字,
用于告诉处理器你想要它做什么。

opcode:一条机器指令,
比如我们用汇编语言写的一条操作语句。

程序中的机器码用一系列的二进制操作码表示,
这些操作码代表一组低级指令被CPU执行。

执行的操作都基于这些二级制操作码,
例如1个二进制操作码可能代表2个数相加,
另外1个操作码可能代表去调用某个东西等等。

Prefix (1 bytes optional) !
Opcode can be 1, 2 or 3 bytes!
ModR/M is one byte (optional) — modifies which registers/memory are used! SIB 1 Byte optional !
Displacement (1,2 or 4 bytes) — added on to the address!
Immediate value (1, 2 or 4 bytes) — immediate value if used by the instruction! 64-bit mode can have an extra byte in here too!!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-slOLE8pz-1630045249018)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p466)]

• x86 opcodes can vary in length from 1 to 15 bytes long
• Difficult to fetch from memory, since length is not know till you are three or four bytes into decoding it
• eip points to the first byte of the next instruction, updated as instructions read
• Possibly to use the structure to make it difficult for a disassembler to find code
• But not the CPU…

机器码指令的类型

• Basic operations
• Maths(加减乘除)
• Boolean Algebra
• Comparisons
• Memory Access — usually including support for stacks
• Flow control — jumps and branches (both conditional and unconditional)
• Subroutines,子程序,子过程,调用其他函数,其他函数称为子过程,call谁谁就是谁的子过程。
• And others

Other instructions depend on the type of CPU — RISC CPUs will often just have a minimal subset of the above (perhaps with instructions to switch processor modes)!

CISC CPUS (such as the x86) add loads — AES encoding, string manipulations etc.

通过使用1个或多个机器码指令来模拟高级语言的语法,
例如循环,变量,数组,条件控制等等。

x86体系结构

Windows系统在x86和ARM的CPUs上均可运行,
x86是迄今为止最常见的平台,无论是32位还是64位。

因为x86指令集非常复杂,恶意软件正好可以利用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sqQmK52H-1630045249019)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p476)]
Control Unit通过寄存器(指令指针)从内存中获得指令去执行,寄存器负责存储指令地址。

寄存器是CPU的基础数据存储单元,
经常被用于节省时间,因为不需要CPU访问内存。

ALU(Arithmetic Logic Unit)执行从内存中获取的指令,并将运算结果放回寄存器或内存中。

指令不断被获取被执行的重复过程,
形成了程序的运行。

CISC架构

CISC的英文全称为“Complex Instruction Set Computer”,即“复杂指令系统计算机”,从计算机诞生以来,人们一直沿用CISC指令集方式。

早期的桌面软件是按CISC设计的,并一直沿续到现在。

目前,桌面计算机流行的x86体系结构即使用CISC。
微处理器(CPU)厂商一直在走CISC的发展道路,
包括Intel、AMD,还有其他一些现在已经更名的厂商,如TI(德州仪器)、IBM以及VIA(威盛)等。

在CISC微处理器中,程序的各条指令是按顺序串行执行的,每条指令中的各个操作也是按顺序串行执行的。

顺序执行的优点是控制简单,
但计算机各部分的利用率不高,执行速度慢。

CISC架构的服务器主要以IA-32架构(英特尔架构)为主,而且多数为中低档服务器所采用。

Little-endian:将低序字节存储在起始地址(低位编址)

CPU

CPU中央处理器主要负责执行代码。

  • 1978年6月,Intel推出了8086微处理器,标志着第三代微处理器问世。它采用16位寄存器、16位数据总线和29000个3微米技术的晶体管,售价360美元。不过当时由于360美元过于昂贵,大部分人都没有足够的钱购买使用此芯片的电脑,于是Intel在1年后推出了8位数据总线的微处理器8088。IBM公司1981年生产的第一台电脑就是使用的这种芯片。

  • 70年代末,因特尔生产了著名的16位8086处理器,之后又推出了80186与80286;

  • 1985年,因特尔继摩托罗拉之后,第二个研制出32位的微处理器80386;

  • 1989年,因特尔推出80486处理器,具有浮点运算功能;

  • 1993年,因特尔推出奔腾处理器,不再以数字命名其产品;

在工业界和学术界,
大家仍然习惯性的把因特尔的CPU称为X86系列,
X作为通配符代替前面的数字。

x86正式一点的名字是IA-32(Intel Architecture 32-bit)。

x86架构的特点是CPU的寄存器是32位的,
因此也叫32位CPU。

基于32位CPU开发的操作系统就叫32位操作系统,
因为目前x86架构在32位CPU的知名度,
32位操作系统也通常被称为x86系统。

AMD皓龙,64位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-205Hb5B1-1630045249021)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p456)]

X86和X86_64和AMD64

由于32位系统x86架构的种种限制,
包括速度,性能等方面,
Intel开始向64位架构发展,那么有2选择:

  1. 向下兼容x86
  2. 完全重新设计指令集,不兼容x86

结果AMD领先,比Intel率先制造出了商用的兼容x86的CPU,AMD称之为AMD64,抢了64位PC的第一桶金,得到了用户的认同。

而Intel选择了设计一种不兼容x86的全新64为指令集,称之为IA-64,但是比amd晚了一步,而且IA-64也挺惨淡的,因为是全新设计的CPU,没有编译器,也不支持windows(微软把intel给忽悠了,承诺了会出安腾版windows server版,但是迟迟拿不出东西)。。。

后来不得不在时机落后的情况下也开始支持AMD64的指令集,但是换了个名字,叫x86_64,表示是x86指令集的64扩展。

也就是说实际上,x86_64,x64,AMD64基本上是同一个东西,我们现在用的intel/AMD的桌面级CPU基本上都是x86_64

i386
首先可以简化一个概念,i386=Intel 80386。
i386通常被用来作为对Intel(英特尔)32位微处理器的统称。

但是目前更多的时候,我们公认i386为32位系统,
其实就是x86了。

寄存器

寄存器是CPU中数据的临时基本存储单元,
访问寄存器的速度要高于访问内存的速度,
CPU通过寄存器很多时候不再需要访问内存,
从而节省了时间。

寄存器中既可以存储数据,又可以存储地址。

寄存器主要作用:

  1. 可将寄存器内的数据执行算术及逻辑运算。
  2. 存于寄存器内的地址可用来指向内存的某个位置,即寻址。

x86寄存器种类:

  • 通用寄存器(general registers),8个32位(或64位),用于CPU执行;
    • 段寄存器(segment registers),6个16位,用于定位内存节;
    • 状态标志,Status Register (EFLAGS),用于条件判断;
    • 指令指针,Instruction Pointer (EIP),用于定位要执行的下一条指令;

这里使用32位名称,
在64位模式中e被一个r替换!
64位模式添加了另一个8寄存器r9-r15!

有些特定要求特定的指令值需要存储在特定的寄存器中。

For example, string instructions use the contents of the ECX, ESI, and EDI registers as operands!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6NbyY5ah-1630045249023)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p457)]
Could access the ax register as two 8-bit registers (high byte ah and low byte al)!

The same register was then extended to 32-bits, as eax — but you could still access the 16-bits (ax) or the 8-bit (ah and al) ! (Around the time of 80386)!

The same register was then extended to 64-bits, as rax — but you could still access the 32bits (eax) or the 16-bits (ax) or the 8-bit (ah and al) ! With the AMD Opteron!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5DTwP7ZX-1630045249026)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p458)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hy7OCbyo-1630045249027)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p465)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PW9SeZSU-1630045249029)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p478)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LujQecpJ-1630045249030)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p460)]

通用寄存器

通用寄存器一般用于存储数据或内存地址,
而且经常交换着使用以完成程序。

它们并不通用,一些x86指令只能使用特定的寄存器,
例如:
乘法和除法指令只能使用EAX和EDX。

还有一些约定(convention):
EAX通常存储了一个函数的返回值,看到一个函数调用后立刻使用EAX,可能是在操作返回值。

EAX:累加器(Accumulator),
它的低16位即是AX,
而AX又可分为高8位AH和低8位AL。

EAX是很多加法乘法的默认寄存器,
在80386及其以上的微处理器中可以用来存放存储单元的偏移地址。
AX寄存器是算术运算的主要寄存器。

EBX:基地址寄存器(Base Register),
它的低16位即是BX,而BX又可分为高8位BH和低8位BL。主要用于在内存寻址时存放基地址。

ECX:计数寄存器(Count Register),它的低16位即是CX,而CX又可分为高8位CH和低8位CL。
在循环和字符串操作时,要用它来控制循环次数;
在位操作中,当移多位时,要用CL来指明移位的位数;是重复(REP)前缀指令和LOOP指令的内定计数器。

EDX:数据寄存器(Data Register),
它的低16位即是DX,
而DX又可分为高8位DH和低8位DL。
在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址;
且总是被用来放整数除法产生的余数。

ESI/EDI:分别叫做源/目标索引寄存器(Source/Destination Index Register),
它们的低16位分别是SI、DI。

它们主要用于存放存储单元在段内的偏移量,
用它们可实现多种存储器操作数的寻址方式,
为以不同的地址形式访问存储单元提供方便。

在很多字符串操作指令中,
DS:ESI指向源串,
而ES:EDI指向目标串。

此外,它们又作为通用寄存器可以进行任意的常规的操作,如加减移位或普通的内存间接寻址。

EBP/BSP:分别是基址针寄存器(Base Pointer Register)/堆栈指针寄存器(Stack Pointer Register),低16位是BP、SP,其内存分别放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶/底部。

主要用于存放堆栈内存储单元的偏移量,
用它们可实现多种存储器操作数的寻址方式,
为以不同的地址形式访问存储单元提供方便。

指针寄存器不可分割成8位寄存器。

作为通用寄存器,
也可存储算术逻辑运算的操作数和运算结果。

并且规定:BP为基指针(Base Pointer)寄存器,
用它可直接存取堆栈中的数据;
SP为堆栈指针(Stack Pointer)寄存器,
用它只可访问栈顶。

标志寄存器

在x86架构中,标志寄存器是32位的,
每一位是一个标志,在执行期间,
每一位要么是置位(1),要么是清除(0)。

由这些值来控制CPU的运算,
或者给出某些CPU运算的值。

一些重要的标志:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PyvDYwiG-1630045249031)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p461)]

指令指针

EIP的唯一作用就是告诉处理器下面该做什么,
保存了程序将要执行的下一条指令的内存地址。

攻击者可以通过控制EIP来控制CPU将要执行什么,
改变EIP使其指向恶意代码,从而攻击系统。

指令

指令是由汇编程序构成,在x86汇编语言中,
一条指令由一个助记符(要执行的指令),
以及0个或多个操作数(说明指令要使用的信息)组成。

助记符目标操作数源操作数
movecx0x42

x86有一个寄存器-内存架构,
指令可以在寄存器上操作,
也可以直接在内存上操作。

在32位系统中,每个地址都是4字节长,
因此后面用到参数偏移offset时,需要加4。

操作码和字节序

每条指令使用操作码(opcode=operation code)来告诉CPU要执行什么样的操作。

操作码opcode在这里表示整条机器指令,
反汇编器将操作码翻译成汇编语言。

例如:
mov ecx, 0x42的操作码是B9 42 00 00 00。

其中0xB9对应mov ecx,用0x42000000来表示0x42,是因为x86架构使用小端字节序。

数据的字节序(endianness)是指在一个大数据项中,最高位(大端,big-endian)还是最低位(小端,little-endian)被排在第一位(即被排在最低的地址上)。

一些恶意代码在网络通信时必须改变字节序,因为网络数据使用大端字节序,而x86程序使用小端字节序。

IP地址127.0.0.1会表示为:
大端字节序(网络):0x7F000001
小端字节序(本地):0x0100007F

确保不要把类似于IP地址的重要数据弄反。

x86的CPU是有点无字节序的,
一些常量在内存中的字符串顺序可能是错的,需要改过来。

操作数Operand

操作数是指令要使用的数据,有3种类型。

  • 立即数(immediate)
    固定的值,如0x42。

  • 寄存器(register)
    指向寄存器,如ecx。

  • 内存地址(memory address)
    指向内存地址,一般由方括号内中的值、寄存器或方程式(计算内存地址)组成,如[eax],指向内存地址为EAX处的数据。使用方程式来计算内存地址可以节省空间,不需要额外的指令来计算公式,不加方括号就是一条非法指令。要明确一点,内存地址是可以用来计算的。

常见指令

采用Intel汇编语法,将目标操作数放在前面。

赋值指令

mov destination, source
移动数据,复制,用于读写内存,
将数据从一个位置移动到另一个位置,
将数据移动到寄存器或内存,
注意,这里是直接覆盖,并不会累加。
(mov是最简单常见的指令)

【是复制还是剪切?复制】

mov eax, ebx
将EBX中的内容复制到EAX

mov eax, 0x42
将立即数0x42复制到EAX

mov eax, [0x4037C4]
将内存地址为0x4037C4处的4个字节复制到EAX

mov eax, [ebx]
将EBX指向的内存地址处的4个字节复制到EAX

mov eax, [ebx + esi * 4]
将ebx + esi * 4的计算结果指向的内存地址处的4个字节复制到EAX。

lea distinatioon, source
将内存地址赋给目的操作数,跟mov类似的一条指令,
lea是load effective address的缩写,
即加载有效地址。

lea eax, [ebx+8]
将EBX+8的值给EAX,这个值可能是个地址。

mov eax, [ebx+8]
将内存地址为EBX+8处的数据给EAX。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sEMJ8z2q-1630045249034)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p462)]

解释mov eax, [ebx+8]
寄存器EBX存的值是0x00B30040,
[ebx+8]的意思是计算内存地址,
先做16进制计算,
0x00B30040 + 8 = 0x00B30048,
方括号代表内存地址,
之后找地址为0x00B30048的内存值0x20,
将0x20赋给EAX。
而lea eax, [ebx+8]则是把0xB30048赋给EAX。

此外,lea指令还可以计算普通值,效率更高,
因为需要的指令更少。

lea ebx, [eax * 5 + 5]
其中eax是普通的数而不是内存地址,
这条指令等价于ebx = (eax + 1) * 5。

运算指令

add destination, value
加法,从目标操作数中加上一个值

add eax, ebx
将EBX的值加入EAX并将结果保存在EAX

sub destination, value
减法,从目标操作数中减去一个值
sub指令会修改2个标志:ZF和CF
如果结果为0则ZF被置位,
如果目标操作数比要减去的值小则CF被置位。

sub eax, 0x10
EAX的值减去0x10

inc edx
加一,EDX的值递增1
Increments EDX by 1

dec ecx
减一,ECX的值递减1
Decrements ECX by 1

乘法与除法指令只能使用预先规定的寄存器EAX和EDX,
乘法与除法指令要操作的寄存器一般会在之前许多条指令的地方被赋值,
因此需要在程序的上下文中来寻找。

mul value
乘法,总是将EAX乘上value,
因此EAX必须在乘法指令出现前就赋值好。
乘法的结果以64位的形式分开存储在2个寄存器中,
EDX存储高32位,EAX存储低32位。

mul 0x50
将EAX的值乘以0x50,并将结果存入EDX+EAX中

div value
除法,除法在运算方向上与乘法相反,
将EDX与EAX合起来存储的64位值除以value,
因此在做除法前,EDX与EAX必须赋值好。
除法的商将存储到EAX,余数存储在EDX。

div 0x75
将EDX+EAX的值除以0x75,
并将结果存入EAX,将余数存入EDX。

imul与idiv是mul与div的有符号版本。

xor eax, eax
Clears the EAX register
把eax的值快速设置为0,
将EAX寄存器清零,为了优化,
因为这条指令只需要2个字节,
而mov eax, 0则需要5个字节。

xor ecx, ecx

or eax, 0x7575
对EAX的值进行与0x7575的or操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pDUflGps-1630045249035)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p479)]

shr destination, count
右位移,由count决定移多少位

shl destination, count
左位移,由count决定移多少位

ror,循环右位移,将最低位循环移动到最高位

rol,循环左位移,将最高位循环移动到最低位

mov eax, 0xA
shl eax, 2
将EAX左移2位,这2个指令将导致EAX=0x28,
因为1010(0xA的二进制表示)左移2位之后为101000(0x28)

mov bl, 0xA
ror bl, 2
将BL循环移位移2位,这2条指令将导致BL = 10000010,因为1010向右循环移动2位为10000010。

条件指令

用来做比较的指令,根据比较结果做出决定。

test eax, eax
与自身进行text经常被用于检查是否为NULL,
效率高,消耗字节更少,花费的CPU周期也更少。
条件对比,类似于if,
后面肯定有一个yes或no的分支出来,
test指令执行完毕后去看ZF标志位。

test指令与and指令的功能一样,
但它并不会修改其使用的操作数,
test指令只设置标志位。

test eax,eax基本上和and eax,eax是一样的,
不同的是test不改变eax的结果,
test只是改变FLAG寄存器的状态,
也就是改变进位标志,零标志,溢出标志等等。

test eax,eax
je xxxxxxxx

test指令的操作是将目的操作数和源操作数按位与,
运算结果不送回目的操作数,
然后根据结果设置SF,ZF,PF标志位,
并将CF和OF标志位清零,
一般下面会跟跳转,
根据ZF标志位是否为零来决定是否跳转,
即,这句意思就是判断eax是否为零。

test指令操作是目的操作数和源操作数按位逻辑“与“操作
运算结果不送回目的操作数(基本上和 And eax,eax 是一样的,不同的是test 不改变eax的结果)

然后根据结果设置SF、ZF、和PF标志位,
并将CF和OF标志位清零。
而JE是当ZF=1时跳转。

即,当eax的值等于0时跳转。

因此说,这里的test就是检测eax的值是不是0

Flags
CF是进位标志,
PF是奇偶标志
AF是辅助进位标志
ZF是零标志
SF是符号标志
OF是溢出标志.

cmp [ebp+argc], 3
用参数argc与3进行比较,if(argc!=3)

cmp [ebp+VersionInformatioon.dwplatformId], 2
验证是不是Win32NT的平台

cmp [ebp+VersionInformation.dwMajorVersion], 5
检查操作系统版本,如果大于5则表示高于vista,小于5则是低于vista

cmp指令与sub指令的功能一样,
但cmp不影响其操作数。

cmp指令也是只用于设置标志位,
其执行的结果是,ZF和CF标志位可能发生变化。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sdK3RHIT-1630045249038)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p474)]

分支指令

最常见的分支指令是跳转指令,
在汇编指令中没有if语句,只有条件跳转。
条件跳转使用标志位来决定是跳转,还是继续执行下一条指令。

jmp location
最简单的跳转指令,无条件跳转,不能用于if,
要被执行的跳转一定会被执行,没有任何条件限制。

jmp short
相对短转移
这种指令格式的jmp指令实现的是段内转移,
它的修改范围是:-128 ~ 127,
它向前转移时最多128字节,向后最多127.

jmp near
16位相对近转移
该指令属于段内转移,转移范围是-32768~32767

jz
如果ZF=1,跳转至指定位置。

jnz
条件跳转语句,如果ZF=0,则跳转至指定位置。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EDZCnh7b-1630045249039)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p472)]

重复指令

详略

rep
循环终止条件ECX=0

repe, repz
循环终止条件ECX=0或ZF=0

repne, repnz
循环终止条件ECX=0或ZF=1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QpYRUi3c-1630045249040)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p482)]

rep cmpsb
rep stosb
rep movsb
repne scasb

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EecMpU9P-1630045249043)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p481)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BSVpQlEF-1630045249044)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p483)]

其他指令

对于没有见过的指令可以参考:
http://www.intel.com/products/processor/ manuals/index.htm.

汇编语言

汇编语言是异类语言的统称,
对不同的处理器体系有不同的汇编语言,
这里只涉及到最流行的x86处理器汇编语言。

在没有源码的情况下,我们可以借助反汇编工具来生成汇编代码,然后做逆向工程或去分析代码。

数组

在汇编中,
数组的形式跟定义一排数据的效果是一样的,
前提是必须要定义类型相同的数据。

定义数组元素时,每个元素的地址都是相邻的,
在内存地址上是连续的,
低地址在上面,越往下地址越高。

输入输出系统IO

为硬盘、键盘、显示器等设备提供接口。

内存RAM

内存负责存储数据和代码。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HRstkbGx-1630045249045)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p477)]

数据:一些数据在程序初始加载时被放到这里,成为静态值或全局值,在程序运行时它们不会发生变化,在程序的任何部分都可以使用它们。

代码:在执行程序时CPU所取得的指令。

堆:为程序执行期间需要的动态内存,用于创建(分配)新的值,以及消除(释放)不再需要的值。将其称为动态内存,是因为在程序运行期间内容会经常改变。

x86 MEMORY MODEL
• x86 has various models for how we can access memory
• Segmented memory
• Address accessed built up from the value in a segment register, and the address specified in the instruction
• Fortunately, these days most operating systems use a flat memory model
• But the segment registers still exist…

(Including Windows)

在内存中,地址与数据是2个东西,它们是一一对应的,1个地址对应着1个数据。
而寄存器中只存了1个东西,可能是数据,也可能是地址(引用)。

栈只能用于短期存储,
主要用于管理函数调用之间的数据交换,
给函数、局部变量、参数、
返回地址、流控制结构的内存存储在栈中。

栈是一种用来压和弹操作后入先出(LIFO)的数据结构。

在内存中,栈被分配成从上到下的(数据从上面压入到栈中),
最高的内存地址最先被使用,
持续的往栈中压入数据,则使用越低的内存地址。

内存地址也分大小,[最小的地址/低位内存]在上面,
[最大的地址/高位内存]在下面,
这也是为什么内存地址寻址要用加减法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eLSyOI7m-1630045249046)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p480)]

x86架构中,ESP与EBP原生支持栈,
ESP是栈指针(stack pointer),
包含了指向栈顶的内存地址。
一些数据被压入或弹出栈时,ESP的值相应改变。

EBP是个基指针(base pointer),
在一个函数中会保持不变,
因此程序可以使用它作为占位符来跟踪局部变量和参数的位置。

栈相关指令

push, pop, call, leave, enter, ret.

使用push指令将函数的参数压入栈中,
参数1在最下面,参数2在参数1上面,以此类推。

pop ebx
栈顶的数据会赋给EBX,ESP的值增加4。

函数调用

每一次函数调用,就会产生一个新的栈帧。
函数维护它自己的栈帧,直到返回,
这时调用者的栈帧被恢复,执行权也返回给了调用函数。

许多函数包含一段序言(prologue),
它是在函数开始处的少数几行代码,
用户保存函数中要用到的栈和寄存器。

在函数结尾的结语(epilogue),
将相关的栈和寄存器恢复至函数被调用前的状态。

实现流程:

  1. 使用push指令将参数压入栈中
  2. 使用call指令来调用函数。此时,当前指令地址(EIP中的内容)被压入栈中。这个地址会在函数结束后,被用于返回到主代码。当函数开始执行时,EIP的值被设为函数的起始地址;
  3. 通过函数的序言部分,分配栈中用于局部变量的空间,EBP(base pointer)也被压入栈中。这样就达到了为调用函数保存EBP的目的;
  4. 函数自己的工作;
  5. 通过函数的结语部分,恢复栈。调用ESP来释放局部变量,恢复EBP,以使得调用函数可以准确地定位它的变量。leave指令可以用作结语,因为它的功能是使ESP等于EBP,然后从栈中弹出EBP。
  6. 函数通过调用ret指令返回,这个指令会从栈中弹出返回地址给EIP,因此程序会从原来调用的地方继续执行。
  7. 调整栈,以移除此前压入的参数,除非它们在后面还要被使用。

FUNCTION CALLS
• Like almost all CPUs, x86 supports calling subroutines (function calls)
• Does this using the call instruction
• Address of next instruction can be specified
• Relative (to the current instruction)
• Absolute
• Indirectly (the address pointed to by…)

• Once the destination address is calculated call will then
• Current instruction pointer (eip/rip) pushed onto the stack
• Instruction pointer set to address of start of subroutine
• Can return from a subroutine using ret
• Pops the old instruction pointer from the stack
• Places it into eip/rip so next instruction carries on after call
• Optionally, can then add an offset to the stack pointer

FUNCTION CALLS AND THE STACK
• Note that ret fetches the return address off the stack
• Stack is also used for various other things such as local variables and arrays
• Possibly to overwrite the return value on the stack
• Causing ret to return to a different place
• If malware can control where ret returns to, it can cause a program to do ‘something else’…
• Often used as a vector for initially executing malware code…
• Two mechanisms used
• Cause the stack to be overwritten with the code we want to execute
• Return-oriented programming

Hello, buffer overflow!
There are was to protect against code on the stack using the DEP bit.

FUNCTION CALL ARGUMENTS
• call enables us to call a subroutine, but how do we pass arguments?

• Several conventions used, most involve placing arguments onto the stack

• Caller and callee need to agree on the way arguments are passed…

• Return values passed in eax/rax

• Variations exist on whether it is the job of the caller or the callee to clean the arguments off the stack

• And the order the values are placed on the stack (left to right, or right to left)

• Other variants will use registers to pass values

Note that smaller data types can be promoted in size to larger sizes!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WDpnvTX8-1630045249048)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p467)]
Cdecl default for C/C++ on Windows! Argument length in bytes!
Also clrcall for managed functions! Thiscall default for C++ methods! 64-bit has its own calling convention! As does ARM!

FUNCTION PROLOGUES/EPILOGUE
• Most C compilers will compile a function prologue at the start of the function
• Pushes the current value of ebp
• Sets ebp to value of esp
• Allocate space for local variables on the stack (using sub)
• Preserve registers
• At the end of the function, an equivalent epilogue is generated to restore the stack/registers
• Side-effect of this is that ebp can be used to trace back up the call stack

栈的布局

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8swMG3kl-1630045249051)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p463)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XgudnBwj-1630045249051)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p464)]

反汇编Disassembly

反汇编将操作码转成汇编语言

• Need to also generate labels so we know where branches and subroutine calls go to
• If you come across a branch, subroutine call etc. then you make a note of that as being
another place to start converting code from…
• Should (in theory) find all the code accessible in the program

But as there is more than one way to make a jump !
Possible to have portions of code the disassembler doesn’t find — might come across them and need to go back and reanalyze some more code! (Now what were to happen if we were to jump into the middle of an instruction…)

ASSEMBLY SYNTAX
Two syntaxes used for x86 assembly language
• Intel syntax
• AT&T syntax
• Usual to use Intel syntax for x86 assembly language in the DOS and Windows world
• Instructions tend to have two operands — the first is the destination
• So add eax, 2 would mean eax = eax + 2

AT&T common in the UNIX world (e.g. Linux)! Lets go look at some assembly in Visual Studio 😉!

Ghidra(工具)

https://www.nsa.gov/resources/everyone/ghidra/About-Us/EEO-Diversity/Employee-Resource-Groups/

入口点一般是左侧“Program Tree”下面Exports中的entry或者main。

双击变量或者函数可以进行跳转,
点击变量的右键菜单可以在“References”看到该变量所有被应用的位置。

此外还有一个常用CFG图,在“Window”-“Function Graph”中可以看到,跟随当前程序函数而变化。

查看字符串:
windows-define strings

交叉引用快捷键
command + shift + F

https://www.sohu.com/a/299745429_120054144

个人认为,这2个软件是相辅相成的,
并不是互相取代的关系。

Downloads for Amazon Corretto 11

https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/downloads-list.html

https://ghidra-sre.org/

https://www.shogunlab.com/blog/2019/04/12/here-be-dragons-ghidra-0.html

https://www.shogunlab.com/blog/2019/12/22/here-be-dragons-ghidra-1.html

https://ghidra-sre.org/CheatSheet.html

IDA pro(工具)

免费版下载地址:
https://www.hex-rays.com/products/ida/support/download_freeware/

https://www.cnblogs.com/sch01ar/p/9537760.html

https://blog.csdn.net/dyxcome/article/details/91345138

https://blog.csdn.net/wang010366/article/details/52505345

图形模式左下角的小视图并不是全貌,只是局部视图

交互式反汇编器,可以反汇编整个程序,
执行查找函数,栈分析,本地变量标识等等。

可以保存分析过程,
过程中的所有属性都可以被修改或重新定义。
可以添加注释,标记数据或函数名。
保存后可以下次继续使用。

将文件作为原始二进制文件进行反汇编,
打开文件时,选择binary file。

打开文件时选择手动加载,可以加载PE文件头和所有节,恶意代码经常会往里面隐藏一些信息。

分号后面是注释,可以自己加注释,
右键enter comments。

函数的参数如果是魔法数字则可以改变为参数值为有意义的文字,在参数处右键点击Use standard symbolic constant…在窗口中找到对应的描述,相关内容可以通过msdn查到。

IDA图形视图会有执行流,
Yes箭头默认为绿色,
No箭头默认为红色,
蓝色表示默认下一个执行块,没有控制跳转。

向上箭头一般是循环

在寄存器窗口中显示着每个寄存器当前的值和对应在反汇编窗口中的内存地址。

函数在进入时都会保存堆栈地址EBP和ESP,
退出函数时恢复。

可以对函数进行重命名,右键函数名即可。
可以给假名改成有意义的名字,
相关联的地方会自动更新。

搜索opcode,search-sequence of bytes
find all occurrences.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MNRyKy93-1630045249052)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p469)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GeSFrYak-1630045249054)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p470)]

自动注释
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RtClC96S-1630045249055)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p471)]

可以快速识别出编译器添加的库代码。
左侧的函数列表中,可以过滤函数长度,复杂的函数可能会更长一些,F表示库函数(library functions), 可以在识别函数时跳过这些编译器生成的函数。start函数一般是程序的入口。

快捷键

按G键,可以直接跳转至某一个地址,
例如:0x10001757

按ESC键,退回到上一个界面。

对代码的开头与结束位置选中,按P,将这段代码强制编程一个函数。

按F5键,反编译汇编代码

按空格键,可以在文本模式与图形模式下切换,
只能在IDA View-A。

shift + F12,显示strings窗口,也可以view-subviews-strings。

交叉引用xref

可以查看到函数、字符串、数据被谁调用。

在函数的地址上按快捷键ctrl + x,
看type为P的,调用者地址的前缀可能会重复,
代表是相同的函数,要仔细查看。

可以查看到自负被谁引用,
在自负的地址上按快捷键ctrl + x,
type = r代表读,type = w代表写。

从看字符串被谁引用,则双击字符串后,右侧有个向上箭头,双击后,上下的指令都要看看。

看指令,如果有shell,以及一些系统命令,包括cd,等等,则可能是为攻击者开启一个远程shell对话。

可以为某个函数开启交叉引用图,可以设置深度,
双击进入某个函数,之后点击view-graphs-user xrefs chart…

分析函数

var_或者右边是负数表示局部变量。
arg_或者右边是正数表示参数。

Windows

PEB

PEB(Process Environment Block,进程环境块)是存放进程信息的结构体(一种数据结构),拥有很多字段,包括全局上下文,启动参数,程序映像加载器等。

• Part of the kernel’s data structures about each process

• Fortunately this one lives in user space, so we can access it

• Contains a field called Ldr
• Pointer to a PEB_LDR_DATA structure
• Provides information about loaded modules for the processes

In computing the Process Environment Block (abbreviated PEB) is a data structure in the Windows NT operating system family. It is an opaque data structure that is used by the operating system internally, most of whose fields are not intended for use by anything other than the operating system.[1] Microsoft notes, in its MSDN Library documentation — which documents only a few of the fields — that the structure “may be altered in future versions of Windows”.[2] The PEB contains data structures that apply across a whole process, including global context, startup parameters, data structures for the program image loader, the program image base address, and synchronization objects used to provide mutual exclusion for process-wide data structures.[1]

https://www.cnblogs.com/DeeLMind/p/6854986.html

https://blog.csdn.net/CSNN2019/article/details/113113347

https://blog.csdn.net/CSNN2019/article/details/113105811

https://www.jianshu.com/p/28c8689b22af

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MoTiFewi-1630045249056)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p475)]

typedef struct _PEB
{
    UCHAR InheritedAddressSpace;                     // 00h
    UCHAR ReadImageFileExecOptions;                  // 01h
    UCHAR BeingDebugged;                             // 02h    这里QAQ
    UCHAR Spare;                                     // 03h
    PVOID Mutant;                                    // 04h
    PVOID ImageBaseAddress;                          // 08h
    PPEB_LDR_DATA Ldr;                               // 0Ch
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;  // 10h
    PVOID SubSystemData;                             // 14h
    PVOID ProcessHeap;                               // 18h
    PVOID FastPebLock;                               // 1Ch
    PPEBLOCKROUTINE FastPebLockRoutine;              // 20h
    PPEBLOCKROUTINE FastPebUnlockRoutine;            // 24h
    ULONG EnvironmentUpdateCount;                    // 28h
    PVOID* KernelCallbackTable;                      // 2Ch
    PVOID EventLogSection;                           // 30h
    PVOID EventLog;                                  // 34h
    PPEB_FREE_BLOCK FreeList;                        // 38h
    ULONG TlsExpansionCounter;                       // 3Ch
    PVOID TlsBitmap;                                 // 40h
    ULONG TlsBitmapBits[0x2];                        // 44h
    PVOID ReadOnlySharedMemoryBase;                  // 4Ch
    PVOID ReadOnlySharedMemoryHeap;                  // 50h
    PVOID* ReadOnlyStaticServerData;                 // 54h
    PVOID AnsiCodePageData;                          // 58h
    PVOID OemCodePageData;                           // 5Ch
    PVOID UnicodeCaseTableData;                      // 60h
    ULONG NumberOfProcessors;                        // 64h
    ULONG NtGlobalFlag;                              // 68h    还有这里!_(:зゝ∠)_
    UCHAR Spare2[0x4];                               // 6Ch
    LARGE_INTEGER CriticalSectionTimeout;            // 70h
    ULONG HeapSegmentReserve;                        // 78h
    ULONG HeapSegmentCommit;                         // 7Ch
    ULONG HeapDeCommitTotalFreeThreshold;            // 80h
    ULONG HeapDeCommitFreeBlockThreshold;            // 84h
    ULONG NumberOfHeaps;                             // 88h
    ULONG MaximumNumberOfHeaps;                      // 8Ch
    PVOID** ProcessHeaps;                            // 90h
    PVOID GdiSharedHandleTable;                      // 94h
    PVOID ProcessStarterHelper;                      // 98h
    PVOID GdiDCAttributeList;                        // 9Ch
    PVOID LoaderLock;                                // A0h
    ULONG OSMajorVersion;                            // A4h
    ULONG OSMinorVersion;                            // A8h
    ULONG OSBuildNumber;                             // ACh
    ULONG OSPlatformId;                              // B0h
    ULONG ImageSubSystem;                            // B4h
    ULONG ImageSubSystemMajorVersion;                // B8h
    ULONG ImageSubSystemMinorVersion;                // C0h
    ULONG GdiHandleBuffer[0x22];                     // C4h
    PVOID ProcessWindowStation;                      // ???
}

注册表Registry

注册表是Windows中的一个重要的基于键值对的数据库,用于存储系统和应用程序的设置、配置信息,可以修改注册表信息让特定的程序在特定的时间去运行。

注册表有三种东西:key(路径),value name,value data。

其中存放着各种参数,直接控制着windows的启动、硬件驱动程序的装载以及一些windows应用程序的运行。

这些作用包括了软、硬件的相关配置和状态信息,比如注册表中保存有应用程序和资源管理器外壳的初始条件、首选项和卸载数据等,联网计算机的整个系统的设置和各种许可,文件扩展名与应用程序的关联,硬件部件的描述、状态和属性,性能记录和其他底层的系统状态信息,以及其他数据等。

具体来说,在启动Windows时,Registry会对照已有硬件配置数据,检测新的硬件信息;系统内核从Registry中选取信息,包括要装入什么设备驱动程序,以及依什么次序装入,内核传送回它自身的信息,例如版权号等;

同时设备驱动程序也向Registry传送数据,并从Registry接收装入和配置参数,一个好的设备驱动程序会告诉Registry它在使用什么系统资源,例如硬件中断或DMA通道等,另外,设备驱动程序还要报告所发现的配置数据;

为应用程序或硬件的运行提供增加新的配置数据的服务。配合ini文件兼容16位Windows应用程序,当安装—个基于Windows 3.x的应用程序时,应用程序的安装程序Setup像在windows中—样创建它自己的INI文件或在win.ini和system.ini文件中创建入口;

同时windows还提供了大量其他接口,允许用户修改系统配置数据,例如控制面板、设置程序等。

如果注册表受到了破坏,轻则使windows的启动过程出现异常,重则可能会导致整个windows系统的完全瘫痪。

Windows API
句柄Handle

句柄有点像指针,可以用来引用某个对象或某个内存位置,
但它不能用来进行数学操作,并且它也不总是表示对象地址。

我们可以在程序中使用句柄来引用对象。

调用CreateWindowEx函数可以返回一个HWND窗口句柄,
在想对这个窗口做什么时可以使用这个句柄。

C语言

大量的恶意软件是用C语言编写。

主函数

标准C语言的主函数有2个参数,
int main(int argc, char ** argv)

argc是命令行参数的个数,包括程序名字本身,
argv是字符串数据指针,指向所有的命令行参数。

xxx.exe -r filename.txt

argc = 3
argv[0] = xxx.exe
argv[1] = -r
argv[2] = filename.txt

int main(int argc, char * argv[])
{
    if (argc != 3) {return 0;}
    if (strncmp(argv[1], "-r", 2) == 0) {
            DeleteFileA(argv[2]);
    }
    return 0;
}

这个主函数所对应的汇编代码:

004113CE cmp [ebp+argc], 3 ;判断argc是否等于3
004113D2 jz short loc_4113D8

004113D4 xor eax, eax
004113D6 jmp short loc_411414
004113D8 mov esi, esp

004113DA push 2 ; MaxCount
004113DC push offset Str2 ; "-r"
004113E1 mov eax, [ebp+argv] ; argv数组的开始地址被载入eax
004113E4 mov ecx, [eax+4] ; 对eax加上4(这就是偏移)得到argv[1]

004113E7 push ecx; Str1
004113E8 call strncmp
004113F8 test eax, eax
004113FA jnz short loc_411412 

004113FC mov esi, esp ; 如果命令行中有-r,则这里会被执行
004113FE mov eax, [ebp+argv]
00411401 mov ecx, [eax+8] ; 童年各国argv[]偏移8来获得argv[2]
00411404 push ecx ; lpFileName
00411405 call DeleteFileA

为什么偏移量是4,因为argv[]中每条记录都是一个指向字符串的地址,而在32位系统中,每个地址都是4字节长。

C语言函数

int strncmp(char str1, char str2, size_t n)
把str1和str2进行比较,最多比较前n个字节。

如果返回值 < 0,则表示 str1 小于 str2。
如果返回值 > 0,则表示 str2 小于 str1。
如果返回值 = 0,则表示 str1 等于 str2。

wsprintf
wsprintf()将一系列的字符和数值输入到缓冲区。
输出缓冲区里的的值取决于格式说明符(即"%")。
格式化作用

如果写入的是文字,
此函数给写入的文字的末尾追加一个’\0’。
函数的返回值是写入的长度,但不包括最后的’\0’。

%d 格式化为十进制有符号整数输出到缓冲区
%ld格式化为十进制有符号长整型数输出到缓冲区
%i,li 等同 %d,%ld
%u 格式化为十进制无符号整数输出到缓冲区
%lu格式化为十进制无符号长整型数输出到缓冲区
%s 格式化为字符串输出到缓冲区
%c 格式化为单个字符输出到缓冲区
%x 格式化为无符号以十六进制表示的整数(a-f小写输出)输出到缓冲区
%X 格式化为无符号以十六进制表示的整数(A-F大写输出)输出到缓冲区
%0 格式化为无符号以八进制表示的整数输出到缓冲区
%p 格式化为十六进制指针地址输出到缓冲区
Ix 在64位上格式化为无符号以十六进制表示的长整型数,在32位上格式化为无符号以十六进制表示的整型数(a-f小写输出)
IX 在64位上格式化为无符号以十六进制表示的长整型数,在32位上格式化为无符号以十六进制表示的整型数(a-f大写写输出)

strcmp 字符串比较函数
strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数。基本形式为strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。

lstrcmp
函数功能:比较两个字符串,此比较不区分大小写。
函数原型:int lstrcmp(LPCTSTR lpString1,LPCTSTR lpString2);
参数:
lpString1:指向将被比较的第一个字符串。
lpString2:指向将被比较的第二个字符串。
返回值:若第一个字符串比第二个字符串小则返回值为负;若第一个字符串比第二个字符串大则返回值为正;若两个字符串相等则返回值为0。将被比较的第二个字符串。

memcmp 比较函数
将参数1减去参数2,如果结果是0代表字符串相同。

malloc 分配内存空间

send 发送

atoi
把字符串转换成整型数
ascii to integer

对抗反汇编

在程序中使用一些特殊构造的代码或数据,
让反汇编分析工具产生不正确的程序代码。

这种技术是由恶意软件作者亲手构造,
他们使用对抗反汇编技术来延缓或阻止分析人员,
在恶意代码贬义和部署阶段使用一个单独的混淆工具,
或是直接在源代码中插入混淆代码。

反汇编算法可以分为2种:
线性反汇编算法(容易实现,容易出错),
面向代码流的反汇编算法。

线性反汇编算法:
遍历一个代码段,一次一条指令的线性反汇编,
从不偏离。

ShellCode

ShellCode是一段用于利用软件漏洞而执行的代码,ShellCode为16进制的机器码,因为经常让攻击者获得shell而得名。

ShellCode常常使用机器语言编写。
可在寄存器EIP溢出后,塞入一段可让CPU执行的ShellCode机器码,让电脑可以执行攻击者的任意指令。

4. 高级动态分析

在程序运行时去看机器码,
可以在debugger中运行,
可以一步一步的去debug,
看恶意软件的内部状态。

高价静+高级动可以搞定大部分疑难杂症。

未完待续。

名词解释

Manifest

Manifest是个XML的描述文件,对于每个DLL有DLL的Manifest文件,对于每个应用程序Application也有自己的Manifest。

对于应用程序而言,Manifest可以是一个和exe文件同一目录下的.manifest文件,也可以是作为一个资源嵌入在exe文件内部的(Embed Manifest)。

XP以前版本的windows,会像以前那样执行这个exe文件,寻找相应的dll,没有分别Manifest只是个多余的文件或资源,dll文件会直接到system32的目录下查找,并且调用。

这样,如果公共DLL升级,将会导致之前安装的应用程序不能使用,这就是“DLL Hell”的来源。

为了解决这个问题,.NET开发提出了side-by-by的开发方法,来避免这个问题。

主要方法,就是通过Manifest文件来查找相应的DLL。XP及以后的系统都集成了这样一种查找DLL的方法。

默认Manifest文件都是内嵌在exe/dll中的。

EXE调用DLL的过程
以下针对链接MFCxx.dll, MSVCPXX.DLL, MSVCRxx.dll的程序。
系统启动exe时,会先检查其Manifest文件(如果没有查找到当前EXE中有Manifest,则会报“程序配置不正确的”的错误提示),查找系统中是否有注册相应的Dll组件。如果有,则会去c:\windows\winsxs\Manifest文件夹根据相应的调用策略及Manifest文件,然后再根据Manifest中的内容去c:\windows\winsxs同名文件夹中查找到关的DLL。

如果没有查找到相应的DLL,则会到当前目录来查找Microsoft.VC80.CRT.manifest和Microsoft.VC80.MFC.manifest。
如果没有查找到当前EXE中有Manifest,则会报“程序配置不正确的”的错误提示。查到之后,就会去找相应的DLL。然后执行程序。

选择性看:
This is where your three options for requestedExecutionLevel start to come out:

asInvoker: The application will run with the same permissions as the process that started it. The application can be elevated to a higher permission level by selecting Run as Administrator.

highestAvailable: The application will run with the highest permission level that it can. If the user who starts the application is a member of the Administrators group, this option is the same as requireAdministrator. If the highest available permission level is higher than the level of the opening process, the system will prompt for credentials.

requireAdministrator: The application will run with administrator permissions. The user who starts the application must be a member of the Administrators group. If the opening process is not running with administrative permissions, the system will prompt for credentials.

https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests

Dynamic analysis enables us to see when it calls them
What sequence it is done in
But also potentially what parameters they have.

软件

普通软件

每个软件只能提供一小部分帮助,
因此要灵活综合运用各种软件,才能达到最终效果。

不要被某个点卡住,尝试其他工具或方法,不同的角度去分析。

Sysinternals

Sysinternals之前为Winternals公司提供的免费工具,Winternals原本是一间主力产品为系统复原与资料保护的公司,为了解决工程师平常在工作上遇到的各种问题,便开发出许多小工具。

之后他们将这些工具集合起来称为Sysinternals,并放在网络供人免费下载,其中也包含部分工具的原始码,一直以来都颇受IT专家社群的好评。

Sysinternals Suite包含一系列免费的系统工具,其中有大名鼎鼎的Process Explorer、FileMon、RegMon等,如果把系统管理员比喻成战士的话,那么Sysinternals Suite就是我们手中的良兵利器。

熟悉和掌握这些工具,并且对Windows的体系有一定的了解,将大幅度的提高日常的诊断和排错能力。

UPX

UPX(the Ultimate Packer for eXecutables)是一个非常全面的可执行文件压缩软件,支持 dos/exe、dos/com、dos/sys、djgpp2/coff、 watcom/le、win32/pe、rtm32/pe、tmt/adam、atari/tos、linux/i386 等几乎所有平台上的可执行文件,具有极佳的压缩比,还可以对未压缩的文件和压缩完后进行比较。

可以pack与unpack。

恶意软件
WannaCry

WannaCry(又叫Wanna Decryptor),一种“蠕虫式”的勒索病毒软件,大小3.3MB,由不法分子利用NSA(National Security Agency,美国国家安全局)泄露的危险漏洞“EternalBlue”(永恒之蓝)进行传播 [1] 。

勒索病毒肆虐,俨然是一场全球性互联网灾难,给广大电脑用户造成了巨大损失。最新统计数据显示,100多个国家和地区超过10万台电脑遭到了勒索病毒攻击、感染。 [2] 勒索病毒是自熊猫烧香以来影响力最大的病毒之一。WannaCry勒索病毒全球大爆发,至少150个国家、30万名用户中招,造成损失达80亿美元,已经影响到金融,能源,医疗等众多行业,造成严重的危机管理问题。中国部分Windows操作系统用户遭受感染,校园网用户首当其冲,受害严重,大量实验室数据和毕业设计被锁定加密。部分大型企业的应用系统和数据库文件被加密后,无法正常工作,影响巨大。

Cobalt Strike

https://www.jianshu.com/p/8d823adbc6b5

Cobalt Strike一款以Metasploit为基础的GUI框架式渗透测试工具,集成了端口转发、服务扫描,自动化溢出,多模式端口监听,exe、powershell木马生成等。

一款工具,可以帮你测试系统,
也可以帮你攻击系统。

钓鱼攻击包括:站点克隆,目标信息获取,
java执行,浏览器自动攻击等。

Cobalt Strike 主要用于团队作战,可谓是团队渗透神器,能让多个攻击者同时连接到团体服务器上,共享攻击资源与目标信息和sessions。

Cobalt Strike 作为一款协同APT工具,针对内网的渗透测试和作为apt的控制终端功能,使其变成众多APT组织的首选。

SolarWinds

https://www.4hou.com/posts/pBk6

https://www.microsoft.com/security/blog/2021/01/20/deep-dive-into-the-solorigate-second-stage-activation-from-sunburst-to-teardrop-and-raindrop

IT管理软件提供商SolarWinds,
是一家美国上市公司,网络安全管理软件产品。

微软宣布将从今天开始,强制屏蔽和隔离已知含有Solorigate(sunburst)恶意软件的SolarWindsOrion应用版本。上周末,多家媒体报道称有俄罗斯政府背景的黑客组织入侵了SolarWinds,并在网络监控和库存平台Orion更迭版本中插入了恶意软件。

在之前已经确认黑客攻击了IT管理软件提供商SolarWinds的网络,并用恶意软件Sunburst感染了Orion应用程序的封包服务器。部署Orion应用程序的1.8万个SolarWinds客户都有潜在风险。

SolarWinds网络安全管理软件产品,
SolarWinds正在改变各类规模的企业监控和管理其企业网络的方式。

2020年12月14日,据路透社和《华盛顿邮报》报道,SolarWinds旗下的Orion网络监控软件更新服务器遭黑客入侵并植入恶意代码,导致美国财政部、商务部等多个政府机构用户受到长期入侵和监视,
甚至可能与上周曝出的FireEye网络武器库被盗事件有关。

SolarWinds供应链攻击已经导致许多美国政府机构和私营公司破产。

我们努力为大家提供经济,易于使用,
实施快速和高度有效的软件产品。

这就是为什么全球有超过45,000用户,
不论是小公司还是全球500强企业,
都信任和使用我们的解决方案来探索,配置,监控和管理日趋复杂的系统和构建网络基础构架的流程。

网络安全公司赛门铁克指出,从 SolarWinds 供应链攻击中找到了第四款恶意软件并将其命名为 Raindrop。之前找到的三款恶意软件是 Sunspot、Sunburst (Solorigate) 和 Teardrop。

Solorigate(Sunburst)

一种恶意软件

Solorigate攻击

Teardrop

一种恶意软件

赛门铁克公司表示,Raindrop 仅用于入侵的最后阶段,仅部署于少数精选的几个目标网络中。迄今为止,仅从调查案例中找到4个 Raindrop 样本。

RainDrop

一种恶意软件

Raindrop的发现是SolarWinds攻击的重要一步,
到目前为止,
发现了四个Raindrop样本用于交付Cobalt Strike Beacon,这是一个内存后门,
能够实现执行命令、键盘记录、文件传输、权限提升、端口扫描和横向移动等多种功能。

要了解 Raindrop 在这些攻击活动中的角色和位置,我们必须首先梳理下整个 SolarWinds 事件的时间线。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KBeSkWZ6-1630045249059)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p420)]
从微软、火眼、CrowdStrike 和其它公司提供的信息可知,SolarWinds 攻击事件应该发生在2019年年中,当时黑客(被指和俄罗斯之间存在关联)攻陷了位于美国德克萨斯州的软件厂商 SolarWinds 的内网。
入侵者首先部署了 Sunspot 恶意软件,专攻 SolarWinds 公司内网。CrowdStrike 公司指出攻击者利用 Sunspot 修改 SolarWinds Orion app 的 build 进程并将 Sunburst (Solorigate) 恶意软件放在 IT 存储管理系统 Orion 的新版本中。
这些被木马化的 Orion 版本未被检测到并在2020年3月至6月期间活跃于 SolarWinds 的官方更新服务器中。应用了 Orion 更新的企业也在毫不知情的情况下将 Sunburst 恶意软件安装在系统中。
但 Sunburst 并不复杂且除了收集受感染网络的信息并发送给一台远程服务器外并未做太多的事情。即使约1.8万名 SolarWinds 客户受 Sunburst 感染,但黑客仔细挑选了目标并选择仅在少数几个案例中提升攻击,如美国政府机构、微软或安全公司火眼等高层次目标。
当黑客决定“提升访问权限”时,他们使用 Sunburst 下载并安装 Teardrop 恶意软件。

https://blog.csdn.net/smellycat000/article/details/112914568

一些资料

我如何能远程控制一台计算机?
我如何能写一个最简单的病毒?

https://www.isolves.com/it/aq/hk/

暗网,洋葱路由网络
tor networking
onion routing protocol
洋葱路由协议

http://www.xinhuanet.com//2017-07/21/c_1121360325.htm

并不是完全匿名,谁控制了exit nodes,
谁就可以控制网络流量,
密码可以被软件所破解。

操作系统
gnome

DDOS攻击需要配合在服务器内安装一个rookit一起使用,效果更好。

每次服务器重启都会导致病毒自我复制之后让服务器死机,


如何看系统日志?
如何获得一台局域网内电脑的控制权?

来路不明的下载可能让自己变成肉鸡。


黑客通过未知网站下载、共享文件下载、钓鱼邮件中的木马或攻击系统漏洞的脚本等手段去获取机器的控制权,
这些机器可以是Mac,Windows,甚至智能手机,
之后把所有被感染的机器组织到一个网络中,形成僵尸网络,这个网络中可能存在成百上千甚至几百万台机器,
这些机器被感染后往往用户无法察觉,继续正常使用,
黑客可以远程遥控这些机器,去做一些事情,

例如:
DDOS攻击,挖矿,传播病毒,网络诈骗,垃圾邮件,网络钓鱼,个人隐私数据被盗,造成被勒索或身份盗用,出租或出售僵尸机器的等等。

被感染的机器可能会出现如下情况:
陡增的网络流量,性能降低,CPU不稳定等等。


基本攻击

1、HTTP协议Content Lenth限制漏洞导致拒绝服务攻击
使用POST方法时,可以设置ContentLenth来定义需要传送的数据长度,例如ContentLenth:999999999,在传送完成前,内 存不会释放,攻击者可以利用这个缺陷,连续向WEB服务器发送垃圾数据直至WEB服务器内存耗尽。这种攻击方法基本不会留下痕迹。

2、为了提高用户使用浏览器时的性能,现代浏览器还支持并发的访问方式,浏览一个网页时同时建立多个连接,以迅速获得一个网页上的多个图标,这样能更快速完成整个网页的传输。HTTP1.1中提供了这种持续连接的方式,而下一代HTTP协议:HTTP-NG更增加了有关会话控制、丰富的内容协商等方式的支持,来提供更高效率的连接。


黑客可以利用邮件,比如把邮件地址设置为和你公司邮件域名特别像的域名,给你发一个携带病毒的链接,当你点击的时候(放心,你会点击的),你的电脑就会自动下载病毒,病毒正式控制你的电脑,而你不自知。 这台电脑正式成为一个僵尸主机。僵尸网络本身不是一个物理上的概念,而是指所有被感染的主机组成的全集,是一个逻辑上概念。 一旦你的主机被感染,那么黑客就可以为所欲为了,你懂的,嘿嘿嘿。 曾经有一个例子(某一合法活动),用户被这种方式攻破后,黑客在这台主机里发现了所有业务系统的账号密码以及使用手册(有些用户就这么傻),黑客只需要按照这些手册就可以把所有的业务系统轮一遍,所有的数据全都可以被拿到,或者删除,或者下载。

[1]实际上,真实的网络犯罪分子会通过漏洞正面进攻没有及时打补丁的脆弱系统,也会通过木马病毒侧面进攻缺乏网络安全意识的人,从而获得计算机系统的控制权限,简称“肉鸡”或“僵尸主机”。那么黑客控制了成百上千台“僵尸主机”之后,他会做什么事情呢?这就涉及到僵尸网络的应用场景,最常见的应该是DDoS分布式拒绝服务。举一个不恰当的例子,生活中我们抢口罩、抢红包、抢优惠券,总是抢不到,为什么呢?因为资源是有限的,而竞争者却太多了。拒绝服务的本质和其是类似的,都是通过抢占资源,来迫使服务不可正常使用,僵尸网络发起的拒绝服务攻击,瞬间就可以使中小企业的网站瘫痪。

另一个常见的僵尸网络应用场景是垃圾邮件,因为邮件很傻的保护了发送者的真实地址,为犯罪分子提供了无形的保护伞,而垃圾邮件往往伴随着恶意软件、木马病毒的二次传播,更有钓鱼邮件会诱导身份证、银行卡密码等隐私泄漏。然鹅,这仅仅是僵尸网络应用的冰山一角,站在网络安全研究员的立场上,对僵尸网络还是太缺乏想象。您或许会有疑问?为什么会有人没去谈恋爱,没去玩游戏,而是花费大好时光去攻击你的计算机或手机呢?不妨试试换位思考,你知道恶意软件的创作者都是什么样的人吗?他们又是如何从中牟取暴利的?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sFRmGbY8-1630045249060)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p419)]

1万台“肉鸡”可以发送450万个数据包,
占用4.5G的带宽,
能够让绝大多数网站处于瘫痪的状态,
这些“肉鸡”组成了一个中等的僵尸网络。

网吧僵尸网络攻击1个违法的千年私服,试一下。

网吧岂不是僵尸网络的温床。


一些文件

exe

svchost.exe
svchost.exe通常是services.exe的子进程,
如果是独立存在是高度可疑的。

winlogon.exe
Windows Logon Process(即winlogon.exe),是Windows NT 用户登陆程序,用于管理用户登录和退出。该进程的正常路径应是C:\Windows\System32,且是以 SYSTEM 用户运行,若不是以上路径且不以 SYSTEM 用户运行,则可能是 W32.Netsky.D@mm 蠕虫病毒,该病毒通过 EMail 邮件传播,当你打开病毒发送的附件时,即会被感染。winlogon.exe是潜在被入侵的受害者。

explorer.exe
桌面主程序

wupdmgr.exe
wupdmgr.exe是windows update manger的缩写,是自动升级的程序,存在于c:\windows\system32下,被删除或被重命名后能立即自动生成。

winup.exe
(infecter.undef.65501)是一款infecter被感染文件,infecter作为传统的病毒技术之一,至今仍广泛地使用。
由于infecter类型病毒是通过被感染文件传播的,病毒母体一般无法追查。infecter病毒的危害性主要体现在一旦中毒,
大量文件被感染,在安全厂商未推出解决方案之前,用户不得不重新下载并安装软件。

dll

Kernel32.dll
This is a very common DLL that contains core functionality, such as access and manipulation of memory, files, and hardware.

Kernel32.dll顾名思义就是内核相关的功能,
主要包含用于管理内存、进程和线程的函数;

Advapi32.dll
This DLL provides access to advanced core Windows components such as the Service Manager and Registry.

User32.dll
This DLL contains all the user-interface components, such as buttons, scroll bars, and components for controlling and responding to user actions.

User32.dll中包含的则是用于执行用户界面任务的函数,比如把用户的鼠标点击操作传递给窗口,以便窗口根据用户的点击来执行预定的事件;

Gdi32.dll
This DLL contains functions for displaying and manipulating graphics.

GDI32.dll的名称用了缩写,全称是Graphical Device Interface(图形设备接口),包含用于画图和显示文本的函数,比如要显示一个程序窗口,就调用了其中的函数来画这个窗口。

Ntdll.dll
This DLL is the interface to the Windows kernel. Executables generally do not import this file directly, although it is always imported indirectly by Kernel32.dll. If an executable imports this file, it means that the author intended to use functionality not normally available to Windows programs. Some tasks, such as hiding functionality or manipulating processes, will use this interface.

WSock32.dll and Ws2_32.dll
These are networking DLLs. A program that accesses either of these most likely connects to a network or performs network-related tasks.

Wininet.dll
This DLL contains higher-level networking functions that implement protocols such as FTP, HTTP, and NTP.

sfc_os.dll
关闭Windows文件保护的一种方式

psapi.dll
psapi.dll是Windows系统进程状态支持模块。

urlmon.dll
urlmon.dll是微软Microsoft对象链接和嵌入相关模块。通常情况下是在安装操作系统过程中自动创建的,对于系统正常运行来说至关重要。在正常情况下不建议用户对该类文件(urlmon.dll)进行随意的修改。它的存在对维护计算机系统的稳定具有重要作用。

常见Windows函数

GetModleFileName
返回进程名(包含路径)

GetModuleBaseName
返回进程名(不包含路径)

IsProcessorFeaturePresent
用于获取当前电脑是否支持指定处理器功能特性
获取系统中支持的x86处理器的特性

lstrcpy(LPWSTR lpString1, LPCWSTR lpString2)
拷贝字符串,
把第2个字符串的内容拷贝到第1个字符串。

common Win32 API calls

这里没有的话要去MSDN查。

createDirectory
创建目录

CreateProcessA
创建其他进程,注意程序运行后是否启动了其他程序。

CreateFile
WriteFile
可能在某个位置创建一个文件,我们要思考,
创建了什么文件,文件里包含了什么。

MoveFile
移动文件,我们需要思考,哪个文件被移动了。移动到哪里?

ReadFile
CopyFile
DeleteFile
操作文件

FindFirstFileW
查找到目录下的第一个文件或目录

FindNextFileW
查找下一文件或目录

FindFirstFile/FindNextFile
Used to search through a directory and enumerate the filesystem.

RegisterClassExW
SetWindowTextW
ShowWindow
图形化界面操作f

SetWindowsHookExW
可用于合法或间谍软件,键盘记录器,在调用SetWindowsHookEx的函数中指定指向钩子子程的指针。

LowLevelKeyboardProc,LowLevelMouseProc
跟SetWindowsHookEx一起使用的回调函数,
每次有新的键盘鼠标输入事件时,系统会调用该它们。

LowLevelKeyboardProc与LowLevelMouseProc函数是由SetWindowsHookExW函数用于指定当键盘鼠标事件发生时调用哪个函数。

Hook Procedure有点像事件监听器,一旦它们被注册,当特定事件发生时,它们会被调用,LowLevelKeyboardProc是一个响应键盘动作的hook。

为什么在这个例子中农,LowLevelKeyboardProc与LowLevelMouseProc被设置成导出函数呢?
-这是因为这个函数是由恶意软件dll导出的,因此它们可以被系统自动扫描、导入。

Windows的各个进程的地址空间是相互隔离的,所以一个进程代码是无法到另一个进程的地址空间去运行的.但是通过在进程中安装全局钩子的方法,钩子函数所在的DLL就有可能被操作系统加载到其它进程的地址空间中去,进而实现了DLL注入.实现了DLL注入之后,这个DLL的代码就可以在另一个进程的地址空间里做任何事.

下面简单介绍一下利用钩子注入DLL的步骤

1.调用SetWindowsHookEx安装系统范围内的钩子.

2.将钩子函数的实现写在DLL里

这样,其它接收与这个钩子相关消息的进程就会自动加载这个钩子函数所在的DLL,从而实现了DLL注入.

Windows的钩子Hook也是用来钩东西的,比较抽象的是他是用来钩Windows事件或者消息的。最常见的就是鼠标和键盘钩子,用Hook钩子钩住鼠标、键盘,当你的鼠标、键盘有任何操作时,通过Hook就能知道他们都做了什么了。我们可以在同一个钩子上挂很多东西。

应用程序可以在相应的钩子Hook上设置多个钩子子程序(Hook Procedures),由其组成一个与钩子相关联的指向钩子函数的指针列表(钩子链表)。当钩子所监视的消息出现时,Windows首先将其送到调用链表中所指向的第一个钩子函数中,钩子函数将根据其各自的功能对消息进行监视、修改、控制,,并在处理完成后把消息传递给下一钩子函数,直至到达钩子链表的末尾。在钩子函数交出控制权后,被拦截的消息最终仍将交还给窗口处理函数。

http://blog.sina.com.cn/s/articlelist_1585708262_3_1.html

RegisterHotKey
注册快捷键(例如Ctrl+Shift+P),用户触发后,无论在干什么,都立刻将用户带到注册了快捷键的应用程序。

RegCloseKey
RegDeleteValueW
RegOpenCurrentUser
RegOpenKeyExW
RegQueryValueExW

RegCreateKey
创建注册表的key,此时value是空的。

RegSetValue
设置注册表的value(value name + value data)

注册表相关,需要去搜一下字符串,
有没有注册表键值,
类似于文件目录/xxx/xxx/xxx

Software\Microsoft\Windows\CurrentVersion\Run,恶意软件常用,控制windows启动时会自动装载哪些程序。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w4E370Fq-1630045249061)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p427)]

accept
Used to listen for incoming connections. This function indicates that the program will listen for incoming connections on a socket.

OpenProcessToken+AdjustTokenPrivileges+SeDebugPrivilege+LookupPrivilegeValue,可以4个连着一起用,出现在恶意软件中,比较经典,用来确保有权限去调用某些函数。

OpenProcessToken
函数用来打开与进程相关联的访问令牌。得到进程的令牌句柄。

AdjustTokenPrivileges
Used to enable or disable specific access privileges. Malware that performs process injection often calls this function to gain additional permissions.

SeDebugPrivilege权限
By default, users can debug only processes that they own. In order to debug processes owned by other users, you have to possess the SeDebugPrivilege privilege. But don’t grant this privilege casually, because once you do, you gave away the farm. If you let users debug processes owned by other users, then they can debug processes owned by System, at which point they can inject code into the process and perform the logical equivalent of net localgroup administrators anybody /add, thereby elevating themselves (or anybody else) to administrator.

LookupPrivilegeValue
函数查看系统权限的特权值,返回信息到一个LUID结构体里。

AttachThreadInput
Attaches the input processing for one thread to another so that the second thread receives input events such as keyboard and mouse events. Keyloggers and other spyware use this function.

bind
Used to associate a local address to a socket in order to listen for incom- ing connections.

BitBlt
Used to copy graphic data from one device to another. Spyware some- times uses this function to capture screenshots. This function is often added by the compiler as part of library code.

CallNextHookEx
Used within code that is hooking an event set by SetWindowsHookEx. CallNextHookEx calls the next hook in the chain. Analyze the function calling CallNextHookEx to determine the purpose of a hook set by SetWindowsHookEx.

CertOpenSystemStore
Used to access the certificates stored on the local system.

CheckRemoteDebuggerPresent
Checks to see if a specific process (including your own) is being debugged. This function is sometimes used as part of an anti-debugging technique.

CoCreateInstance
Creates a COM object. COM objects provide a wide variety of functional- ity. The class identifier (CLSID) will tell you which file contains the code that implements the COM object. See Chapter 7 for an in-depth explanation of COM.

connect
Used to connect to a remote socket. Malware often uses low-level func- tionality to connect to a command-and-control server.

ConnectNamedPipe
Used to create a server pipe for interprocess communication that will wait for a client pipe to connect. Backdoors and reverse shells sometimes use ConnectNamedPipe to simplify connectivity to a command-and-control server.

ControlService
Used to start, stop, modify, or send a signal to a running service. If mal- ware is using its own malicious service, you’ll need to analyze the code that implements the service in order to determine the purpose of the call.

CreateFile
Creates a new file or opens an existing file.

CreateFileMapping
Creates a handle to a file mapping that loads a file into memory and makes it accessible via memory addresses. Launchers, loaders, and injec- tors use this function to read and modify PE files.

CreateMutex
Creates a mutual exclusion object that can be used by malware to ensure that only a single instance of the malware is running on a system at any given time. Malware often uses fixed names for mutexes, which can be good host-based indicators to detect additional installations of the malware.

OpenMutex
Opens a handle to a mutual exclusion object that can be used by malware to ensure that only a single instance of malware is running on a system at any given time. Malware often uses fixed names for mutexes, which can be good host-based indicators.

引入互斥量的概念,
保证同一时间只有一个实例在系统中运行。

The program creates a Mutex to ensure only one instance is running

CreateProcess
Creates and launches a new process. If malware creates a new process, you will need to analyze the new process as well.

CreateService
Creates a service that can be started at boot time. Malware uses CreateService for persistence, stealth, or to load kernel drivers.
创建服务,每次系统启动后都会运行。

CreateToolhelp32Snapshot
Used to create a snapshot of processes, heaps, threads, and modules. Malware often uses this function as part of code that iterates through processes or threads.

Process32First/Process32Next
Used to begin enumerating processes from a previous call to CreateToolhelp32Snapshot. Malware often enumerates through processes to find a process to inject into.

OpenProcess
Opens a handle to another process running on the system. This handle can be used to read and write to the other process memory or to inject code into the other process.用于打开要寄生的目标进程。

GetCurrentProcess
获取当前进程的一个伪句柄

GetProcessHeap

CreateRemoteThread
Used to start a thread in a remote process (one other than the calling process). Launchers and stealth malware use CreateRemoteThread to inject code into a different process and inject DLL.远程加载DLL的核心内容,用于控制目标进程调用API函数。创建远程线程。
那我们要思考,是对哪个进程下手?之后调用什么?

WriteProcessMemory
Used to write data to a remote process. Malware uses WriteProcessMemory as part of process injection.用于在目标进程中写入要加载的DLL名称。

VirtualAllocEx
A memory-allocation routine that can allocate memory in a remote process. Malware sometimes uses VirtualAllocEx as part of process injection.用于在目标进程中分配/释放内存空间。

一般是CreateRemoteThread+WriteProcessMemory+VirtualAllocEx作配合,来创建空间,但如果没有调用WriteProcessMemory+VirtualAllocEx,也没有传递DLL名称,那我们怎么知道CreateRemoteThread调用什么呢?我们只能用WriteProcessMemory。DLL必须已经加载进受害者的线程中。

LocalAlloc
局部内存对象的分配
从堆中分配指定大小的字节数
uBytes:[in]指定要分配的字节数。
uFlags:[in] Specifies how to allocate memory. If zero is specified, the default is the LMEM_FIXED flag. The following table shows possible values.

GlobalAlloc
全局内存对象的分配

LocalFree
释放局部内存对象并使句柄失效

CryptAcquireContext
Often the first function used by malware to initialize the use of Windows encryption. There are many other functions associated with encryption, most of which start with Crypt.

CryptGenKey
https://docs.microsoft.com/en-us/previous-versions/aa925731(v=msdn.10)

This function generates a random cryptographic session key or a public/private key pair for use with the cryptographic service provider (CSP). The function retrieves a handle to the key in the phKey parameter. This handle can then be used as needed with any of the other CryptoAPI functions requiring a key handle.

When calling this function, the application must specify the algorithm. Because this algorithm type is kept bundled with the key, the application does not need to specify the algorithm later when the actual cryptographic operations are performed.

CryptEncrypt
https://docs.microsoft.com/en-us/previous-versions/aa925235(v=msdn.10)
This function encrypts data. The key held by the cryptographic service provider (CSP) and referenced by the hKey parameter specifies the algorithm used to encrypt the data parameter.

CryptImportKey
https://docs.microsoft.com/en-us/previous-versions/aa919782(v=msdn.10)
导入秘钥
将密钥从BLOB转换到CSP中

CryptExportKey
https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms884452(v=msdn.10)
This function exports cryptographic keys from of a cryptographic service provider (CSP) in a secure manner.

The caller passes to the CryptImportKey function a handle to the key to be exported and gets a key binary large object (BLOB). This key BLOB can be sent over a nonsecure transport or stored in a nonsecure storage location. The key BLOB is useless until the intended recipient uses the CryptImportKey function, which imports the key into the recipient’s CSP.

DeviceIoControl
Sends a control message from user space to a device driver. DeviceIoControl is popular with kernel malware because it is an easy, flexible way to pass information between user space and kernel space.

DllCanUnloadNow
An exported function that indicates that the program implements a COM server.

DllGetClassObject
An exported function that indicates that the program implements a COM server.

DllInstall
An exported function that indicates that the program implements a COM server.

DllRegisterServer
An exported function that indicates that the program implements a COM server.

DllUnregisterServer
An exported function that indicates that the program implements a COM server.

EnableExecuteProtectionSupport
An undocumented API function used to modify the Data Execution Pro- tection (DEP) settings of the host, making it more susceptible to attack.

EnumProcesses
Used to enumerate through running processes on the system. Malware often enumerates through processes to find a process to inject into.
枚举进程并输入进程名和句柄,会返回给我们进程ID的集合。

EnumProcessModules
Used to enumerate the loaded modules (executables and DLLs) for a given process. Malware enumerates through modules when doing injection.

GetVolumeInformation
获取磁盘驱动器与文件系统等相关信息

FindWindow
Searches for an open window on the desktop. Sometimes this function is used as an anti-debugging technique to search for OllyDbg windows.

FtpPutFile
A high-level function for uploading a file to a remote FTP server.

GetAdaptersInfo
Used to obtain information about the network adapters on the system. Backdoors sometimes call GetAdaptersInfo as part of a survey to gather information about infected machines. In some cases, it’s used to gather MAC addresses to check for VMware as part of anti-virtual machine techniques.

GetAsyncKeyState
Used to determine whether a particular key is being pressed. Malware sometimes uses this function to implement a keylogger.

GetDC
Returns a handle to a device context for a window or the whole screen. Spyware that takes screen captures often uses this function.

GetForegroundWindow
Returns a handle to the window currently in the foreground of the desktop. Keyloggers commonly use this function to determine in which window the user is entering his keystrokes.

gethostbyname
Used to perform a DNS lookup on a particular hostname prior to making an IP connection to a remote host. Hostnames that serve as command- and-control servers often make good network-based signatures.

gethostname
Retrieves the hostname of the computer. Backdoors sometimes use gethostname as part of a survey of the victim machine.

GetKeyState
Used by keyloggers to obtain the status of a particular key on the keyboard.

GetModuleFilename
Returns the filename of a module that is loaded in the current process. Malware can use this function to modify or copy files in the currently running process.

GetModuleHandle
Used to obtain a handle to an already loaded module. Malware may use GetModuleHandle to locate and modify code in a loaded module or to search for a good location to inject code.

GetStartupInfo
Retrieves a structure containing details about how the current process was configured to run, such as where the standard handles are directed.

GetSystemDefaultLangId
Returns the default language settings for the system. This can be used to customize displays and filenames, as part of a survey of an infected victim, or by “patriotic” malware that affects only systems from certain regions.
获取系统默认语言信息

GetWindowsDirectory
Returns the file path to the Windows directory (usually C:\Windows). Malware sometimes uses this call to determine into which directory to install additional malicious programs.

GetTempPath
Returns the temporary file path. If you see malware call this function, check whether it reads or writes any files in the temporary file path.

SHGetSpecialFolderPath
获取系统路径

GetThreadContext
Returns the context structure of a given thread. The context for a thread stores all the thread information, such as the register values and current state.

GetTickCount
Retrieves the number of milliseconds since bootup. This function is sometimes used to gather timing information as an anti-debugging tech- nique. GetTickCount is often added by the compiler and is included in many executables, so simply seeing it as an imported function provides little information.

GetVersionEx
Returns information about which version of Windows is currently run- ning. This can be used as part of a victim survey or to select between dif- ferent offsets for undocumented structures that have changed between different versions of Windows.
获取系统版本信息

IsDebuggerPresent
Checks to see if the current process is being debugged, often as part of an anti-debugging technique. This function is often added by the com- piler and is included in many executables, so simply seeing it as an imported function provides little information.

IsNTAdmin
Checks if the user has administrator privileges.

IsWoW64Process
Used by a 32-bit process to determine if it is running on a 64-bit operat- ing system.

LdrLoadDll
Low-level function to load a DLL into a process, just like LoadLibrary. Normal programs use LoadLibrary, and the presence of this import may indicate a program that is attempting to be stealthy.

LoadLibrary
Loads a DLL into a process that may not have been loaded when the program started. Imported by nearly every Win32 program.
目标进程通过调用此函数来加载病毒DLL

GetProcAddress
Retrieves the address of a function in a DLL loaded into memory. Used to import functions from other DLLs in addition to the functions imported in the PE file header.
通过其他DLL文件引入新的函数使用

GetProcAddress+LoadLibrary表示尝试调用一些DLL的函数。那我们要思考,哪些DLL会被动态加载?之后会调用哪些函数。

LoadResource
Loads a resource from a PE file into memory. Malware sometimes uses resources to store strings, configuration information, or other malicious files.

FindResource
Used to find a resource in an executable or loaded DLL. Malware sometimes uses resources to store strings, configuration information, or other malicious files. If you see this function used, check for a .rsrc section in the malware’s PE header.

SizeofResource
aaa

LsaEnumerateLogonSessions
Enumerates through logon sessions on the current system, which can be used as part of a credential stealer.

MapViewOfFile
Maps a file into memory and makes the contents of the file accessible via memory addresses. Launchers, loaders, and injectors use this function to read and modify PE files. By using MapViewOfFile, the malware can avoid using WriteFile to modify the contents of a file.

MapVirtualKey
Translates a virtual-key code into a character value. It is often used by keylogging malware.

MmGetSystemRoutineAddress
Similar to GetProcAddress but used by kernel code. This function retrieves the address of a function from another module, but it can only get addresses from ntoskrnl.exe and hal.dll.

Module32First/Module32Next
Used to enumerate through modules loaded into a process. Injectors use this function to determine where to inject code.

NetScheduleJobAdd
Submits a request for a program to be run at a specified date and time. Malware can use NetScheduleJobAdd to run a different program. As a mal- ware analyst, you’ll need to locate and analyze the program that will be run in the future.

NetShareEnum
Used to enumerate network shares.

NtQueryDirectoryFile
Returns information about files in a directory. Rootkits commonly hook this function in order to hide files.

NtQueryInformationProcess
Returns various information about a specified process. This function is sometimes used as an anti-debugging technique because it can return the same information as CheckRemoteDebuggerPresent.

NtSetInformationProcess
Can be used to change the privilege level of a program or to bypass Data Execution Prevention (DEP).

OleInitialize
Used to initialize the COM library. Programs that use COM objects must call OleInitialize prior to calling any other COM functions.

OpenSCManager
Opens a handle to the service control manager. Any program that installs, modifies, or controls a service must call this function before any other service-manipulation function.

OutputDebugString
Outputs a string to a debugger if one is attached. This can be used as an anti-debugging technique.

PeekNamedPipe
Used to copy data from a named pipe without removing data from the pipe. This function is popular with reverse shells.

QueryPerformanceCounter
Used to retrieve the value of the hardware-based performance counter. This function is sometimes using to gather timing information as part of an anti-debugging technique. It is often added by the compiler and is included in many executables, so simply seeing it as an imported func- tion provides little information.

QueueUserAPC
Used to execute code for a different thread. Malware sometimes uses QueueUserAPC to inject code into another process.

ReadProcessMemory
Used to read the memory of a remote process.

recv
Receives data from a remote machine. Malware often uses this function to receive data from a remote command-and-control server.

RegisterHotKey
Used to register a handler to be notified anytime a user enters a partic- ular key combination (like CTRL-ALT-J), regardless of which window is active when the user presses the key combination. This function is some- times used by spyware that remains hidden from the user until the key combination is pressed.

RegOpenKey
Opens a handle to a registry key for reading and editing. Registry keys are sometimes written as a way for software to achieve persistence on a host. The registry also contains a whole host of operating system and application setting information.

ResumeThread
Resumes a previously suspended thread. ResumeThread is used as part of several injection techniques.

RtlCreateRegistryKey
Used to create a registry from kernel-mode code.

RtlWriteRegistryValue
Used to write a value to the registry from kernel-mode code.

SamIConnect
Connects to the Security Account Manager (SAM) in order to make future calls that access credential information. Hash-dumping programs access the SAM database in order to retrieve the hash of users’ login passwords.

SamIGetPrivateData
Queries the private information about a specific user from the Security Account Manager (SAM) database. Hash-dumping programs access the SAM database in order to retrieve the hash of users’ login passwords.

SamQueryInformationUse
Queries information about a specific user in the Security Account Man- ager (SAM) database. Hash-dumping programs access the SAM database in order to retrieve the hash of users’ login passwords.

send
Sends data to a remote machine. Malware often uses this function to send data to a remote command-and-control server.

SetFileTime
Modifies the creation, access, or last modified time of a file. Malware often uses this function to conceal malicious activity.

SetThreadContext
Used to modify the context of a given thread. Some injection techniques use SetThreadContext.

SetWindowsHookEx
Sets a hook function to be called whenever a certain event is called. Commonly used with keyloggers and spyware, this function also provides an easy way to load a DLL into all GUI processes on the system. This function is sometimes added by the compiler.

SfcTerminateWatcherThread
Used to disable Windows file protection and modify files that otherwise would be protected. SfcFileException can also be used in this capacity.

ShellExecute
Used to execute another program. If malware creates a new process, you will need to analyze the new process as well.

运行一个外部程序,或者打开一个已注册的文件、打开一个目录、打印文件等等功能,它可以打开电脑内的任何文件,也可以打开URL。

StartServiceCtrlDispatcher
Used by a service to connect the main thread of the process to the service control manager. Any process that runs as a service must call this func- tion within 30 seconds of startup. Locating this function in malware tells you that the function should be run as a service.

SuspendThread
Suspends a thread so that it stops running. Malware will sometimes sus- pend a thread in order to modify it by performing code injection.

system
Function to run another program provided by some C runtime libraries. On Windows, this function serves as a wrapper function to CreateProcess.

Thread32First/Thread32Next
Used to iterate through the threads of a process. Injectors use these functions to find an appropriate thread to inject into.

Toolhelp32ReadProcessMemory
Used to read the memory of a remote process.

URLDownloadToFile
A high-level call to download a file from a web server and save it to disk. This function is popular with downloaders because it implements all the functionality of a downloader in one function call. 如果有这个函数,则需要看一下字符串里是否有URL,如果有的话,很可能是从这里下载的。但我们要考虑,这个文件下载后会写在哪里?

VirtualProtectEx
Changes the protection on a region of memory. Malware may use this function to change a read-only section of memory to an executable.

WideCharToMultiByte
Used to convert a Unicode string into an ASCII string.

WinExec
Used to execute another program. If malware creates a new process, you will need to analyze the new process as well.执行可执行文件,我们要思考,哪个进程被开始新执行?

WlxLoggedOnSAS (and other Wlx* functions)
A function that must be exported by DLLs that will act as authentication modules. Malware that exports many Wlx* functions might be performing Graphical Identification and Authentication (GINA) replacement, as discussed in Chapter 11.

Wow64DisableWow64FsRedirection
Disables file redirection that occurs in 32-bit files loaded on a 64-bit sys- tem. If a 32-bit application writes to C:\Windows\System32 after calling this function, then it will write to the real C:\Windows\System32 instead of being redirected to C:\Windows\SysWOW64.

WSAStartup
Used to initialize low-level network functionality. Finding calls to
WSAStartup can often be an easy way to locate the start of network- related functionality.

GetCurrentProcessId
GetCurrentThreadId
都不是恶意的

CloseHandle
关闭句柄,几乎哪里都用了,没有太多分析价值。

网络

inet_addr
Converts an IP address string like 127.0.0.1 so that it can be used by func- tions such as connect. The string specified can sometimes be used as a network-based signature.

InternetOpen
Initializes the high-level Internet access functions from WinINet, such as InternetOpenUrl and InternetReadFile. Searching for InternetOpen is a good way to find the start of Internet access functionality. One of the parameters to InternetOpen is the User-Agent, which can sometimes make a good network-based signature.
可以设置用于通信的User-Agent字段。

InternetOpenUrl
Opens a specific URL for a connection using FTP, HTTP, or HTTPS. URLs, if fixed, can often be good network-based signatures.
打开一个文件句柄

InternetCloseHandle
关闭已经打开的文件句柄

InternetReadFile
Reads data from a previously opened URL.
从打开的句柄中获取相关的数据

InternetWriteFile
Writes data to a previously opened URL.

InternetGetConnectedState
获取系统网络连接状态,
有可用的网络连接就返回true或1,
否则返回false或0。

导出函数

ServiceMain,
代码需要安装一个服务,使其能够正常运行。

常见CMD命令

sc delete MySQL
删除MySQL服务

taskkill -f -im
taskkill是Windows命令行里终止指定程序“进程”的命令。 /f 表示强制终止 /im 表示指定的进程名称,例如“explor.exe" 如果不使用名称,使用进程号,则用/PID,例如(假设已知道某进程的PID号是3352,PID号可以在windows任务管理器中查看): taskkill /f /pid 3352

tasklist
列出任务列表分

其他资料

汇编
http://www.ruanyifeng.com/blog/2018/01/assembly-language-primer.html

录播课
https://moodle.nottingham.ac.uk/mod/page/view.php?id=4850840;

https://moodle.nottingham.ac.uk/pluginfile.php/7236075/mod_resource/content/0/2020.COMP4101.04.Lab02.pdf

https://moodle.nottingham.ac.uk/pluginfile.php/7236075/mod_resource/content/0/2020.COMP4101.04.Lab02.pdf

B站大学
https://www.bilibili.com/video/BV1e4411r7VP?p=1

https://blog.csdn.net/qq_44370676

https://search.bilibili.com/all?keyword=%E6%B1%87%E7%BC%96&from_source=nav_suggest_new

https://blog.csdn.net/baidu_41108490/article/details/80323492

https://blog.csdn.net/baidu_41108490/article/details/80298973

https://blog.csdn.net/m0_37442062/article/details/102926761

删完注册表之后,想重现注册表,
需要重启Windows Explorer。

xxx.DLL有若干个导入导出函数,想在动态分析时运行这个DLL,如何确定选择哪个函数当做rundll32.exe的参数?

If xxx.DLL has several import and export functions, and I want to dynamic analysis and run this DLL, how could I be sure which function is suitable for the parameter of rundll32.exe when I wanna run this DLL?

You would need to identify the functions which can be run from your static analysis (e.g. via Dependency Walker)

32位文件?64位文件?
我们现在的VM上有快照吗?怎么回滚?没有
W/A suffix是什么?
这些也是函数吗?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fFDtWDjx-1630045249062)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p452)]

C++的库都是以下划线开头的

__crtTerminateProcess

C Runtime library,用C语言编程,
在你的代码运行之前,你需要初始化全局变量或全局变量类型等,你需要用到C Runtime library。

官方电子版
https://ebookcentral.proquest.com/lib/nottingham/reader.action?docID=1137570

Practical Malware Analysis Lab7,9,11
https://blog.csdn.net/qq_35713009/article/details/88388609

https://malware-guide.com/blog/how-to-remove-guesswho-file-extension-ransomware

https://www.pcrisk.com/removal-guides/15384-guesswho-ransomware#creating-data-backups

没有绝对的分析顺序,都是根据线索去理清自己的思路。

基础静态分析

【综合】

  1. 先上传到VirusTotal和hybrid-analysis工具上看看特征,看看反毒引擎的描述,大概判断它的类型;
  2. 通过PEview、PE Studio工具查看相关信息;
  3. 函数名不一定都是大写开头,也有都是小写;
  4. CreateProcess与Sleep普遍在后门程序中出现,它们与与exec、sleep字符串组合出现,exec字符串通过网络给后门程序传送命令,sleep用于命令后门程序进入休眠。

【判断文件是否加壳加密?】

  • 使用PEiD与VirusTotal双保险,看是否有提示,Microsoft Visual C++不是加壳标识;
  • 使用PEview或VirusTotal,看节名称是否为UPX0,UPX1,UPX2,如果是的话代表被加壳,没有名字的节也代表被加壳。此外,节中虚拟大小远超过原始大小,代表是加壳的;
  • 导入函数特别少,不超过10个(Hello World也会比这个多一些),有可能是加壳的,超过10个导入函数少代表是小程序;
  • UPX脱壳命令:upx -o xxx.exe -d Lab01-02.exe
  • size比大小

【字符串里的东西】
即使是加过壳的文件也有可能字符串是没有被混淆过的,
是可读的,因此无论是否加壳都要先看一下字符串。

  • 里面有xxx.exe,代表可能对.exe文件进行操作,可能是受害者,被攻击的对象,目标文件,一些类似以OpenProcess的操作可能都是针对这个xxx.exe的;

  • 有公网IP或网址代表是网络传播恶意软件,字符串里可能用障眼法1和l来迷惑我们,字符串里有的信息可以帮助你去检查被感染机器内的线索,例如Malservice等自定义关键字;

  • 路径信息可能是注册表的key;

【检查脱壳后的信息】
主要是看导入导出函数以及字符串

  • 通过导入导出函数来推测其功能和含义,使用Dependency Walker和VirusTotal来查看导入导出函数,kernel32.dll与msvcrt.dll几乎被每个文件导入LoadResource、FindResource、SizeofResource表示对资源进行操作or对数据进行提取,访问.rsrc分区中的数据,此刻我们要考虑,是什么样的数据,这些数据代表了什么,这些提取出来的数据可以被新建成1个新文件之后完全当成1个新的程序来运行(嵌入在里面的可执行文件)。使用Resource Hacker打开文件,如果是二进制内容,但有一行"This program cannot be run in DOS mode",这个是在所有PE文件头都会包含的错误信息,这表示在这个文件中包含了另一个文件,使用Action->save resource as binary file存储,之后再用PEview等去分析,WinExec执行磁盘上的可执行文件,碰到涉及到注册表的函数,可以搜一下字符串,看是否有相关的注册表键值;

如果是静态分析,先看DLL的导入函数列表,
例如先看kernel32.dll,把一些感兴趣的函数记录下来,
例如:OpenProcess,CreateRemoteThread,(LoadLibrary,GetProcAddress),WinExec,CreateFile,WriteFile,(LoadResource,FindResource,SizeofResource ),MoveFile,GetWindowsDirectory,GetTempPath。
然后记笔记,查笔记。

之后看看有没有对注册表进行操作的函数调用。 (如果没有操作注册表的话就不会使用注册表来进行持久化)

之后是观察字符串,抛掉之前看到的函数名与DLL名,我们还可以看到一些有趣的东西,
例如:winlogon.exe,可能是CreateRemoteThread的潜在受害者。
sfc_os.dll,可疑
SeDebugPrivilege,恶意软件通过获得SeDebugPrivilege来确保有权限调用CreateRemoteThread。

OpenProcessToken+AdjustTokenPrivileges+SeDebugPrivilege+LookupPrivilegeValue,可以4个连着一起用,出现在恶意软件中,比较经典,用来确保有权限去调用某些函数。

\system32\wupdmgr.exe,
可以猜测跟前面的GetWindowsDirectory,
GetTempPath有关,可能用这2个函数在system32路径中用wupdmgr.exe做些什么坏事。
%s%s,跟printf有关

之后把整理出来的信息整合一下,
来推测出恶意软件都做了什么?

EnumProcessModules
psapi.dll
GetModuleBaseNameA
psapi.dll
EnumProcesses
psapi.dll

貌似好像在通过EnumProcesses搜索一个特定的进程,搜索进程中的modules。
我们要考虑是什么进程,winlogon.exe? wupdmgr.exe? winup.exe? wupdmgrd.exe?

我猜可能是winlogon.exe,
因为EnumProcesses会返回给我们进程ID的集合,
通过进程ID我们可以调用OpenProcess来得到句柄,通过句柄我们可以调用GetModuleBaseName,可以得到进程的BaseName。

wupdmgr.exe可能不是,
因为文件名是作为路径的一部分。
winup.exe可能不是,
原因同上,并且后面有%s%s。
wupdmgrd.exe可能不是,原因同上。

在字符串中,这句话出现2次是非常奇怪的: !This program cannot be run in DOS mode. 在字符串中,第2次出现这个的地方下面很可能是一个全新的可执行文件, 可能存在文件嵌套的情况。

一般的套路:先建1个文件,再把它写在某个地方。

用其他的可执行文件替换windows update manager(wupdmgr.exe)可以进行持久化。

基本动态分析

动态分析后回告诉你字符串里的东西与导入函数是如何被使用的。

【前置准备工作】
0. 先进行静态分析;

  1. 运行Process Monitor,设置过滤恶意代码名称,运行前清空所有事件,先停止Capture Events再运行;
  2. 运行Process Explorer;
  3. 使用Regshot进行注册表的第1次快照;
  4. 使用xxx去模拟虚拟网络(暂时没有);
  5. 设置WireShark记录网络行为(暂时没有);

【开始运行】
点击运行恶意软件,运行一段时间后(不要太短)。。。
如果是DLL则需要用rundll32.exe

使用Process Explorer来确定rundll32.exe已经停止,不在进程列表中了,这时再做第2个快照。

【运行结束】

  1. 停止Process Monitor的事件捕获;
  2. 使用Regshot进行注册表的第2次快照;
  3. 检查是否有DNS请求(暂时没有);
  4. 查看Process Monitor的监视结果,并不是所有的操作都有意义,双击条目,如果是创建了1个新文件且相同,可能是把自己复制到了新的位置,可以用在Process Explorer中发现的PID进行过滤;
  5. 比较Regshot的2次快照的变化,如果是往这里添加HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run,代表系统启动自动运行。

可能出现安装xxx服务,
那就需要再用net start xxx启动服务,
在注册表的values中能看到,DLL文件需要依赖一个EXE文件去运行,会运行在xxx.eve中,
需要查看每个相关进程直到找到当前dll,或者用Process Explorer的Find DLL来搜索。(Lab03-02.dll)

显示的服务名为Intranet Network Awareness (INA+),描述为“Depends INA+, Col- lects and stores network configuration and location information, and notifies applications when this information changes.”

被安装咋注册表:HKLM\SYSTEM\CurrentControlSet\Services\IPRIP\ Parameters\ServiceDll: %CurrentDirectory%\xxx.dll

  1. 使用Process Explorer来检查进程,以确定是否产生互斥或监听端口接受外来连接。单击xxx.exe进程,选择view->lower pane view->handles,可以看到创建的互斥量(mutant),选择view->lower pane view->DLL,可以看到恶意代码动态装载的DLL文件;
  2. 查看网络通信(暂时没有)

高级静态分析

函数有2种,一种是引入的,一种是自定义的。

链到IDA pro章节

开启Ida pro的自动注释和机器码功能,非常有用。

如果遇到一个函数中只有xor、or、and、shl、ror、shr、rol这样的指令,并且反复出现,看起来随机排列,可能遇到了一个加密或压缩函数,不用看细节,直接跳出来,继续后面的分析。

有的程序太大太复杂,
千万不要一个指令一个指令的找线索,非常浪费时间,
把握整体,抽象成块状结构,可以只看call指令。

在IDA pro文本模式下的左侧箭头代表跳转,
向上箭头代表循环,
如果是实线表示一定会发生,
如果是虚线表示可能会发生(有条件)。

在分析dll文件时,导出函数列表非常有用。

看到可疑的字符串与函数时时,可以用IDA pro的交叉引用,看哪些地方调用了。

子过程函数内部的开头部分会有局部变量或者参数,
如果跟着的整数是正数则表示是参数,
负数表示是局部变量。

可以在IDA pro中对一些数值进行转换,
可以转化成2、8、10、16进制、符号等等,
只要在数值上按右键即可。

使用IDA Pro,1个机器码是16进制形式,每个机器码都占1个内存位置,
例如:
.text:004012BC 52
.text:004012BD 6A 01
.text:004012BF 8B 85 FC FE FF

寻址时,在32位下,+1就是往后定位1个机器码

反抗反汇编

需要打开左侧的机器码显示功能。

将程序中不合理的地方调整为正常代码。
寻址带加号的数字都要看看,不是+4,+8的那种,
+1,+2的那种是无效地址,因为位于2条指令中间。

jz short near ptr unk_40126D
jnz short near ptr unk_40126D
【相同目标的跳转指令】
2个紧挨着的跳转指令跳转到相同的位置,
把光标放在40126D地址处,
在IDA Pro按D键,转换成数据的形式。

call near ptr CB4C550XX
call的地址感觉是荒谬的,不可跳转的,
把光标放在地址处,在IDA Pro按D键,转换成数据的形式。(IDA会标红)

jmp short near ptr loc_401215+1
jmp要跳转的地方紧挨着自己
把光标放在401215地址处,
在IDA Pro按D键,转换成数据的形式,
跳过某个几个的机器码(+几就跳几),
在IDA Pro按C键,转换成代码的形式。

test esp, esp
jnz short near ptr loc_401010+1

xor eax, eax
jz short near ptr loc_401010+1
【固定条件的跳转指令】
跳转到一段指令的中间位置(那个+1)是很不正常的,
把光标放在401010地址处,
在IDA Pro按D键,转换成数据的形式。

要跳过,机器码
db 0E8h(理论上EB代表call,在E8后面紧跟着的内容就是目的地。E8的出现是为了欺骗反汇编器的陷阱)
db 0E9h (jmp)
db 0EBh

db 8Bh
db 45h
db 0Ch
db 0Fh
没有对齐,一直转换到一条指令挨着一条指令,
在IDA Pro按C键,转换成代码的形式。
此外还有一些稀奇古怪的东西也可以用C键:
db 824648Bh, 0A164h等等

jz short near ptr loc_4012E6+2
向上跳转,跳转到了当前位置上面的位置
先看4012E6的机器码,假如是66 B8 EB 05,
把光标放在4012E6地址处,
在IDA Pro按D键,转换成数据的形式,
因为是+2,因此跳过66 B8,之后将其余部分
db转化成代码,
在IDA Pro按C键,转换成代码的形式。

转化完成的代码中可能包含一些多出来的机器码,
这些机器码会阻碍IDA把一段代码转化成图形形式,
可以用90这个机器码(Null)来把它们弄掉,
需要编写idc脚本。

一些常见指令

3行指令可以是组合起来做1件事情。

一些约定:
EAX通常存储了一个函数的返回值,看到一个函数调用后立刻使用EAX,可能是在操作返回值。

EBP通常引用局部变量、传进来的参数。
EBP通常引用局部变量、传进来的参数。
EBP是个基指针,在一个函数中会保持不变,
因此程序可以使用它作为占位符来跟踪局部变量和参数的位置。

ESP是栈指针,包含了指向栈顶的内存地址,
数据被压入或弹出栈时,ESP的值相应改变。

乘法与除法指令只能使用EAX与EDX。

清理栈,调用windowsAPI不需要清理栈,
相应的DLL程序会负责清理栈。

add esp, 12

ascii_stricmp是实现,文档跟stricmp一样。

cmp [ebp+argc], 3
; argc是个参数,[ebp+argc]表示参数开始地址,与3进行比较。

push 2
push offset Str2 ;"-r"

mov eax, [ebp+argv]
; 数组的开始地址被加载进EAX

mov ecx, [eax+4]
; 对eax里保存的内存地址加4做偏移,
; 获得数组里第2个下标,加8就是第3个下标。

push ecx ; Str1
; strncmp(argv[1], "-r", 2)

在指令中的dword_40CF60表示变量存储在,
0x40CF60这个内存地址中。

2个全局变量相加,需要将x先复制到eax,
之后在eax上加y,再把eax复制回x。

全局变量通过内存地址引用:

int x = 1;
int y = 2;
void main() {
  x = x+y;
  printf("Total = %d\n", x);
}

mov eax, dword_40CF60
# 全局变量x通过dword_40CF60来标记,在0x40CF60处的内存位置。
add eax, dword_40C000
# 全局变量y通过dword_40C000来标记,实行x+y。
mov dword_40CF60, eax
# 把x+y赋值给x
mov ecx, dword_40CF60 
# 装载成参数,准备压入栈中
push ecx
push offset aTotalD ;"total = %d\n" 

call printf

局部变量通过栈地址引用:

void main(){
  int x = 1;
  int y = 2;
  x = x+y;
  printf("Total = %d\n", x); 
}

# 未标记
mov dword ptr [ebp-4], 0 
mov dword ptr [ebp-8], 1 
mov eax, [ebp-4]
add eax, [ebp-8]
mov [ebp-4], eax
mov ecx, [ebp-4]
push ecx
push offset aTotalD ; "total = %d\n" 
call printf

# 标记后
mov [ebp+var_4], 0 
mov [ebp+var_8], 1 
mov eax, [ebp+var_4] 
add eax, [ebp+var_8] 
mov [ebp+var_4], eax 
mov ecx, [ebp+var_4] 
push ecx
push offset aTotalD ; "total = %d\n" 
call printf

算数运算:

int a = 0; 
int b = 1; 
a = a + 11; 
a = a - b; 
a--;
b++;
b = a % 3;

mov [ebp+var_4], 0
mov [ebp+var_8], 1
mov eax, [ebp+var_4]
add eax, 0Bh
# 11转成16进制是0B。

mov [ebp+var_4], eax

mov ecx, [ebp+var_4] 
sub ecx, [ebp+var_8]
mov [ebp+var_4], ecx

mov edx, [ebp+var_4]
sub edx,1
mov [ebp+var_4], edx

mov eax, [ebp+var_8] 
add eax,1
mov [ebp+var_8], eax

mov eax, [ebp+var_4]
cdq
mov ecx, 3
idiv ecx
mov [ebp+var_8], edx

if跳转,对于跳转最好是看图形化界面,更容易理解:

int x = 1;
int y = 2;
if(x == y){
  printf("x equals y.\n");
}else{
  printf("x is not equal to y.\n");
}

mov [ebp+var_8], 1
mov [ebp+var_4], 2
mov eax, [ebp+var_8]
cmp eax, [ebp+var_4]
jnz short loc_40102B
# 如果x!=y,则跳转会发生,否则不会发生。
push offset aXEqualsY_ ; "x equals y.\n"
call printf
add esp, 4
jmp short loc_401038
# 无条件跳转
loc_40102B:
push offset aXIsNotEqualToY ; "x is not equal to y.\n"  
call printf

嵌套if:

int x = 0; 
int y = 1; 
int z = 2;
if(x == y){
  if(z==0){
    printf("z is zero and x = y.\n");     
  }else{
    printf("z is non-zero and x = y.\n");
  }
}else{
  if(z==0){
    printf("z zero and x != y.\n"); 
  }else{
    printf("z non-zero and x != y.\n"); }
}

# 详略

循环:

int i;
for(i=0; i<100; i++) {
  printf("i equals %d\n", i); 
}


mov [ebp+var_4], 0
# 初始化i
jmp short loc_401016
loc_40100D:
mov eax, [ebp+var_4]
add eax, 1
mov [ebp+var_4], eax
# i自增1
loc_401016:
cmp [ebp+var_4], 64h
# 比较i与100,16进制的64=10进制的100
jge short loc_40102F
# 如果不符合条件就跳出循环

mov ecx, [ebp+var_4]
push ecx
push offset aID ; "i equals %d\n" 
call printf
# 打印i
add esp, 8
jmp short loc_40100D
# 跳转回去继续循环你

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GguZbCuc-1630045249063)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p473)]

while循环:

int status=0; 
int result = 0;
while(status == 0){
  result = performAction(); 
  status = checkResult(result);
}

mov [ebp+var_4], 0
mov [ebp+var_8], 0
loc_401044:
cmp [ebp+var_4], 0
jnz short loc_401063
call performAction
mov [ebp+var_8], eax 
mov eax, [ebp+var_8] 
push eax
call checkResult
add esp, 4
mov [ebp+var_4], eax 
jmp short loc_401044 

nop
什么都不做,当它出现时,直接执行下一条指令,
这条指令的opcode是0x90,可以起到填充代码的作用,
降低shellcode可能在中间部分开始执行所造成的风险。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TXnmd8eh-1630045249064)(evernotecid://BCE3D193-8584-4CB1-94B3-46FF37A1AC6C/appyinxiangcom/12192613/ENResource/p468)]

call
把call指令的下一条指令的地址入栈,调用函数,函数执行完毕后,执行ret指令,将返回地址弹出到栈的顶部,并将它载入指令指针寄存器中,执行刚好返回到call后面的指令。

pop edi
将栈顶的内容出栈并保存在edi寄存器。

PTR 运算符可以用来重写一个已经被声明过的操作数的大小类型。只要试图用不同于汇编器设定的大小属性来访问操作数,那么这个运算符就是必需的。

注意,PTR 必须与一个标准汇编数据类型一起使用,这些类型包括:BYTE、SEYTE、WORD、SWORD、DWORD、SDWORD、FWORD、QWORD 或 TBYTE。

将较小的值送入较大的目的操作数

lodsb 指令:从esi指向的源地址中逐一读取一个字符,送入AL中; (然后,可以先判断这个字符是什么字符,如0dh,0ah之类等,再执行相应的操作);

汇编语言中,串操作指令LODSB/LODSW是块装入指令,其具体操作是把SI指向的存储单元读入累加器,LODSB就读入AL,LODSW就读入AX中,然后SI自动增加或减小1或2.其常常是对数组或字符串中的元素逐个进行处理。

(1) lodsb、lodsw:把DS:SI指向的存储单元中的数据装入AL或AX,然后根据DF标志增减SI。

(2) stosb、stosw:把AL或AX中的数据装入ES:DI指向的存储单元,然后根据DF标志增减DI

Practical Malware Analysis纸质书

每个小节都会有3个试验,难度依次提升,
第三个试验是最难的,第一个是最简单的。

第2章纸质书,建虚拟机,直接忽略掉。

恶意代码样本下载,
www.practicalmalwareanalysis.com
https://nostarch.com/malware.htm

虚拟机
不要在自己的机器上去run恶意软件,
用lab上的VM去run,
把windows自带的杀毒软件防火墙关掉,
随时准备开回来。

用虚拟机可以模拟多种操作系统的版本,
方便做测试。

如果在虚拟机中做动态分析时,
恶意软件把系统弄坏了,
可以恢复到上一个快照。

有些病毒知道自己运行在虚拟机中,
则会表现的不一样。

恶意软件会侦测到自己是运行在虚拟机中还是真实的系统中,会有一些差异化。

有些病毒会突破虚拟机跑到宿主机上来。
https://en.wikipedia.org/wiki/Virtual_machine_escape

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值