导语:以前,我曾介绍过高级逆向工程(FLARE)脚本系列,这篇文章我会继续接着介绍idawasm,它是一个IDA Pro插件,为WebAssembly模块提供加载器和处理器模块。
前言
以前,我曾介绍过高级逆向工程(FLARE)脚本系列,这篇文章我会继续接着介绍idawasm,它是一个IDA Pro插件,为WebAssembly模块提供加载器和处理器模块。idawasm适用于IDA Pro支持的所有操作系统,可以从idawasm GitHub中下载得到。
参加了今年的FireEye FLARE-On挑战比赛的朋友们,会在比赛中发现一种新的文件格式:WebAssembly (“wasm”)模块。如果要继续挑战,就必须对基于WebAssembly堆栈的虚拟机的二进制文件中包含的密钥检查逻辑进行逆向工程。但首先,你必须对WebAssembly(Wasm)有所了解。
WebAssembly(Wasm)及其相关的工具
WebAssembly被设计为一个可移植的目标,用于编译C/c++ /Rust等高级语言,支持在web上部署客户机和服务器应用程序。
WebAssembly在2018年第一季度算得上是真正取得了成功,这是自Web诞生以来首个Java原生替代方案。现在,Go语言也宣布加入WebAssembly!
在如今的浏览器中,JavaScript是在虚拟机(VM)中执行的,该虚拟机能够最大化的优化代码并压榨每一丝的性能,这也使得JavaScript称为速度最快的动态语言之一。但尽管如此,它还是无法与原生的C/C++代码相媲美。所以,WebAssembly就出现了。
编译为wasm的Golang应用程序将与Java应用程序具有互操作性。这意味着WebAssembly憧憬的WebAssembly架构将在很大程度上从Java内部访问和嵌入。
此外,在WebAssembly体系结构上运行Golang的基础包含许多技术规范。其中有:内存管理,32/64位架构功能,线程,垃圾回收以及与Java互操作的细节。
WebAssembly同样在JavaScript虚拟机中运行,但是它表现得更好。两者可以自由交互、互不排斥,这样你就同时拥有了两者最大的优势——JavaScript巨大的生态系统和有好的语法,WebAssembly接近原生的表现性能。
WebAssembly堆栈被设计为以大小和加载时间有效的二进制格式进行编码。WebAssembly旨在通过利用各种平台上可用的通用硬件功能,让计算机速度的运行加快。
虽然WebAssembly是一个相当新的标准,但已经存在一些利用WebAssembly进行分析的工具。WebAssembly二进制工具包提供了命令行工具wasm2wat,负责将WebAssembly二进制文件转换为可读的S表达式文本文件(.wat),以及一个名为wasm2c的基本反编译器。
基于Web的WebAssembly Studio IDE发布了一个将.wasm文件解压缩为有趣格式的功能,包括由Firefox SpiderMonkey JIT引擎生成的x86-64转换为有趣的格式。Radare2可以反汇编指令,但它目前还不能重建控制流程图。
但是,由于这些工具我们很少用到,所以不是很熟悉。如果我们可以在IDA Pro中分析.wasm文件,那就像使用.exe和.so文件一样,更好的为利用WebAssembly来进行攻击的恶意软件的防护做好准备。
idawasm IDA Pro插件是一个加载器和处理器模块,这使得分析师能够使用熟悉的界面查看WebAssembly模块,让我们来看看它的一些主要功能。
Idawasm的功能介绍
安装了idawasm之后,就可以将.wasm文件加载到IDA Pro中。“加载新文件”对话框将指示加载程序模块何时识别WebAssembly模块。目前,该插件支持WebAssembly的MVP(版本1)版本,如下图所示。
IDA Pro加载WebAssembly模块
然后处理器模块开始工作并重新构造控制流程,从而启用IDA的图形模式。这样可以轻松识别高级控件构造,例如if语句和while循环。我发现,在FLARE团队利用高级逆向工程(FLARE)脚本时,当为WebAssembly编译C程序时,生成的控制流程图将镜像x86编译目标。虽然具体指令不同,但我们在x86上学到的技术和方法也适用于wasm。注意,在下图中识别if语句对是多么容易。
WebAssembly指令的控制流程图
除了重新构造控制流程之外,处理器模块还使用嵌入.wasm文件的元数据来解析和呈现函数名称和类型。它还提取对全局变量的交叉引用,使分析师能够“列出交叉引用”并找到操纵有趣值的代码。当然,idawasm解析的所有元素都可以进行交互式重命名和注释。因此,分析师可以在.idb文件中记录有关WebAssembly恶意软件样本的信息,并与其他分析人员共享。
例如,下图显示了分析师如何重命名局部变量并添加注释,以及如何添加注释来解释在函数序言中如何操作函数框架。
IDA Pro中带注释的WebAssembly
当idawasm处理器检测到WebAssembly模块是由LLVM编译的,则它可以实现增强分析。 LLVM使用WebAssembly规范提供的原语在全局内存中实现一个用于可变函数局部变量的函数frame堆栈。在函数序言中,前几条指令会在此全局堆栈上分配frame,并在返回之前清除它。idawasm自动查找对全局frame堆栈指针的引用,并重新构造每个函数的frame布局。处理器可以使用这些信息,更新IDA的堆栈frame结构,并将立即寻址标记为这些结构的偏移量。这意味着更多的指令操作数实际上是可以注释和重命名的符号,如下图所示。
功能frame的自动重建
按照惯例,WebAssembly编译器会发出指令,以单一静态赋值(SSA)形式引用变量。这对浏览器引擎来说是一个好消息,因为已经以SSA形式存在的代码更容易导入到优化器和JIT引擎等分析系统中。这也是使用SSA形式时,为什么连最简单的函数也有几十个或几百个局部变量。
但对于分析师来说,SSA形式的分析就是繁琐的,因为他们必须跟踪许多单独的局部变量的操作。为此,idawasm包含一个WebAssembly模拟器,可以在符号出现时就开始跟踪指令。这使分析师能够将一系列简单的相关指令整合成一个复杂表达式。
要使用idawasm,分析师就要在一个基本块中选择一个指令区域并运行wasm_emu.py脚本。该脚本会模拟指令,简化其效果,并将效果呈现给全局变量、局部变量、内存和堆栈。下图显示了函数的序言如何简化为单个全局变量更新:
wasm_emu.py显示了功能 frame分配的效果
当同时出现很多运算时,wasm_emu.py通常会简化为一个有意义的表达式。例如,下图显示了32个指令是如何在两个输入字节中归结为单个XOR。
wasm_emu.py简化了复杂指令
总结
idawasm是一个IDA Pro插件,可通过加载器和处理器支持WebAssembly模块。这使得分析人员可以使用熟悉的界面来逆向.wasm文件并与他人分享他们的工作。wasm_emu.py脚本也有助于理解WebAssembly指令的超长流程的分析效果。
现在idawasm IDA Pro插件来处理WebAssembly的文件格式和架构,就容易多了。