JavaScript難読化読経
はせがわようすけ
セキュリティ・キャンプ 2015
セキュリティ・キャンプ 2015
自己紹介
はせがわようすけ
株式会社セキュアスカイ・テクノロジー
OWASP Kansai Chapter Leader
OWASP Japan board member
@hasegawayosuke
http://utf-8.jp/
セキュリティ・キャンプ 2015
JavaScriptの難読化
セキュリティ・キャンプ 2015
JavaScriptの難読化
eval(function(p,a,c,k,e,r){e=function(c){return c.toString(a)};if(!''.replace(
/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=funct
ion(){return'¥¥w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('¥¥b'+e(
c)+'¥¥b','g'),k[c]);return p}('4 0=3.5("6");0.2("7",1);0.2("8",1);0.2("9","a
://b.c/");3.d.e(0);',15,15,'frame||setAttribute|document|var|createElement|ifr
ame|width|height|src|http|example|jp|body|appendChild'.split('|'),0,{}))
var frame = document.createElement( "iframe" );
frame.setAttribute( "width", 1 );
frame.setAttribute( "height", 1 );
frame.setAttribute( "src", "http://example.jp/" );
document.body.appendChild( frame );
/packer/ http://dean.edwards.name/packer/
セキュリティ・キャンプ 2015
JavaScriptの難読化
var _0x574a=["¥x69¥x66¥x72¥x61¥x6D¥x65","¥x63¥x72¥x65¥x61¥x74¥x65
¥x45¥x6C¥x65¥x6D¥x65¥x6E¥x74","¥x77¥x69¥x64¥x74¥x68","¥x73¥x65¥
x74¥x41¥x74¥x74¥x72¥x69¥x62¥x75¥x74¥x65","¥x68¥x65¥x69¥x67¥x68¥
x74","¥x73¥x72¥x63","¥x68¥x74¥x74¥x70¥x3A¥x2F¥x2F¥x65¥x78¥x61¥x6
D¥x70¥x6C¥x65¥x2E¥x6A¥x70¥x2F","¥x61¥x70¥x70¥x65¥x6E¥x64¥x43¥x6
8¥x69¥x6C¥x64","¥x62¥x6F¥x64¥x79"];var frame=document[_0x574a[1]](_0x57
4a[0]);frame[_0x574a[3]](_0x574a[2],1);frame[_0x574a[3]](_0x574a[4],1);frame[_
0x574a[3]](_0x574a[5],_0x574a[6]);document[_0x574a[8]][_0x574a[7]](frame);
var frame = document.createElement( "iframe" );
frame.setAttribute( "width", 1 );
frame.setAttribute( "height", 1 );
frame.setAttribute( "src", "http://example.jp/" );
document.body.appendChild( frame );
</> Javascript Obfuscator https://javascriptobfuscator.com/Javascript-Obfuscator.aspx
セキュリティ・キャンプ 2015
JavaScriptの難読化
eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace
(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){r
eturn d[e]}];e=function(){return'¥¥w+'};c=1};while(c--
){if(k[c]){p=p.replace(new RegExp('¥¥b'+e(c)+'¥¥b','g'),k[c])}}return p}(
'4 0=3.8("7");0.2("6",1);0.2("5",1);0.2("9","e://d.c/");3.a.b(0);',15,15,'fram
e||setAttribute|document|var|height|width|iframe|createElement|src|body|append
Child|jp|example|http'.split('|'),0,{}))
var frame = document.createElement( "iframe" );
frame.setAttribute( "width", 1 );
frame.setAttribute( "height", 1 );
frame.setAttribute( "src", "http://example.jp/" );
document.body.appendChild( frame );
Javascript Obfuscator/Encoder http://www.jsobfuscate.com/index.php
セキュリティ・キャンプ 2015
JavaScriptの難読化
$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:
++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[
$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$]
)+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[
$.$_][$.$_];$.$($.$($.$$+"¥""+"¥¥"+$.__$+$.$$_+$.$$_+$.$_$_+"¥¥"+$.__$+$.$$_+$._$_+"¥¥"+$.$__+$.__
_+$.$$$$+"¥¥"+$.__$+$.$$_+$._$_+$.$_$_+"¥¥"+$.__$+$.$_$+$.$_$+$.$$$_+"¥¥"+$.$__+$.___+"=¥¥"+$.$__
+$.___+$.$$_$+$._$+$.$$__+$._+"¥¥"+$.__$+$.$_$+$.$_$+$.$$$_+"¥¥"+$.__$+$.$_$+$.$$_+$.__+"."+$.$$__+"
¥¥"+$.__$+$.$$_+$._$_+$.$$$_+$.$_$_+$.__+$.$$$_+"¥¥"+$.__$+$.___+$.$_$+(![]+"")[$._$_]+$.$$$_+"¥¥"+
$.__$+$.$_$+$.$_$+$.$$$_+"¥¥"+$.__$+$.$_$+$.$$_+$.__+"(¥¥"+$.$__+$.___+"¥¥¥"¥¥"+$.__$+$.$_$+$.__
$+$.$$$$+"¥¥"+$.__$+$.$$_+$._$_+$.$_$_+"¥¥"+$.__$+$.$_$+$.$_$+$.$$$_+"¥¥¥"¥¥"+$.$__+$.___+");¥
¥"+$.__$+$._$_+$.$$$$+"¥¥"+$.__$+$.$$_+$._$_+$.$_$_+"¥¥"+$.__$+$.$_$+$.$_$+$.$$$_+".¥¥"+$.__$+$.$$
_+$._$$+$.$$$_+$.__+"¥¥"+$.__$+$.___+$.__$+$.__+$.__+"¥¥"+$.__$+$.$$_+$._$_+"¥¥"+$.__$+$.$_$+$.__$+
$.$_$$+$._+$.__+$.$$$_+"(¥¥"+$.$__+$.___+"¥¥¥"¥¥"+$.__$+$.$$_+$.$$$+"¥¥"+$.__$+$.$_$+$.__$+$.$$_
$+$.__+"¥¥"+$.__$+$.$_$+$.___+"¥¥¥",¥¥"+$.$__+$.___+$.__$+"¥¥"+$.$__+$.___+");¥¥"+$.__$+$._$_+
$.$$$$+"¥¥"+$.__$+$.$$_+$._$_+$.$_$_+"¥¥"+$.__$+$.$_$+$.$_$+$.$$$_+".¥¥"+$.__$+$.$$_+$._$$+$.$$$_+$
.__+"¥¥"+$.__$+$.___+$.__$+$.__+$.__+"¥¥"+$.__$+$.$$_+$._$_+"¥¥"+$.__$+$.$_$+$.__$+$.$_$$+$._+$.__+
$.$$$_+"(¥¥"+$.$__+$.___+"¥¥¥"¥¥"+$.__$+$.$_$+$.___+$.$$$_+"¥¥"+$.__$+$.$_$+$.__$+"¥¥"+$.__$+$
.$__+$.$$$+"¥¥"+$.__$+$.$_$+$.___+$.__+"¥¥¥",¥¥"+$.$__+$.___+$.__$+"¥¥"+$.$__+$.___+");¥¥"+$._
_$+$._$_+$.$$$$+"¥¥"+$.__$+$.$$_+$._$_+$.$_$_+"¥¥"+$.__$+$.$_$+$.$_$+$.$$$_+".¥¥"+$.__$+$.$$_+$._$$
+$.$$$_+$.__+"¥¥"+$.__$+$.___+$.__$+$.__+$.__+"¥¥"+$.__$+$.$$_+$._$_+"¥¥"+$.__$+$.$_$+$.__$+$.$_$$+
$._+$.__+$.$$$_+"(¥¥"+$.$__+$.___+"¥¥¥"¥¥"+$.__$+$.$$_+$._$$+"¥¥"+$.__$+$.$$_+$._$_+$.$$__+"¥¥
¥",¥¥"+$.$__+$.___+"¥¥¥"¥¥"+$.__$+$.$_$+$.___+$.__+$.__+"¥¥"+$.__$+$.$$_+$.___+"://"+$.$$$_+"¥
¥"+$.__$+$.$$$+$.___+$.$_$_+"¥¥"+$.__$+$.$_$+$.$_$+"¥¥"+$.__$+$.$$_+$.___+(![]+"")[$._$_]+$.$$$_+".
¥¥"+$.__$+$.$_$+$._$_+"¥¥"+$.__$+$.$$_+$.___+"/¥¥¥"¥¥"+$.$__+$.___+");¥¥"+$.__$+$._$_+$.$$_$+$
._$+$.$$__+$._+"¥¥"+$.__$+$.$_$+$.$_$+$.$$$_+"¥¥"+$.__$+$.$_$+$.$$_+$.__+"."+$.$_$_+"¥¥"+$.__$+$.$$
_+$.___+"¥¥"+$.__$+$.$$_+$.___+$.$$$_+"¥¥"+$.__$+$.$_$+$.$$_+$.$$_$+"¥¥"+$.__$+$.___+$._$$+"¥¥"+$
.__$+$.$_$+$.___+"¥¥"+$.__$+$.$_$+$.__$+(![]+"")[$._$_]+$.$$_$+"(¥¥"+$.$__+$.___+$.$$$$+"¥¥"+$.__$+
$.$$_+$._$_+$.$_$_+"¥¥"+$.__$+$.$_$+$.$_$+$.$$$_+"¥¥"+$.$__+$.___+");¥¥"+$.__$+$._$_+"¥"")())();
jjencode http://utf-8.jp/public/jjencode.html
セキュリティ・キャンプ 2015
JavaScriptの難読化
゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; 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) +(o^_^o))+ ((o^_^o) - (゚
Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+
((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) +
(゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚
Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+
(゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+
(゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚)
+ (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o)
+(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o)
+(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚
Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚
Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+
(c^_^o)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚
ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚
ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o)
+(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚
ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+
(以下省略)
aaencode http://utf-8.jp/public/aaencode.html
セキュリティ・キャンプ 2015
JavaScriptの難読化
[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]
+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]
+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+
[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]
+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(
[![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]
+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]
]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((+(!+[]+!+[]
+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!!
[]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(+![]+([]+[])[([][(![]+[])[+[]]+([!
[]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[
])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+
(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!!
[]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]
+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![
]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[
]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]
+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(+![]+[![]]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]
]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![
]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[
]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+
!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(
!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![
]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+
!+[]+[+[]]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(!![]+[])[+!
+[]]+(+[![]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+
[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+!+[]]]+(![]+[])[+[]]+(!![]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([]
(以下省略)
JSFuck http://www.jsfuck.com/
セキュリティ・キャンプ 2015
なぜ難読化するのか
セキュリティ・キャンプ 2015
なぜ難読化するのか
圧縮、JS自動生成の副作用
アンチウイルスやIDSの回避
アンチデバッグ
セキュリティ・キャンプ 2015
圧縮、JS自動生成の副作用
配信サイズの縮小
 レイテンシの向上
様々なminifyツール
 Google Closure Compiler
 UglifyJS
 Microsoft Ajax Minifier
他言語からJSの生成
 JSX(DeNA)、Dart (Google)など。どちらも下火
セキュリティ・キャンプ 2015
圧縮、JS自動生成の副作用
var a;for(i=0;3>i;i++)(a=docuent.getElementById("div"+i))&&a.setAttribute(
"class","Class1");
function foo(){
var div;
for( i = 0; i < 3; i++ ){
div = docuent.getElementById( "div" + i );
if( div ) div.setAttribute( "class", "Class1" );
}
}
foo();
Closure Compiler (Advanced mode) https://developers.google.com/closure/compiler/index
セキュリティ・キャンプ 2015
圧縮、JS自動生成の副作用
圧縮されたJSのデバッグ
 ブラウザのデバッガで整形
 開発者の意図を予測 - 読み手をかく乱する意図はな
いはず
 運が良ければsource mapがあるかも
セキュリティ・キャンプ 2015
圧縮、JS自動生成の副作用
WebAssembly
 ブラウザ上でのJavaScriptパース時間が高速化のボト
ルネック
 事前パース済みのバイナリJSを配信
 Web Assenblyそのものは他言語から生成されてもよ
い
 ブラウザ = WebAssembly実行環境
セキュリティ・キャンプ 2015
アンチウイルスやIDSの回避
パターンマッチの回避が目的
 機械的に大量に生成
 Gumblar、Gumblar.Xなど
 最近は少ない(?)
 解析は容易
セキュリティ・キャンプ 2015
アンチウイルスやIDSの回避
Gumblar.X
<script>/*GNU GPL*/ try{
window.onload = function(){
var If0y2m9d6n3gx = document.createElement(
's)(c&&r&i@&$p(t))@&@....'
.replace(
/&|¥(|@|#|¥!|¥$|¥^|¥)/ig, ''));
If0y2m9d6n3gx.setAttribute('type',
't$&&^e$)#x@(#@t^/^@#)j&^@a$!&^)v$a(!$!s
$$$c^r@))i$@p^@)t^!!$'
.replace(/&|#|¥)|¥!|@|¥^|¥$|¥(/ig, ''));
If0y2m9d6n3gx.setAttribute('src',
'h&(t##t(^@p&$$:#@^/$)($/#!) … (.@c)o!$$m!!(/('
.replace(/¥$|#|¥^|@|¥(|&|¥)|¥!/ig, ''));
セキュリティ・キャンプ 2015
アンチデバッグ
解読しにくくすることが目的
 攻撃者による悪意あるコード
 正規のアプリケーションによるロジックの隠ぺい
一部は趣味の世界
 jjencode, aaencode, JSF*ck
様々なテクニックが用いられる
セキュリティ・キャンプ 2015
難読化のテクニック
セキュリティ・キャンプ 2015
難読化のテクニック
長く読めない変数名
文字列の隠ぺい
プロパティへのアクセス
文字列を実行
セキュリティ・キャンプ 2015
長く読めない変数名
機械的に変数名を生成していることも。
minifyされた場合は逆に全て1文字変数
var _d43b220acebe5210eaa2 = "hello, world";
var a=document,b=body,c="message";
for( var e=f=x;j<k;j++){ .... }
セキュリティ・キャンプ 2015
難読化の文字列の隠ぺい
ゴミの埋め込み
 ゴミの埋め込まれた文字列から必要部分のみ抽出する
8進数、16進数
// "script"
's)(c&&r&i@&$p(t))@&@....'
.replace( /&|¥(|@|#|¥!|¥$|¥^|¥)/ig, '')
// "abc"
"¥141¥142¥143"
"¥x61¥x62¥x63"
セキュリティ・キャンプ 2015
文字列の隠ぺい
文字コードで1文字ずつ組み立て
ブラウザのエスケープ関数、エンコード関数
// "xss"
String.fromCharCode( 0x78, 0x73, 0x73 );
["¥x78","¥x73","¥x73"].join("");
// "alert"
atob( "YWxlcnQ=" );
unescape("%61%6c%65%72%74");
decodeURIComponent("%61%6c%65%72%74");
セキュリティ・キャンプ 2015
文字列の隠ぺい
n進数
部分文字列の切り出し、連結
// "alert"
(8680439).toString(30)
// "xyz"
"xss"[0]+"say"[2]+"gzip"[1];
"x".concat("y").concat("z");
セキュリティ・キャンプ 2015
プロパティへのアクセス
JavaScriptはオブジェクトのプロパティに連想配
列形式でアクセス可能
var obj = {
msg : "hello";
};
obj.msg = "goodbye";
alert( obj[ "msg" ] ); // "goodbye"
セキュリティ・キャンプ 2015
プロパティへのアクセス
文字列を組み立ててプロパティにアクセス可能
 以下は全て等価なコード
document.getElementById( "link" ).setAttribute("href", url );
document[ "getElementById" ]( "link" )[ "setAttribute" ]("href", url );
var x = "getElementById", y = "setAttribute";
document[ x ]( "link" )[ y ]("href", url );
セキュリティ・キャンプ 2015
文字列を実行
作成された文字列をコードとして実行
eval以外にも様々な機能が文字列をコードとして
実行可能
 要するにDOM-based XSSのシンク
var s = "alert(1)";
eval( s );
Function( "alert(1)" )();
setTimeout( "alert(1)", 0 );
execScript( "alert(1)", "jscript" ); // IE6-10
element.innerHTML = "<img src=# onerror=alert(1)>";
セキュリティ・キャンプ 2015
難読化のテクニック
改ざん時の典型的な難読化パターン
 長く読めない変数名
 文字列の隠ぺい
 プロパティへのアクセス
 文字列を実行
これらの組み合わせ
ここまではjjencode登場前の話
var de235baefe9325ea1a0012 = "a@l%e=r#t(1)".replace(/[@%=#]/g,"");
var c23356baf34a238efa0354 = "eval";
window[c23356baf34a238efa0354 ]( de235baefe9325ea1a0012 );
セキュリティ・キャンプ 2015
難読化のテクニック
jjencodeの登場でJS難読化は大きく進化
Mario Heiderich, Eduardo Alberto Vela Nava, Gareth Heyes, David Lindsay (2010)
"Web Application Obfuscation", Syngress.
この技法はこれまで誰も
目にしたことがなく、
JavaScriptにおいて真に
革新的な方法だった。
セキュリティ・キャンプ 2015
jjencodeの原理
セキュリティ・キャンプ 2015
jjencodeの原理
いくつかのシンプルなルールを活用
 数値でないものに算術演算子を適用すると数値にキャ
ストされる ( ~{} === -1 )
 文字列でないものに空文字列を連結すると文字列にキ
ャストされる ( []+"" === "" )
 数値のconstructorはNumberオブジェクト
 NumberオブジェクトのconstructorはFunctionオブ
ジェクト
 Functionを使うと文字列をコードとして実行できる
( Function("alert(1)")() )
セキュリティ・キャンプ 2015
jjencodeの原理
数字の生成
文字の生成
 この方法で"constructor"や"return"などの重要な文
字を生成する
$ = ~[]; // -1 空の配列にビットnot演算
$ = (![]+""); // "false"
$ = (![]+"")[0]; // "f"
$ = ({}+""); // "[object Object]"
$ = ({}+"")[5]; // "c"
$ = ({}.$+""); // "undefined"
$ = ({}.$+"")[1]; // "n"
セキュリティ・キャンプ 2015
jjencodeの原理
文字列からコードを実行
(0).constructor == Numberオブジェクト
Number.constructor == Functionオブジェクト
Function( "alert(1)" )(); // コードとして実行
(0)[ "constructor" ][ "constructor" ]( "alert(1)" )();
$ = "constructor";
$$ = "alert(1)";
$_ = ~[]; // -1
($_)[ $ ][ $ ]( $$ )();
セキュリティ・キャンプ 2015
jjencodeの原理
慣れればそれほど難しくはない
aaencodeも全く同じ原理
JSFuckも基本原理は同じ。"constructor"等の文
字の生成が複雑
多数の解説記事
 http://pferrie2.tripod.com/papers/jjencode.pdf
 https://code.google.com/p/corkami/source/bro
wse/trunk/asm/encodings/jjencode.txt?r=1158
セキュリティ・キャンプ 2015
難読化JSの読み方
セキュリティ・キャンプ 2015
難読化JSの読み方
 圧縮、JS自動生成されたもの
 変数名や関数名が1文字になっている
 ロジックの隠ぺいは基本的にはない
 DOM操作は隠れていないのでDOM操作を手掛かりに処理
の意図を推測
 攻撃者による改ざん
 基本的には「文字列の生成→文字列をコードとして実行」の
形態
 evalやFunctionなどのコード実行部分をフック
 改ざんの場合は結局はiframeやscriptの注入がほとんど
 基本的に根性で読む
セキュリティ・キャンプ 2015
難読化JSの読み方
Fiddlerなどのプロキシ
ブラウザのデバッガ機能
 Chrome - Developer Tools
 Firefox - 開発ツール
 IE - F12開発者ツール
セキュリティ・キャンプ 2015
Chrome Developer Tools
Ctrl+Shift+Iを押す
 または「≡」→「その他のツール」→「デベロッパーツー
ル」
セキュリティ・キャンプ 2015
Chrome Developer Tools
クリックまたは長押しする
ことで、デベロッパーツー
ルのウィンドウをブラウザ
の右または下にドッキン
グあるいは分離ができる
セキュリティ・キャンプ 2015
Chrome Developer Tools
「Sources」を選択する
ことで使われているJS
のソースコードが表示さ
れる
セキュリティ・キャンプ 2015
Chrome Developer Tools
ソースコード下段の「{ }」をクリックすること
でminifyされたJSソースを整形して表示
セキュリティ・キャンプ 2015
Chrome Developer Tools
行番号をクリックするとブレークポイントが設定される。
その状態でF5を押すとページがリロードされブレークポイントまで実行されて停止する
セキュリティ・キャンプ 2015
Chrome Developer Tools
左から順に
・コードの実行を再開
・関数を超えてステップ実行
・関数内に入ってステップ実行
・関数から抜ける
・ブレークポイントの有効/無効切り替え
・例外で停止する/しないの切り替え
セキュリティ・キャンプ 2015
演習
実際に難読化されたJSを読んでみよう
セキュリティ・キャンプ 2015
質問
hasegawa@utf-8.jp
hasegawa@securesky-tech.com
@hasegawayosuke
http://utf-8.jp/

JavaScript難読化読経