热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

恶意软件分析的最佳编程语言及其应用

本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。

 

在过去,许多人会经常问我一个问题:“我想要入门恶意软件分析和逆向工程领域,应该学习什么编程语言?”为了回答这个问题,我将详细讲解我认为最适合的前三种语言,希望大家可以通过阅读本文找到自己认为最有用的语言。在本文中,我将重点讨论本地恶意软件(也就是不需要Java、Python或.NET等框架就能直接运行的恶意软件),因为这是最常用的类型,如果能够理解了这一类型,那么对其他类型的恶意软件也就变得轻车熟路。本文将不会涉及物联网或移动恶意软件的相关内容,因为我对这一领域并没有太多的经验。

 

第三名:Python

Python是一种具有多种用途的语言,当我需要快速完成某些工作时,我会选择使用Python语言。虽然其他几种语言的开发速度很快,但我发现Python具有可读性高、可快速开发、易于学习的优点。由于Python是一种解释型语言,所以解释器可以为我们完成不同操作系统之间的所有转换,因此我们仅需要编写一次代码就可以一劳永逸,而我们的代码可以在任何操作系统上运行。尽管我是一位Linux服务器的忠实粉丝,但我还是使用Windows作为日常主要使用的操作系统。因此,如果能在我的Windows上面编写并测试代码,然后在完成后将其上传到服务器上,这样就会特别方便,而不再需要尝试通过PuTTY终端开发和测试代码。


恶意软件分析

我最喜欢的一个Python的用途就是快速复制恶意软件的组件,以便更好地理解其工作方式,并获得恶意软件自身的接口,从而实现更快速的分析。我的TrickBot工具包就是一个很好的例子,它能有助于解决逆向模块化恶意软件时所遇到的一些问题。
我在研究TrickBot的过程中,遇到的一个主要问题就是它会使用被黑客入侵的服务器来控制恶意软件,当然,其中大部分服务器都会很快就关闭。在获得新样本后的几天之内,所有硬编码的控制服务器都会发生死机,并且样本开始失效。在对恶意软件所使用的加密和解密代码进行分析之后,我可以编写一个简单的Python脚本,该脚本可以允许我解密并修改任何TrickBot的配置文件,我通过这些文件来编辑主配置文件,并为其指定新的控制服务器,这些控制服务器是其他恶意软件分析者在网络上发布的。
我写的另一个脚本是用于命令与控制的基础结构接口,该脚本可以帮助我在不运行恶意二进制文件的前提下,就能获取到命令、有效载荷以及新的服务器地址。如果我们非常注重个人主机的风险防范,那么可能不希望在连接到互联网的系统上运行恶意软件。相反,通过Python来离线分析恶意软件并重新实现需要访问互联网的代码,这是非常有意义的。我们可以完全控制恶意软件的功能,使其不再发送真实数据,甚至是发送蜜罐凭据。


调试器扩展

通常,分析任务往往是枯燥、无聊的,并且需要耗费大量的时间,所以如果能识别这些任务并使其自动化完成,那么将会非常有帮助。我所使用的每个调试器和反汇编器都有自己的内置语言脚本,但如果我们使用多个调试器或反汇编器,那么恐怕就需要学习大量不同的脚本语言,这是没有意义的。但幸运的事,几乎所有的调试器或反汇编器都支持Python。
以前我写过一篇文章,主要讲解了如何使用Python实现任务的自动化,在文章中我是以IDA Pro为例的。在我的分析中,我使用了Python对Dridex系列进行自动解密、评论和转储加密字符串。此外,我还展示了如何使用它来处理只能在调用时才能解析的问题,这样使得静态分析更为简单。
在上面的示例中,脚本会遍历Dridex二进制文件中的每个加密字符串。然后进行解密,并转储每个字符串,在这过程中不需要运行恶意软件。


任务自动化

Python以其拥有大量可下载的库而闻名,它实现了各种不同的功能,可以让用户无需从头开始编写代码,就能够在计算机上高效地自动执行几乎任何任务。使用Python进行任务自动化,不仅仅适用于恶意软件的分析,对其他许多方面的工作都很有用。我编写过脚本来检查命令与控制域、在VirusTotal上传或查询文件、加载用于分析恶意软件的虚拟机等。Python是编程界的瑞士军刀,值得我们对其进行学习,并用于分析恶意软件。

 

第二名:C

对于作者而言,C语言是我在12岁开始学习相关技术之后,第一个熟练掌握的编程语言。由于我的梦想是成为一名程序员,因此我学习C的初衷并不是想研究逆向工程,也没有想到我学到的知识会在如今作为恶意软件分析工作的基础。尽管我并不会坚持让你掌握C语言,但我会在本文中提出如何阅读和理解的相关建议,这对于恶意软件分析来说是有所帮助的。


查看官方文档

即使对于一个经验丰富的逆向工程师,有时也会遇到不熟悉的某个恶意软件代码中的函数调用。如果想要了解该函数的功能、参数、如何对其初始化、返回什么结果,那么最好的方法就是调出文档并进行阅读。
例如,我们在Windows和Linux文档中查看“connect”函数。


在这两种环境下,函数的定义都是用C语言写成的(尽管左边的MSDN文档中说是C++,但实际上就是C语言)。在C中,传递给函数的每个参数都有一个“类型”,它只是指定其所包含的数据类型(数字/文本/二进制数据)。在示例中,第三个参数都是“sockaddr”类型,这是一个常见的C语言中的类型。如果能了解“sockaddr”是什么,我们就能够知道它需要什么数据、如何对其进行引用以及如何对其进行解释。由于“sockaddr”是一个结构,我们必须首先查找sockaddr的定义,找到它的数据类型,然后查找每个单独的数据类型,这实际上也是学习C语言的过程。MSDN中也经常提供示例C语言代码,来解释一个函数中的用法,阅读这些代码是了解函数之间关系的一种快速而有效的途径。


无官方文档的情况

对于像Microsoft Windows这样的闭源操作系统,就有很多没有记录的数据结构和功能,其原因通常是它们不应该被除微软之外的任何人使用。这些数据结构和功能通常被称为Windows内部机制。恶意软件开发者喜欢滥用内部机制来绕过安全控制,或者是为了迷惑恶意软件分析师。为了了解其内部结构,尽管我们可以对操作系统自身进行逆行工程,但该过程耗时过多且异常困难。然而,如果我们掌握了C,就有一个更快的方式。
(1) ReactOS源代码
ReactOS是一个用C语言编写的开源操作系统,旨在与Windows Server 2003可执行文件相兼容。为了保证与Windows二进制文件的兼容性,开发人员必须对NT 5.2(用于Windows 2000、Windows Server 2003和Windows XP的Windows操作系统核心版本)进行逆向工程并重新实现,因此许多Windows中的相关机制都可以通过ReactOS来了解。由于Windows XP仍然占有较大的市场份额,因此恶意软件开发者仍然会为了使他们的恶意软件兼容XP,而付出很多的努力,所以我们很难看到不支持5.2内核的恶意软件。就我个人而言,我借助ReactOS源代码来了解Windows内部知识,这样我就可以在真正的Windows操作系统上成功使用它了。
(2) Windows研究内核
Windows Research Kernel(WRK)是微软为研究人员提供的NTOS内核源代码的一个子集,其中包含大部分核心内核的源代码,但也有一部分内容被删除。尽管WRK仅包含Windows的内核部分,但它仍然可以用于帮助我们理解非内核的恶意软件,因为内核的某些部分经常被Rookie滥用的“Native API”暴露给用户级应用程序。最初,WRK很难获得,只作为各种计算机科学研究计划的一部分提供给经过认证的大学,但从那时开始,一些旧版本陆续被发布到GitHub,因此微软决定公开发布。尽管WRK不像ReactOS那样完整,但它还是具有一些优点,例如包含64位Windows内核的代码,并且它是由Microsoft编写的实际代码,并不是通过逆向工程而制作的副本。


泄露的恶意软件

要了解恶意软件工作模式并在逆向工程中读取实际恶意软件的源代码,最好的方法之一就是阅读真实恶意软件的源代码。显然,恶意软件开发者并不会轻易公开源代码,所以我们不可能获得大部分恶意软件的源代码。但是,一些庞大的恶意软件家族的源代码会在某个时间节点被披露(例如Zeus、Mirai、Carberp、ISFB、Rovnix)。大部分泄漏的恶意软件源代码都可以在GitHub找到,但我建议最好避免下载这些代码,因为其中可能会存在感染计算机的威胁。请注意,在某些国家,拥有恶意代码甚至可能违反法律。


IDA Pro伪代码

带有反编译器的完整版IDA Pro中有一个选项,可以将程序集显示为“伪代码”,这会导致它提供与程序集相匹配的代码。


虽然IDA伪代码在技术上并不是100%有效的C语言代码,其中有着细微的差别,但对于任何能阅读C语言的人来说,该伪代码都是清晰可读的。伪代码可以让我们快速了解代码的功能,可以有效节省时间。

 

第一名:汇编语言

汇编语言(ASM)是每一位逆向工程师的工具箱中最重要的一个工具,它是机器码的人类可读版本,是计算机CPU实际理解的唯一语言。任何在没有解释器的情况下在计算机上运行的代码,都必须被编译成机器代码,机器代码是一组0、1指令,该指令告诉CPU要做什么。像C、C++、GoLang、Pascal和Haskell这样的语言,都会被编译(翻译)成机器代码,因此大多数软件(包括恶意软件在内)都可以使用反编译器(将机器代码翻译成人类可读版本的汇编语言)。如果你能够很好地阅读汇编语言,那么就不需要使用高级语言,直接可以分析汇编语言的代码。同样,这一技能在恶意软件分析之外的很多地方都非常有用。
然而,因为汇编语言只是一个人类可读版本的机器代码,由于不仅仅有一种机器代码,所以也不仅仅存在一种汇编语言。不同类型的CPU会接受不同类型的指令,当你学习汇编语言时,其实只是在学习CPU所支持的指令内容(称为指令集)。在学习汇编语言之前,我们应该首先选择要学习的汇编语言指令集。目前,有两个在传统计算机上非常常见。


i386

英特尔Inter 80386,简称为i386,是x86指令集的32位版本,几乎用于所有的32位桌面计算机、服务器和笔记本电脑之中。运行Windows、Linux或Mac的计算机,如果是32位的,那么CPU就很可能是基于i386。由于这是最常见的指令集,因此如果有人在说到“汇编”时,可能就是在指i386。
当Microsoft开始设计64位操作系统时,他们遇到了很大的麻烦,因为他们需要确保32位(i386)应用程序仍然可以正常工作。目前,大多数Windows恶意软件开发者只编写32位恶意软件,因为它可以同时在32和64位操作系统上运行。即使在64位Windows上,大多数恶意软件仍然是基于i386,因此这也是我推荐的指令集


x86_64

这是x86的64位版本,也是现代计算机中较为常见的指令集。由于x86系列中的体系结构都保持了强大的向后兼容性,因此所有x86_64 CPU都可以执行i386指令,而大多数64位指令与i386指令非常相似,因此首先学习i386汇编,然后再学习x86_64是有意义的,因为x86_64指令集本质上包括i386。
虽然64位Windows可以运行i386应用程序,但其他操作系统并不支持,因此所有本地代码都必须是x86_64。更高级的Windows恶意软件系列通常会在64位Windows上部署64位版本的代码,并且所有内核模式函数都是64位的,因此x86_64汇编语言对于了解i386也是非常有价值的。

 

结论

如果此前没有程序设计经验,要转型成为恶意软件逆向工程师并不是很容易,但学习编程的这一过程能有非常多的收获。如果我们掌握编程语言(特别是汇编和C语言等),那么就可以更快地学习其他语言,并能更好地掌握计算机的工作原理。编程是市场化程度最高的一个计算机相关技能,即使最后没有成为恶意软件分析师,我们也可以借助该语言进行编程,所以希望大家不要觉得为了开始分析恶意软件而学习一种程序设计语言是非常麻烦的行为。


推荐阅读
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
author-avatar
燕过无痕GY_274
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有