控制流程完整性:给大家介绍一种“另类”的Javascript反分析技术
写在前面的话
理解恶意软件的真实代码对恶意软件分析人员来说是非常有优势的,因为这样才能够真正了解恶意软件所要做的事情。但不幸的是,我们并不总是能够得到“真实”的代码,有时恶意软件分析人员可能需要类似反汇编工具或调试器之类的东西才能“推测”出恶意软件的真实行为。不过,当恶意软件使用的是“解释型语言”开发的话,例如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代码了。如果攻击者不停地迭代实现这种技术,他基本上就可以完全规避逆向工程分析技术了。
希望本文的内容可以给大家的安全研究带来灵感!
控制流程完整性:给大家介绍一种“另类”的Javascript反分析技术的更多相关文章
- Linux下几种另类创建文件之方法
以前我们用编辑器例如vi来新建文件,下面介绍几种另类生成文件的方法,多用在备份和测试上. 创建文件的方法: 1.echo 命令 #echo "set bell" >& ...
- MySQL聚合函数、控制流程函数(含navicat软件的介绍)
MySQL聚合函数.控制流程函数(含navicat软件的介绍) 一.navicat的引入:(第三方可视化的客户端,方便MySQL数据库的管理和维护) NavicatTM是一套快速.可靠并价格相宜的数据 ...
- MySQL数据库学习笔记(四)----MySQL聚合函数、控制流程函数(含navicat软件的介绍)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- 【JAVA零基础入门系列】Day8 Java的控制流程
什么是控制流程?简单来说就是控制程序运行逻辑的,因为程序一般而言不会直接一步运行到底,而是需要加上一些判断,一些循环等等.举个栗子,就好比你准备出门买个苹果,把这个过程当成程序的话,可能需要先判断一下 ...
- C#深入浅出之操作符和控制流程
操作符 操作符简单举例就是生活中的+-*/等等运算符号,下面会详细讨论运算符内容. 一元正负操作符 有时候需要改变数值的正负号.一元操作符(-)可以使得数字的正负号改变. 例如:int a = -11 ...
- JavaScript---js语法,数据类型及方法, 数组及方法,JSON对象及方法,日期Date及方法,正则及方法,数据类型转换,运算符, 控制流程(三元运算),函数(匿名函数,自调用函数)
day46 一丶javascript介绍 JavaScript的基础分为三个 1.ECMAScript:JavaScript的语法标准.包括变量,表达式,运算符,函数,if语句,for语句 ...
- 《Android游戏开发详解》一1.7 控制流程第1部分——if和else语句
本节书摘来异步社区<Android游戏开发详解>一书中的第1章,第1.7节,译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区"异步社区"公众号查看. 1.7 ...
- C# 8.0和.NET Core 3.0高级编程 分享笔记三:控制流程和转换类型
控制流程和转换类型 本章的内容主要包括编写代码.对变量执行简单的操作.做出决策.重复执行语句块.将变量或表达式值从一种类型转换为另一种类型.处理异常以及在数值变量中检查溢出. 本章涵盖以下主题: 操作 ...
- 干货:结合Scikit-learn介绍几种常用的特征选择方法
原文 http://dataunion.org/14072.html 主题 特征选择 scikit-learn 作者: Edwin Jarvis 特征选择(排序)对于数据科学家.机器学习从业者来说非 ...
随机推荐
- 【BestCoder 1st Anniversary】
AB题都是签到题.... C 题意: 有一串数列,An=3*n*(n-1)+1 然后要从A数列中选取尽量少个数(可重复),使得Sum(An)=m 题解: 贪心地想,能拿大就拿大很明显就是错的...[哪 ...
- [bzoj4712] 洪水 [树链剖分+线段树+dp]
题面 传送门 思路 DP方程 首先,这题如果没有修改操作就是sb题,dp方程如下 $dp[u]=max(v[u],max(dp[v]))$,其中$v$是$u$的儿子 我们令$g[u]=max(dp[v ...
- 【BZOJ 5000 OI树】
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 107 Solved: 64[Submit][Status][Discuss] Description ...
- git bash 如何进入某个盘的特定文件夹
下面是用gitbash进入E:\the fifth version of ecard\epayment这个文件夹下 命令如下图所示:
- Topcoder SRM 601 div1题解
日常TC计划- Easy(250pts): 题目大意:有n个篮子,每个篮子有若干个苹果和橘子,先任取一个正整数x,然后从每个篮子中选出x个水果,把nx个水果放在一起,输出一共有多少种不同的组成方案.其 ...
- Kubernetes控制节点安装配置
#环境安装Centos 7 Linux release 7.3.1611网络: 互通配置主机名设置各个服务器的主机名hosts#查找kubernetes支持的docker版本Kubernetes v1 ...
- javascript与mongodb的日期时区问题
默认情况下,js的日期生成是当地时区,但默认显示是按照GMT显示的: > var c = new Date('2017-10-31 06:00:00'); > c 2017-10-30T2 ...
- Oracle sql例子
create database oracle1 )) select * from class ,'一班') ,'二班') ,'三班') --创建学生表 ),cid int ,constraint FK ...
- poj 1265&&poj 2954(Pick定理)
Area Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5811 Accepted: 2589 Description ...
- PHP源码加密- php-beast
php-beast 详细介绍 使用案例: http://www.beastcoder.com/ PHP Beast是一个源码加密模块,使用这个模块可以把PHP源码加密并在此模块下运行. 为什么要用PH ...