Javascript eval - 混淆?

时间:2015-01-10 16:20:17

标签: javascript binary obfuscation

我遇到了一些评估代码:

eval('[+!+[]+!+[]+!+[]+!+[]+!+[]]');

此代码等于整数5。

这种类型的东西叫什么?我试过在网上搜索,但我似乎无法弄清楚这是什么。我发现这非常有趣,并想知道在哪里/如何学习如何打印不同的东西,而不仅仅是整数5.字母,符号等等因为我不能在该代码中指出一个模式我有0成功从中获取并添加它以产生不同的结果。

这是某种混淆吗?

4 个答案:

答案 0 :(得分:8)

这种类型的混淆,除了eval()之外,被称为非字母数字混淆。 要完全是非字母数字,eval必须由Array构造函数原型函数和下标符号执行:

[]["sort"]["constructor"]("string to be evaled");

然后将这些字符串转换为非字母数字形式。

AFAIK,它是由Yosuke Hosogawa在2009年左右首次提出的。 如果您想看到它的实际效果,请参阅此工具:http://www.jsfuck.com/

它不被认为是一种好的混淆类型,因为它很容易反向回原始源代码,甚至不必运行代码(静态)。另外,它极大地增加了文件大小。

但它是一种有趣的混淆形式,它探讨了JavaScript类型的强制。要了解更多信息,我推荐此演示文稿,幻灯片33: http://www.slideshare.net/auditmark/owasp-eu-tour-2013-lisbon-pedro-fortuna-protecting-java-script-source-code-using-obfuscation

答案 1 :(得分:4)

这被称为非字母数字JavaScript ,并且由于JavaScript类型强制功能而成为可能。实际上有一些方法可以调用eval / Function而不必使用字母字符:

[]["filter"]["constructor"]('[+!+[]+!+[]+!+[]+!+[]+!+[]]')()

更换字符串" filter"和"构造函数"通过非字母数字表示,您可以获得完整的非字母数字JavaScript。

如果你想玩这个,有一个网站,你可以这样做:http://www.jsfuck.com/

请查看此https://github.com/aemkei/jsfuck/blob/master/jsfuck.js以获取更多示例,如下所示:

'a':   '(false+"")[1]',
'b':   '(Function("return{}")()+"")[2]',
'c':   '([]["filter"]+"")[3]',
...

答案 2 :(得分:2)

要将值设为5,表达式应该是这样的

+[!+[] + !+[] + !+[] + !+[] + !+[]]

让我们首先分析共同的要素。 !+[]

  1. JavaScript中的空数组文字被视为Falsy。

  2. +运算符应用于数组文字,会尝试将其转换为数字,因为它为空,JavaScript会将其评估为0.

  3. !运算符将0转换为true

  4. 所以,

    console.log(!+[]);
    

    会打印true。现在,表达式可以像这样减少

    +[true + true + true + true + true]
    

    由于算术表达式中true被视为1,因此实际表达式变为

    +[ 5 ]
    

    +运算符尝试将数组([ 5 ])转换为数字,结果为5.这就是您获得5的原因。

答案 3 :(得分:1)

我不知道用于描述此类代码的任何术语,除了"滥用eval()"。

  

我觉得这非常有趣,想知道一个人在哪里/怎么样   学习如何打印不同的东西,而不仅仅是整数5。   字母,符号等因为我无法在其中指出一个模式   代码我已经成功取得了成功并添加了它以使其与众不同   结果

这部分我至少可以部分回答。你粘贴的eval()在很大程度上依赖于Javascript的奇怪类型强制规则。网上有一个 lot 页面,描述了强制规则的各种奇怪后果,您可以轻松搜索。但我无法找到关于类型强制的任何参考,其具体目标是让人惊讶地发现"从eval()之类的东西输出,除非你算this video by Destroy All Software(Javascript部分从1:20开始)。他们中的大多数都可以理解为如何避免代码中的奇怪错误。为了您的目的,我相信我所知道的最有用的东西是:

  • ! operator会将任何东西转换为布尔值。
  • 一元+运算符会将任何内容转换为数字。
  • 在添加或连接它们之前,binary +运算符会将其参数强制转换为数字或字符串。通常情况下,如果一个或另一个参数已经是一个字符串,它将仅使用字符串,但也有例外。
  • 无论输入如何,按位运算符都会输出整数。
  • 转换为数字很复杂。布尔值将转到0或1.字符串将尝试使用parseInt(),或者如果失败则生成NaN。我忘了其余的。
  • 将对象转换为字符串或数字将调用其" toString"或者" toValue"方法分别存在。

你明白了。 thefourtheye的回答将详细介绍这些规则如何应用于您给出的示例。我甚至不打算总结在涉及日期,函数和正则表达式时会发生什么。

  

这是某种混淆吗?

通常情况下,你只是在缩小时免费进行模糊处理,所以我不知道为什么有人会在真实的生产代码中写出这一点(假设你找到它的地方)。