博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
控制流程完整性:给大家介绍一种“另类”的Javascript反分析技术
阅读量:6973 次
发布时间:2019-06-27

本文共 3090 字,大约阅读时间需要 10 分钟。

写在前面的话

理解恶意软件的真实代码对恶意软件分析人员来说是非常有优势的,因为这样才能够真正了解恶意软件所要做的事情。但不幸的是,我们并不总是能够得到“真实”的代码,有时恶意软件分析人员可能需要类似反汇编工具或调试器之类的东西才能“推测”出恶意软件的真实行为。不过,当恶意软件使用的是“解释型语言”开发的话,例如Java、JavaScript、VBS或.NET等等,我们就有很多种方法来查看它们真正的原始代码了。

不幸的是,攻击者同样知道这些分析技术,而且为了规避安全分析,他们还会采用很多混淆技术来干扰研究人员的分析过程。攻击者可以利用反分析技术来判断恶意代码是否在虚拟机环境中运行,或者让自己的代码只在特定环境中运行以避免调试以及逆向分析环境(包括反混淆),而今天我们要讨论了就是一种基于JavaScript的新型反逆向分析技术。

JavaScript正邪对垒

对于攻击者来说,JavaScript已经变成一种非常重要的攻击向量了。它一般用于攻击的Payload感染阶段,它的使用非常多样化,编码形式也不像其他语言那样受到各种限制,而且几乎所有的恶意JavaScript代码都会进行混淆处理。下图显示的是一个经过了混淆处理的JavaScriptPayload样本:

对于恶意软件分析人员来说,第一步就是要对这种代码进行反混淆处理。从最简单的复制粘贴,到更强大一点的“脚本替换”(涉及函数和变量的重命名),研究人员需要想方设法让代码更加清晰。但是在JavaScript中,我们可以根据函数名的调用情况来了解函数的运行机制。比如说函数arguments.callee.caller(),在这个函数的帮助下,我们可以创建一个堆栈跟踪,并将执行过的函数按照顺序存储在列表中。获取到函数名之后,我们就可以将它们当作密钥来对处理过的JavaScript代码进行动态“解密”了。这项技术可以让我们得到隐式的控制流完整性,因为如果一个函数被重命名或者函数运行顺序发生了变化,那么“结果哈希”肯定是不同的。如果哈希不同,生成的密钥也就不同,这样就可以进行解密并运行经过特殊加密的代码了。

为了让大家更清楚地了解我在说什么,请大家看看下面这段没有经过混淆处理的样本代码【】:

 

var _= require("underscore"); function keyCharAt(key, i) { return key.charCodeAt( Math.floor(i %key.length) ); } function xor_encrypt(key, data) { return _.map(data, function(c, i) { return c.charCodeAt(0) ^ keyCharAt(key,i); }); } function xor_decrypt(key, data) { return _.map(data, function(c, i) { return String.fromCharCode( c ^keyCharAt(key, i) ); }).join(""); } function cow001(){ eval(xor_decrypt(arguments.callee.name,[0,0,25,67,95,93,6,65,27,95,87,25,68,34,22,92,89,82,10,0,2,67,16,114,12,1,3,85,94,69,67,59,5,89,87,86,6,29,4,16,120,84,17,10,87,17,23,24])); } function pyth001(){ eval(xor_decrypt(arguments.callee.name,[19,22,3,88,0,1,25,89,66])); } function pippo(){ pyth001(); } pippo();

 

代码运行过程中会对“特定内容”进行计算(eval()函数),在代码的第21和25行,函数cow001()和pyth001()会计算XOR后的解密内容。xor_decrypt函数可以接收两个参数:decoding_key和需要解密的Payload。接下来,代码会使用arguments.callee.name()函数来将内部阶段的每一个函数名当作解密密钥来使用,如果函数名是“原始函数名”(攻击者用来解密Payload的函数名),那么加密后的代码就会正常运行,不会报错。换句话说,如果函数名经过了重命名,那么eval()函数将得到错误的结果,并导致攻击者转换代码运行路径(使用简单的try catch语句)。

在使用JavaScript代码实施攻击之前,攻击者需要开发恶意JavaScript代码并对其进行混淆处理,这样才能准备好所谓的“攻击路径”。代码混淆的过程中,攻击者需要使用额外的脚本(比如说下面这段代码-【】)并根据混淆后的函数名来加密Payload,然后用新加密的Payload替换之前的代码(加密后的Payload就是加密函数名所使用的密钥)。

"use strict";   var _= require("underscore"); function keyCharAt(key, i) { return key.charCodeAt( Math.floor(i %key.length) ); } function xor_encrypt(key, data) { return _.map(data, function(c, i) { return c.charCodeAt(0) ^ keyCharAt(key,i); }); } function xor_decrypt(key, data) { return _.map(data, function(c, i) { return String.fromCharCode( c ^ keyCharAt(key,i) ); }).join(""); } var final_payload = "console.log('Malicious Content Triggers Here !')"; var k_final = "cow001"; var encrypted_final = xor_encrypt(k_final,final_payload); var decrypted_final = xor_decrypt(k_final, encrypted_final); console.log(encrypted_final.toString()); console.log(decrypted_final); var _1_payload = "cow001();"; var k_1 = "pyth001"; var encrypted_1 = xor_encrypt(k_1,_1_payload); var decrypted_1 = xor_decrypt(k_1, encrypted_1); console.log(encrypted_1.toString()); console.log(decrypted_1);

 

总结

现在,攻击者就可以使用自己设计的控制流来编写JavaScript代码了。如果攻击者不停地迭代实现这种技术,他基本上就可以完全规避逆向工程分析技术了。

希望本文的内容可以给大家的安全研究带来灵感!

转载地址:http://lwrsl.baihongyu.com/

你可能感兴趣的文章
HA(heartbeat)主备模式实现lvs群集的高可用性
查看>>
mtr路由监控
查看>>
容器编排 Docker Compose
查看>>
KVM 使用virtio驱动Windows server 虚拟机
查看>>
我的Oracle 9i学习日志(15)-- 表的管理
查看>>
mysql5.7更改密码
查看>>
adb无线网络调试
查看>>
Nginx+Keepalived搭建高可用负载均衡集群
查看>>
防火墙示例-用简单规则集保护网络
查看>>
记一次开发过程中的思维转换
查看>>
8. Accordion模拟菜单,Accordion动态绑定数据,模拟菜单点击
查看>>
基于Spring源码分析AOP的实现机制
查看>>
Windows Server 2016 Hyper-v Nested Virtualization
查看>>
30种图像动画特效算法(C#多线程版)(中)
查看>>
在VMware虚拟机中安装Linux/ubuntu系统(图文)
查看>>
WCF开发常见问题:“There is already a listener on IP endpoint 0.0.0.0:4503”
查看>>
现在还有perlmonks网站这样的网站?!
查看>>
自动到ftp下载并替换文件内容
查看>>
生成服务器密码的shell脚本
查看>>
信号捕捉
查看>>