0%

记一次JS木马分析

0x00 前言

  随着 javascript 这类脚本语言的快速发展,它能展现的内容越来越多样,所运用的功能变得越来越强大。当运用在 web 开发上时,增加了更多的动态功能和效果,极大的改善了用户体验。但是,随着 js 的功能强大的同时,也带来了更多的安全隐患。由于 js 的混淆效果多样,常见的有 YUI CompressorGoogle Closure CompilerUglifyJS。更有 jsfuck 这种比较奇葩的加密方式。使得让软件自动的识别特征码,查杀 js 恶意代码变的非常困难。对 JavaScript 恶意代码的检测已成为 Web 信息安全领域一个亟待解决的问题。
  因为近期偶然发现一个 js 木马文件,所以想探寻一下 js 木马的混淆方法和这个木马起的作用。

0x01 解混淆

  首先打开 js 文件,看到的就是一个很明显的 var PAa = ""; 定义了一个变量,然后是大段的代码:img

  这大段的代码都是以函数执行的方式放在数组里的,我们在仔细看一下数组第一个元素:

1
(function f000(){return "Sq";})()

  发现,这数组的第一个元素其实就是字符串 Sq,但是是以函数执行后返回的结果显示的,其他数组元素也是这样的。非常的巧妙,等于加了一层壳,防止被跟踪查杀。

  接着我们看到最后:

img

  发现,又定义了一个字典,然后对中间数组元素进行对照替换处理,得到真正的字符,而且这个字符也不是真正的字符,而是以 16 进制的形式表示的。然后拼接到开始定义的 PAa 这个变量中,最后 eval 执行这段代码,那毫无疑问,最后 PAa 这个变量存储的东西就是真正的代码了。

  在这里,就可以用 document.write() 来直接输出 PAa 这个变量的内容,也就是明文代码了。

  这第一层的混淆,相当于对代码进行”加壳”处理,通过函数,数组,字典、16进制等方式进行层层替换,最后才得出代码。

0x02 代码分析

  对于输出的代码,在进行美化和调整一下格式,终于达到人能理解的程度了。但是代码还是有第二层的混淆,不过这层的混淆就是些字符串的拼接与组合,已达到骗过机器追踪关键字的目的,从而达到免杀的效果。但对人来说,还是可以判断分析出来的:

img

  下面就来分析一下,这个木马到底做了哪些操作。

判断cmd.exe的路径

  代码开始就是执行了一个函数:

img

  可以看到,在这里也是对字符进行拼接,最后凑出来的关键字。 这个函数的大概意思就是通过创建 WScript.Shell 对象来查看环境变量中的 COMSPEC 值,这个值是返回命令行解释器可执行程序的准确路径,就是 cmd.exe 的路径。然后与系统目录下的 system32\cmd.exe 进行比较。判断 cmd.exe 的路径。

扩展与查看环境变量

img

  这里,也是经过一连串的字符的替换与拼接,大致还原出原来的样子

1
2
3
Za3 + OHb + PVg7 + Tp7 + QRn4  表示  CreateObject
OEl7 + Pa + Eu 表示 WScript.Shell
Js9 + Vh + PVx + COb3 表示 %TEMP%/

这里的意思就是通过扩充环境字串 %TEMP%/,并在该目录下,创建出一串无意义名字的后缀为 dll 的字符串,即 xx.dll 赋值于 GLq 这个变量中,为后面的写文件做铺垫,继续看下去:

img

  接下来,就是查看环境变量中的 PROCESSOR_ARCHITECTUREiD,来判断系统是 64,还是 32 位,最后选择相对应的 rundll32.exe,用于后面执行恶意动态链接库的函数。其中

1
2
3
Cc5 + TXr9 + HUf + YEn7 + Ci5 + SDb9 表示 PROCESSOR_ARCHITECTURE
Vg 表示 "%SystemRoot%\\system32\\rundll32.exe" + ""
ZPt 表示 "%SystemRoot%\\SysWOW64\\rundll32.exe" + ""

下载恶意文件

img

  创建 http 请求对象,其中

1
Zm6 表示 [MSXML2.XMLHTTP,WinHttp.WinHttpRequest.5.1]

  这 2 个都是能实现 HTTP 请求响应的组件,这里是尝试创建这其中任意一个组件对象。

  紧接着,就是判断在 %TEMP%/ 是否已有 xx.dll ,即是否已经被攻击,如果没有的话,就继续执行下去,也就是访问恶意网站,下载要在计算机上执行的恶意文件,并放在 %TEMP%/ 目录下的临时文件中,当然文本也是加密处理的:

img

解密并校验恶意文件

  存放临时文件后,因为文件内容也是经过混淆处理的,所以要重新从文件中取出内容进行处理与校验。我们来看下关键函数 IGi2 函数。

img

img

  可以看到,主要的方法就是通过字符的 unicode 编码,针对恶意文本的一些特定字符的 unicode 编码进行替换。但是还没完,还有一个步骤:

img

  对所有的数字进行异或运算。在最后,还要通过一系列特定的计算,与后四位的标志位进行比较,进行文本内容的校验,来判断该文本是否被修改,或者是内容不全。

  之后,还加上了一层保险,就是判断整个恶意文件的字符数,保证是在一定的区间内。

img

执行恶意文件代码

  最后,在判断过字符个数,没问题之后,就直接写入 dll 文件,准备执行了,如上图。

  但是我们知道,要写入文本的字符串现在还都是 unicode 编码的,所以需要还原成真正的字符串才行,这里是通过 St 函数。而这个 St 函数和上面的 IGi2 函数的作用是一样的,只不过数组是反的,这也是我疑惑的地方,它的作用就是把之前替换掉的数字替换回来,然后进行全部的 unicode 解码,变成字符串。至于为什么要把替换掉的字符换回来?由于恶意网站已无法访问,所以拿不到下载的恶意文本,是注释?还是另一层混淆?这点就无法判断了,也是非常的遗憾。

img

  在写入文件之后,就通过命令 Rundll32.exe DLLname,Functionname [Arguments] 的形式运行 dll 文件里的函数了。

0x03 免杀方式总结

  js 的混淆能力真的很强大,简单总结一下上面木马的混淆免杀方式,第一层混淆就是通过了函数返回值,数组,字典、16 进制表示字符等方式进行层层替换,得到真正的代码。第二层混淆就是在代码执行过程中对关键字进行字符串的拼接,躲避对关键字的查杀,简单而有效。第三层混淆就是通过 unicode 编码,利用特定数值替换,然后通过异或等数学方法得到代码明文,对下载的恶意文件中的字符进行解密操作。整个过程体现了对普通杀毒软件的极强的欺骗性和防御性。

0x04 后记

  由于找不到下载到本地的恶意代码文本,特意到网上搜了N个该 JS 的特征代码。最后终于发现了在国外的一个网站上发现了对类似 JS 执行的内存和行为分析,虽然还是没有下载的恶意代码文本,但是已经能够大致确定该 JS下载的恶意代码的作用了。地址

https://www.hybrid-analysis.com/sample/d8f738474e7c4251132059375b3716fdf21e87823f5890a918dfb70a4d164066?environmentId=100

  从上面找到了 JS 代码,发现和我们分析的样本的第一层混淆方式略有不同:img

  但是同样经过了最开始的还原之后,发现核心代码和分析样本代码基本一致:

img

  最后来看下,该 JS 下载的恶意代码究竟干了什么:

img

  大概意思就是该恶意文件会从本地浏览器窃取信息,如平时让浏览器记住的账号密码,然后查找电脑账户名称,计算机名,计算机组名ID等。

  也可以从行为分析的角度再次验证 JS 执行过程,因为上面是从代码角度分析的,难免有点点抽象,从 JS 实际操作过程分析,会更加的直观。我们可以看到:

img
img

  发现与分析基本一致。