Tru*_*gDQ 65 javascript obfuscation deobfuscation
这是一个警告"Hello world"的小javascript:
????=/??´??~???//*´??*/['_'];o=(???)=_=3;c=(???)=(???)-(???);(???)=(???)=(o^_^o)/(o^_^o);(???)={???:'_',????:((????==3)+'_')[???],????:(????+'_')[o^_^o-(???)],????:((???==3)+'_')[???]};(???)[???]=((????==3)+'_')[c^_^o];(???)['c']=((???)+'_')[(???)+(???)-(???)];(???)['o']=((???)+'_')[???];(?o?)=(???)['c']+(???)['o']+(????+'_')[???]+((????==3)+'_')[???]+((???)+'_')[(???)+(???)]+((???==3)+'_')[???]+((???==3)+'_')[(???)-(???)]+(???)['c']+((???)+'_')[(???)+(???)]+(???)['o']+((???==3)+'_')[???];(???)['_']=(o^_^o)[?o?][?o?];(???)=((???==3)+'_')[???]+(???).????+((???)+'_')[(???)+(???)]+((???==3)+'_')[o^_^o-???]+((???==3)+'_')[???]+(????+'_')[???];(???)+=(???);(???)[???]='\\';(???).????=(???+???)[o^_^o-(???)];(o???o)=(????+'_')[c^_^o];(???)[?o?]='\"';(???)['_']((???)['_'](???+(???)[?o?]+(???)[???]+(???)+(???)+(???)+(???)[???]+(???)+((???)+(???))+(???)+(???)[???]+(???)+(???)+((???)+(???))+(???)[???]+(???)+((o^_^o)+(o^_^o))+((o^_^o)-(???))+(???)[???]+(???)+((o^_^o)+(o^_^o))+(???)+(???)[???]+((???)+(???))+(c^_^o)+(???)[???]+(???)+((o^_^o)-(???))+(???)[???]+(???)+(???)+(c^_^o)+(???)[???]+(???)+(???)+((???)+(???))+(???)[???]+(???)+((???)+(???))+(???)+(???)[???]+(???)+((???)+(???))+(???)+(???)[???]+(???)+((???)+(???))+((???)+(o^_^o))+(???)[???]+(???)+(c^_^o)+(???)[???]+(???)+((o^_^o)-(???))+((???)+(o^_^o))+(???)[???]+(???)+((???)+(???))+((???)+(o^_^o))+(???)[???]+(???)+((o^_^o)+(o^_^o))+((o^_^o)-(???))+(???)[???]+(???)+((???)+(???))+(???)+(???)[???]+(???)+(???)+(???)+(???)[???]+(???)+((o^_^o)-(???))+(???)[???]+((???)+(???))+(???)+(???)[?o?])(???))('_');
Run Code Online (Sandbox Code Playgroud)
好看的版本:
???? = /??´??~???//*´??*/['_'];
o = (???) = _ = 3;
c = (???) = (???) - (???);
(???) = (???) = (o^_^o)/(o^_^o);
(???) = {
???: '_',
????: ((????==3)+'_')[???],
????: (????+'_')[o^_^o-(???)],
????: ((???==3)+'_')[???]
};
(???)[???] = ((????==3)+'_')[c^_^o];
(???)['c'] = ((???)+'_')[(???)+(???)-(???)];
(???)['o'] = ((???)+'_')[???];
(?o?)=(???)['c'] + (???)['o'] + (???? + '_')[???] + ((????==3) + '_')[???] + ((???) + '_')[(???) + (???)] + ((???==3) + '_')[???] + ((???==3) + '_')[(???) - (???)] + (???)['c'] + ((???) + '_')[(???) + (???)] + (???)['o'] + ((???==3) + '_')[???];
(???)['_'] = (o^_^o)[?o?][?o?];
(???) = ((???==3) + '_')[???] + (???).???? + ((???) + '_')[(???) + (???)] + ((???==3) + '_')[o^_^o-???] + ((???==3) + '_')[???] + (????+'_')[???];
(???) += (???);
(???)[???] = '\\';
(???).???? = (???+???)[o^_^o-(???)];
(o???o) = (????+'_')[c^_^o];
(???)[?o?] = '\"';
(???)['_']((???)['_'](???+(???)[?o?]+(???)[???]+(???)+(???)+(???)+(???)[???]+(???)+((???)+(???))+(???)+(???)[???]+(???)+(???)+((???)+(???))+(???)[???]+(???)+((o^_^o)+(o^_^o))+((o^_^o)-(???))+(???)[???]+(???)+((o^_^o)+(o^_^o))+(???)+(???)[???]+((???)+(???))+(c^_^o)+(???)[???]+(???)+((o^_^o)-(???))+(???)[???]+(???)+(???)+(c^_^o)+(???)[???]+(???)+(???)+((???)+(???))+(???)[???]+(???)+((???)+(???))+(???)+(???)[???]+(???)+((???)+(???))+(???)+(???)[???]+(???)+((???)+(???))+((???)+(o^_^o))+(???)[???]+(???)+(c^_^o)+(???)[???]+(???)+((o^_^o)-(???))+((???)+(o^_^o))+(???)[???]+(???)+((???)+(???))+((???)+(o^_^o))+(???)[???]+(???)+((o^_^o)+(o^_^o))+((o^_^o)-(???))+(???)[???]+(???)+((???)+(???))+(???)+(???)[???]+(???)+(???)+(???)+(???)[???]+(???)+((o^_^o)-(???))+(???)[???]+((???)+(???))+(???)+(???)[?o?])(???))('_');
Run Code Online (Sandbox Code Playgroud)
取自这里:https://codegolf.stackexchange.com/a/24041/17049
任何人都知道它是如何工作的?我甚至没有看到该alert代码.
Gum*_*mbo 110
在仔细研究代码之前,您必须知道,因为JavaScript 1.5 标识符不仅包含ASCII字符,还包含Unicode字符.
在这种情况下,许多这些有趣的序列只是标识符.通过更简单的标识符交换这些标识符并删除不必要的注释和括号后,代码如下所示:
a = /??´??~???/['_'];
o = b = _ = 3;
c = d = b-b;
e = d = o^_^o/o^_^o;
e = {
d: '_',
a: ((a==3)+'_')[d],
h: (a+'_')[o^_^o-d],
i: ((b==3)+'_')[b]
};
e[d] = ((a==3)+'_')[c^_^o];
e['c'] = (e+'_')[b+b-d];
e['o'] = (e+'_')[d];
f = e['c']+e['o']+(a+'_')[d]+((a==3)+'_')[b]+(e+'_')[b+b]+((b==3)+'_')[d]+((b==3)+'_')[b-d]+e['c']+(e+'_')[b+b]+e['o']+((b==3)+'_')[d];
e['_'] = (o^_^o)[f][f];
g = ((b==3)+'_')[d]+e.i+(e+'_')[b+b]+((b==3)+'_')[o^_^o-d]+((b==3)+'_')[d]+(a+'_')[d];
b += d;
e[g] = '\\';
e.j = (e+b)[o^_^o-d];
obo = (a+'_')[c^_^o];
e[f] = '\"';
e['_'](e['_'](g+e[f]+e[g]+d+b+d+e[g]+d+(b+d)+b+e[g]+d+b+(b+d)+e[g]+d+((o^_^o)+(o^_^o))+((o^_^o)-d)+e[g]+d+((o^_^o)+(o^_^o))+b+e[g]+(b+d)+(c^_^o)+e[g]+b+((o^_^o)-d)+e[g]+d+d+(c^_^o)+e[g]+d+b+(b+d)+e[g]+d+(b+d)+b+e[g]+d+(b+d)+b+e[g]+d+(b+d)+(b+(o^_^o))+e[g]+b+(c^_^o)+e[g]+d+((o^_^o)-d)+(b+(o^_^o))+e[g]+d+(b+d)+(b+(o^_^o))+e[g]+d+((o^_^o)+(o^_^o))+((o^_^o)-d)+e[g]+d+(b+d)+b+e[g]+d+b+b+e[g]+b+((o^_^o)-d)+e[g]+(b+d)+d+e[f])(d))('_');
Run Code Online (Sandbox Code Playgroud)
现在我们可以一次评估每个语句:
a = /??´??~???/['_'] 评估为 a = undefinedo = b = _ = 3分配o,b和_整数3c = d = b-b分配c和d整数0e = d = o^_^o/o^_^o赋值e和d整数1(o^_^o计算结果为3 XOR 3 XOR 3,产生3)e = { d: '_', a: ((a==3)+'_')[d], h: (a+'_')[o^_^o-d], i: ((b==3)+'_')[b] }分配e对象{ d: '_', a: 'a', h: 'd', i: 'e' }e[d] = ((a==3)+'_')[c^_^o]分配e[1]字符串'f'e['c'] = (e+'_')[b+b-d]分配e['c']字符串'c'e['o'] = (e+'_')[d]分配e['o']字符串'o'这只是设置,并设置了以下变量:
a = undefined
b = 3
c = 0
d = 1
e = {
1: "f",
a: "a",
c: "c",
d: "_",
h: "d",
i: "e",
o: "o"
}
Run Code Online (Sandbox Code Playgroud)
下一个语句是第一个构造东西的语句:
f = e['c'] + // => "c"
e['o'] + // => "o"
(a+'_')[d] + // => "undefined_"[1] = "n"
((a==3)+'_')[b] + // => "false_"[3] = "s"
(e+'_')[b+b] + // => "object_"[6] = "t"
((b==3)+'_')[d] + // => "true_"[1] = "r"
((b==3)+'_')[b-d] + // => "true_"[2] = "s"
e['c'] + // => "c"
(e+'_')[b+b] + // => "object_"[6] = "t"
e['o'] + // => "o"
((b==3)+'_')[d]; // => "true"[1] = "r"
Run Code Online (Sandbox Code Playgroud)
所以f = "constructor".在下一个语句中,这"constructor"用于检索函数:
e['_'] = (o^_^o)[f][f]
Run Code Online (Sandbox Code Playgroud)
这相当于(3).constructor.constructor产生函数Function,因此:
e['_'] = Function
Run Code Online (Sandbox Code Playgroud)
这个Function函数很特殊,因为可以通过参数传递函数体代码来动态构造函数:
f = Function("alert(1)")
// equivalent to
f = function() { alert(1) }
Run Code Online (Sandbox Code Playgroud)
我将跳过接下来的几个语句,然后编写结果变量和值:
a = undefined
b = 4
c = 0
d = 1
e = {
1: "f",
_: Function,
a: "a",
c: "c",
constructor: "\"",
d: "_",
h: "d",
i: "e",
j: "b",
o: "o",
return: "\\"
}
f = "constructor"
obo = "u"
Run Code Online (Sandbox Code Playgroud)
最后一个陈述完成了最后的工作:
e['_'](e['_'](g+e[f]+e[g]+d+b+d+e[g]+d+(b+d)+b+e[g]+d+b+(b+d)+e[g]+d+((o^_^o)+(o^_^o))+((o^_^o)-d)+e[g]+d+((o^_^o)+(o^_^o))+b+e[g]+(b+d)+(c^_^o)+e[g]+b+((o^_^o)-d)+e[g]+d+d+(c^_^o)+e[g]+d+b+(b+d)+e[g]+d+(b+d)+b+e[g]+d+(b+d)+b+e[g]+d+(b+d)+(b+(o^_^o))+e[g]+b+(c^_^o)+e[g]+d+((o^_^o)-d)+(b+(o^_^o))+e[g]+d+(b+d)+(b+(o^_^o))+e[g]+d+((o^_^o)+(o^_^o))+((o^_^o)-d)+e[g]+d+(b+d)+b+e[g]+d+b+b+e[g]+b+((o^_^o)-d)+e[g]+(b+d)+d+e[f])(d))('_');
Run Code Online (Sandbox Code Playgroud)
这相当于:
Function(Function( … )(1))('_')
Run Code Online (Sandbox Code Playgroud)
long表达式构建以下字符串:
return"\141\154\145\162\164\50\42\110\145\154\154\157\40\127\157\162\154\144\42\51"
Run Code Online (Sandbox Code Playgroud)
转义字符串计算:
alert("Hello World")
Run Code Online (Sandbox Code Playgroud)
此return代码传递给Function,它创建一个匿名函数,如:
function anonymous() {
return"\141\154\145\162\164\50\42\110\145\154\154\157\40\127\157\162\154\144\42\51";
}
Run Code Online (Sandbox Code Playgroud)
我们知道,相当于:
function anonymous() {
return"alert(\"Hello World\")";
}
Run Code Online (Sandbox Code Playgroud)
然后使用1as参数执行此函数,该参数返回结果字符串:
alert("Hello World")
Run Code Online (Sandbox Code Playgroud)
然后Function再次传递给它,这将创建一个新的匿名函数:
function anonymous() {
alert("Hello World");
}
Run Code Online (Sandbox Code Playgroud)
最后,还使用'_'as参数调用此函数.
sab*_*bof 15
这里有很多东西.变量附近的括号不起作用.
基本上他构造了这个字符串:
return"\141\154\145\162\164\50\42\110\145\154\154\157\40\127\157\162\154\144\42\51"
Run Code Online (Sandbox Code Playgroud)
这是一个转义版本
return "alert(\"Hello World\")"
Run Code Online (Sandbox Code Playgroud)
最后这样做:
Function(Function('return "alert(\\"Hello World\\")"')())()
Run Code Online (Sandbox Code Playgroud)
双重Function似乎是一件随意的事情,但事实并非如此.Function()将字符串中的反斜杠解释为转义字符.所以第一个调用解码,第二个调用执行.
Function("return '\\110\\145\\154\\154\\157'")()
// => "Hello"
Run Code Online (Sandbox Code Playgroud)
这是相同的代码,更好的格式化,以及"正常"变量名称;
var1=/??´??~???//*´??*/['_'];
three=(threeThenFour)=_=3;
c=(one)=(threeThenFour)-(threeThenFour);
(anObject)=(one)=(three)/(three);
(anObject)={
one:'_',
var1:((var1==3)+'_')[one],
var2?:(var1+'_')[three-(one)],
var4?:((threeThenFour==3)+'_')[threeThenFour]
};
(anObject)[one]=((var1==3)+'_')[c ^ _ ^ three];
(anObject)['c']=((anObject)+'_')[(threeThenFour)+(threeThenFour)-(one)];
(anObject)['three']=((anObject)+'_')[one];
(theConstructor)=(anObject)['c']+
(anObject)['three']+
(var1+'_')[one]+
((var1==3)+'_')[threeThenFour]+
((anObject)+'_')[(threeThenFour)+(threeThenFour)]+
((threeThenFour==3)+'_')[one]+
((threeThenFour==3)+'_')[(threeThenFour)-(one)]+
(anObject)['c']+
((anObject)+'_')[(threeThenFour)+(threeThenFour)]+
(anObject)['three']+
((threeThenFour==3)+'_')[one];
// theConstructor => "constructor"
(anObject)['_']=(three)[theConstructor][theConstructor];
(theReturn)=((threeThenFour==3)+'_')[one]+
(anObject).var4?+
((anObject)+'_')[(threeThenFour)+(threeThenFour)]+
((threeThenFour==3)+'_')[three-one]+
((threeThenFour==3)+'_')[one]+
(var1+'_')[one];
// theReturn => "return"
(threeThenFour)+=(one);
(anObject)[theReturn]='\\';
(anObject).var3?=(anObject+threeThenFour)[three-(one)];
(ovar2o)=(var1+'_')[c ^ _ ^ three];
(anObject)[theConstructor]='\"';
// (anObject)['_'] => Function
(anObject)['_'](
(anObject)['_'](theReturn+
(anObject)[theConstructor]+
(anObject)[theReturn]+
(one)+
(threeThenFour)+
(one)+
(anObject)[theReturn]+
(one)+
((threeThenFour)+(one))+
(threeThenFour)+
(anObject)[theReturn]+
(one)+(
threeThenFour)+
((threeThenFour)+(one))+
(anObject)[theReturn]+
(one)+
((three)+(three))+
((three)-(one))+
(anObject)[theReturn]+
(one)+
((three)+(three))+
(threeThenFour)+
(anObject)[theReturn]+
((threeThenFour)+(one))+
(c ^ _ ^ three)+
(anObject)[theReturn]+
(threeThenFour)+((three)-(one))+
(anObject)[theReturn]+
(one)+(one)+
(c ^ _ ^ three)+
(anObject)[theReturn]+
(one)+
(threeThenFour)+
((threeThenFour)+(one))+
(anObject)[theReturn]+
(one)+
((threeThenFour)+(one))+
(threeThenFour)+
(anObject)[theReturn]+
(one)+
((threeThenFour)+(one))+
(threeThenFour)+
(anObject)[theReturn]+
(one)+
((threeThenFour)+(one))+
((threeThenFour)+(three))+
(anObject)[theReturn]+
(threeThenFour)+
(c ^ _ ^ three)+
(anObject)[theReturn]+
(one)+
((three)-(one))+
((threeThenFour)+(three))+
(anObject)[theReturn]+
(one)+
((threeThenFour)+(one))+
((threeThenFour)+(three))+
(anObject)[theReturn]+
(one)+
((three)+(three))+
((three)-(one))+
(anObject)[theReturn]+
(one)+
((threeThenFour)+(one))+
(threeThenFour)+
(anObject)[theReturn]+
(one)+
(threeThenFour)+
(threeThenFour)+
(anObject)[theReturn]+
(threeThenFour)+
((three)-(one))+
(anObject)[theReturn]+
((threeThenFour)+(one))+
(one)+
(anObject)[theConstructor]
)
(one)
)('_');
Run Code Online (Sandbox Code Playgroud)
让我解释一下关键步骤:
代码创建一个名为Д的对象,然后添加一个'_'具有魔术JavaScript 函数构造函数值的属性.在JavaScript中,您可以将任何字符串作为代码执行,方法是将其传递给Function构造函数.
如何(???)['_']包含Function构造函数?这是通过以下方式完成的巧妙技术:
(???)['_'] = (o^_^o)[?o?][?o?];
Run Code Online (Sandbox Code Playgroud)
这里o和_设置为3.所以o^_^o返回3.显然作者可能刚刚使用o因为o^_^o返回相同的值,但我猜他对混淆有很好的品味:).所以上面的表达现在变成了(3)[?o?][?o?].
的值?o?在方括号设置为字符串"构造",是由串联在前面的语句建.它使用一种非常聪明的方法来构建字符串"constructor",方法是从内置的JavaScript字符串中删除单个字符,例如"object","true","false"和"undefined",它们是从转换为字符串的JavaScript表达式生成的.显然作者找不到字符"c"来从这些内置字符串中删除,所以他必须明确地写出这个字符串.请注意,方括号中的字符是゚o゚,它是Unicode字符,而不是圆括号中使用的简单o,尽管两者看起来非常相似.执行(3)("constructor")此操作时,返回Number构造函数.Number构造函数的构造函数是Function构造函数.所以通过(3)("constructor")("constructor")你得到函数构造函数,现在你可以最终传递一个任意字符串来执行它.
最后一行构建字符串"alert(\"Hello World\")"并将其传递给Function构造函数以执行.
问题是如何在"alert(\"Hello World\")"不输入实际字母的情况下获取该字符串?聪明的技术是使用\xxxxxx是八进制数并转换为字符的位置.要获得此字符串,您需要的数字是0,1,2,3,4,5,6,7和8.但实际上并不需要所有这些,而是可以通过三个数字0的简单算法生成它们例如,要生成'a'"警报"中的字符,您需要ASCII十进制97或八进制141,即\141.如果只有0,1和4存储在上面对象的某个属性中,则可以将它们连接起来生成'a'.这样你就可以生成任何字符串,即使你拥有的所有字符串都是0,1和4存储在Д对象的某些属性中.聪明?你打赌!
| 归档时间: |
|
| 查看次数: |
5116 次 |
| 最近记录: |