【问题标题】:Javascript calling Function() to create a functionJavascript 调用 Function() 来创建一个函数
【发布时间】:2015-02-16 17:17:44
【问题描述】:

谁能解释一下下面的代码?

Function(
Function(
'return \'\\141\\75\\160\\162\\157\\155\\160\\164\\50\\47\\105\\156\\164\\162\\145\\172\\40\\154\\145\\40\\155\\157\\164\\40\\144\\145\\40\\160\\141\\163\\163\\145\\47\\51\\73\\151\\146\\50\\141\\75\\75\\47\\164\\157\\164\\157\\61\\62\\63\\154\\157\\154\\47\\51\\173\\141\\154\\145\\162\\164\\50\\47\\142\\162\\141\\166\\157\\47\\51\\73\\175\\145\\154\\163\\145\\173\\141\\154\\145\\162\\164\\50\\47\\146\\141\\151\\154\\56\\56\\56\\47\\51\\73\\175\''
)  ()  
)()

这里很有趣:使用Function() 创建了一个实际函数。

但由于我无法查看本机代码,我很难理解正在创建的实际函数。这取自 root-me.org Javascript - 本机代码挑战。

【问题讨论】:

  • 在控制台中运行它会发生什么? Function( 'return \'\\141\\75\\160\\162\\157\\155\\160\\164\\50\\47\\105\\156\\164\\162\\145\\172\\40\\154\\145\\40\\155\\157\\164\\40\\144\\145\\40\\160\\141\\163\\163\\145\\47\\51\\73\\151\\146\\50\\141\\75\\75\\47\\164\\157\\164\\157\\61\\62\\63\\154\\157\\154\\47\\51\\173\\141\\154\\145\\162\\164\\50\\47\\142\\162\\141\\166\\157\\47\\51\\73\\175\\145\\154\\163\\145\\173\\141\\154\\145\\162\\164\\50\\47\\146\\141\\151\\154\\56\\56\\56\\47\\51\\73\\175\'' ) ()
  • a=prompt('Entrez le mot de passe');if(a=='toto123lol'){alert('bravo');}else{alert('fail...');}

标签: javascript function native deobfuscation


【解决方案1】:

它去混淆了:

a = prompt('Entrez le mot de passe');
if(a=='toto123lol'){
    alert('bravo');
} else{
    alert('fail...');
}

要验证,请在 Chrome 中打开开发者工具,打开控制台,然后粘贴:

Function(
    'return \'\\141\\75\\160\\162\\157\\155\\160\\164\\50\\47\\105\\156\\164\\162\\145\\172\\40\\154\\145\\40\\155\\157\\164\\40\\144\\145\\40\\160\\141\\163\\163\\145\\47\\51\\73\\151\\146\\50\\141\\75\\75\\47\\164\\157\\164\\157\\61\\62\\63\\154\\157\\154\\47\\51\\173\\141\\154\\145\\162\\164\\50\\47\\142\\162\\141\\166\\157\\47\\51\\73\\175\\145\\154\\163\\145\\173\\141\\154\\145\\162\\164\\50\\47\\146\\141\\151\\154\\56\\56\\56\\47\\51\\73\\175\''
)  ()  

本质上,这是“编码如何工作”的步骤。要“编码”字母“a”:

test = "a";
console.log(test.charCodeAt(0)); //97
console.log(parseInt('141', 8)); //97
console.log('\141'); //a

【讨论】:

  • 我们如何从 OP 到您的答案去混淆本机代码:)?
  • @Arkantos 在 chrome 控制台中输入它? '\141\75\160\162\157\155\160\164\50\47.......'引用
  • @null & dave .. 谢谢大家
  • 优秀。精彩的!但是我还没有得到的一件事是,这是什么类型的编码?为了消除混淆,Chrome 控制台实际上在做什么?我知道 Chrome 控制台执行 javascript ......但这里控制台实际上是在提供去混淆的代码!!!这怎么可能?
  • perlmonks.org/bare/?node_id=445179 给出了一个图表,其中显示了哪个代码转换为哪个字母。你基本上只有一系列转义字符 - 控制台取消转义字符。
【解决方案2】:

但由于我无法查看本机代码,我很难理解正在创建的实际函数。

脚本标签内有本机代码。它只是看起来不寻常,因为它引用了 ASCII 键码;确切地说是八角形(OCT)。这是一个链接

ASCII Key Codes

首先,我们有一个可执行的标签来启动。这是一个解释它的作用的链接。

HTML tags

在标签内部,我们有两个函数或函数构造函数。

如果你在控制台中输入 Function() ,你会得到

function anonymous() {}

有关更多信息,请查看此链接。

Funciton JS link

让我们先从嵌套函数开始。

Function(
  'return \'\\141\\75\\160\\162\\157\\155\\160\\164\\50\\47\\105\\156\\164\\162\\145\\172\\40\\154\\145\\40\\155\\157\\164\\40\\144\\145\\40\\160\\141\\163\\163\\145\\47\\51\\73\\151\\146\\50\\141\\75\\75\\47\\164\\157\\164\\157\\61\\62\\63\\154\\157\\154\\47\\51\\173\\141\\154\\145\\162\\164\\50\\47\\142\\162\\141\\166\\157\\47\\51\\73\\175\\145\\154\\163\\145\\173\\141\\154\\145\\162\\164\\50\\47\\146\\141\\151\\154\\56\\56\\56\\47\\51\\73\\175\'')()

通过使用 JS Function 构造函数,我们可以将参数传递给我们的新函数以及函数体。

新函数([arg1[, arg2[, ...argN]],] functionBody)

在嵌套函数中,我们只是创建一个匿名函数,并以这样的字符串形式传递给它一个函数体

'return \'\\141\\75\\160\\162\\157\\155\\160\\164\\50\\47\\105\\156\\164\\162\\145\\172\\40\\154\\145\\40\\155\\157\\164\\40\\144\\145\\40\\160\\141\\163\\163\\145\\47\\51\\73\\151\\146\\50\\141\\75\\75\\47\\164\\157\\164\\157\\61\\62\\63\\154\\157\\154\\47\\51\\173\\141\\154\\145\\162\\164\\50\\47\\142\\162\\141\\166\\157\\47\\51\\73\\175\\145\\154\\163\\145\\173\\141\\154\\145\\162\\164\\50\\47\\146\\141\\151\\154\\56\\56\\56\\47\\51\\73\\175\''

当函数运行时,第一个字符串 ''(引号)被删除并运行此语句

return \'\\141\\75...'

return,当然是执行并退出函数,当这个函数运行时,我们得到另一个字符串值形式的函数体。

"a=prompt('Entrez le mot de passe');if(a=='toto123lol'){alert('bravo');}else{alert('fail...');}"

在return语句之后,实际字符串之前的前导'\'只是为了转义后面的引号,因此编译器不会将它误认为是re​​turn语句之前引号的第二个右引号。我们可以去掉它,以及最后一个数字之后的第二个,而是像这样编写函数体

Function(
'return "\\141\\75\\160\\162\\157\\155\\160\\164\\50\\47\\105\\156\\164\\162\\145\\172\\40\\154\\145\\40\\155\\157\\164\\40\\144\\145\\40\\160\\141\\163\\163\\145\\47\\51\\73\\151\\146\\50\\141\\75\\75\\47\\164\\157\\164\\157\\61\\62\\63\\154\\157\\154\\47\\51\\173\\141\\154\\145\\162\\164\\50\\47\\142\\162\\141\\166\\157\\47\\51\\73\\175\\145\\154\\163\\145\\173\\141\\154\\145\\162\\164\\50\\47\\146\\141\\151\\154\\56\\56\\56\\47\\51\\73\\175"')()

如果您在控制台中运行此代码,您会得到相同的结果,试试吧!

如果你这样做你会发现所有这些数字都编译成实际的字母和数字,实际上它编译成ASCII字符代码。这是因为每个数字都使用了“\”。为了减少混淆,让我们把这个“\\”改为这个“\”

Function(
'return "\141\75\160\162\157\155\160\164\50\47\105\156\164\162\145\172\40\154\145\40\155\157\164\40\144\145\40\160\141\163\163\145\47\51\73\151\146\50\141\75\75\47\164\157\164\157\61\62\63\154\157\154\47\51\173\141\154\145\162\164\50\47\142\162\141\166\157\47\51\73\175\145\154\163\145\173\141\154\145\162\164\50\47\146\141\151\154\56\56\56\47\51\73\175"')()

如你所见,这仍然会运行,我们得到

"a=prompt('Entrez le mot de passe');if(a=='toto123lol'){alert('bravo');}else{alert('fail...');}"

因此,嵌套函数将函数体作为字符串返回,然后在外部 Function 构造函数中以与嵌套函数触发相同的方式执行。这是相同的示例,为了更清楚起见,删除了一些内容

 Function(
Function('return "\141\75\160\162\157\155\160\164\50\47\105\156\164\162\145\172\40\154\145\40\155\157\164\40\144\145\40\160\141\163\163\145\47\51\73\151\146\50\141\75\75\47\164\157\164\157\61\62\63\154\157\154\47\51\173\141\154\145\162\164\50\47\142\162\141\166\157\47\51\73\175\145\154\163\145\173\141\154\145\162\164\50\47\146\141\151\154\56\56\56\47\51\73\175"')())()

注意:您可能需要打开一个新窗口,然后将其粘贴到控制台并点击进入。

为了更清楚,我们可以像这样将初始返回值复制并粘贴到外部函数中

Function("a=prompt('Entrez le mot de passe');if(a=='toto123lol'){alert('bravo');}else{alert('fail...');}")()

这也可以。

嵌套函数的作用

第一部分打开一个浏览器提示窗口并将其未来值附加到变量“a”。试试这个

Function("a=prompt('Enter Password');console.log(a);")()

当您按下回车键时,您的值将显示在控制台中。该函数的第二部分通过将其与字符串“toto123lol”进行比较来分析此返回值。

当输入的值正好是“toto123lol”时,将出现一个新的警报窗口,显示“bravo”。

如果输入的值不完全是“toto123lol”,则会出现一个新的警报窗口,显示“失败...”

如您所见,您的问题的初始函数不仅包含运行工作代码所需的所有信息,还包含您需要弄清楚它在做什么的所有本机代码。

结帐后您提到的网站

Root-me.org

也许测试试图表明的是,看似无害的代码,实际上可以是任何可以在 HTML 标记中执行的代码。或者也许有很多方法可以影响行为?

我希望这能回答你的问题。

更新:如果您想知道 '\\' 或 '\' 之间有什么区别,我在这里问过 - why double or single escapes

【讨论】:

  • 精彩的解释。我喜欢它。非常感谢。
  • 你会说它回答了你的问题吗?
  • 当然。它不仅仅回答了我的问题。
猜你喜欢
  • 1970-01-01
  • 2019-09-17
  • 2020-09-12
  • 1970-01-01
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多