Javascript 코드 난독화(Code Obfuscation)와 JS Packing
코드 난독화란 코드를 쉽게 알아볼 수 없도록 만드는 기술입니다. 쉽게 생각하면 int a = 123
이란 코드를 int a = ((123+34+350-34-350)*0)+123
같이 좀 더 알아보기 어렵게 만드는 기술입니다. 물론 위의 대충 쓴 코드는 쉽게 볼 수 있지만 escape, unescape 함수 등을 이용해서 코드가 눈에 잘 들어오지 않도록 만들 수 있습니다.
난독화 방법도 매우 많고 난독화를 도와주는 프레임워크, 툴도 매우 많습니다. 그 중 아주 가볍게 몇개만 적어보았고, 쉽게 Packing 을 할 수 있는 사이트 하나를 더 소개하겠습니다.
URL Encoding
escape 함수는 url 인코딩을 지원하는 함수입니다.
<html>
<body>
<script>document.write(escape('CODE==BLACK'))</script>
</body>
</html>
Output : CODE%3D%3DBLACK
eval 함수를 이용한 Decimal 난독화
eval 함수는 javascript의 읽고 실행하는 함수입니다. 해당 함수를 이용하여 숫자를 문자값으로 변환하여 코드의 내용을 숨길 수 있습니다.
<html>
<body>
<script>
code = "115,99,114,105,112,116";
code = eval("String.fromCharCode("+code+")");
document.write(code);
</script>
</body>
</html>
Output : script
난독화에 사용되는 여러 함수들
위 eval 함수 하나만으로는 정교한 난독화가 어렵습니다. 분석가가 코드를 알아보기 더 힘들게 공격자는 replace, eval 등 js 함수와 unicode, hex 데이터 등 여러가지 방법으로 난독화를 진행하게 됩니다. 위에서 사용된 함수를 이용하여 간단하게 작성하였으며 아래와 같은 형식으로 분석에 방해를 줄 수 있습니다.
<html>
<body>
<script>
code = "115,99,114,105,112,116";
code = eval("String.fromCharCode("+code+")");
code2 = "%66%61%6b%65%20%66%75%6e%63%74%69%6f%6e%20%61%61%61%64%66%64%76%6d%76%6d%66%6d%66%67%6c%6a%66%6c%67%6b%6a%61%66%64%6c%6b%61%6a%73%64%66%3b%6c%6b%61%6a%73%3b%66%6c%6b%6a%3b%6c";
code3 = "%3e%61%6c%65%72%74%28%22%63%6f%64%65%62%6c%61%63%6b%2e%6e%65%74%20%62%79%20%68%61%68%77%75%6c%22%29%3b%3c%2f%73%63%72%69%70%74%3e";
code1 = code3;
code3 = code2 == code3 ? code2 : code1;
document.write("<"+code+""+unescape(code3));
</script>
</body>
</html>
Output
<script>alert("codeblack.net by hahwul");</script>
Javascript Packing
자바스크립트에는 여러가지 Packer가 있지만 간단하게는 아래 사이트에서 쉽게 적용할 수 있습니다.
input
code = "115,99,114,105,112,116";
code = eval("String.fromCharCode("+code+")");
document.write(code);
Output (Base62 encode)
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=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('0="6,2,3,4,5,b";0=7("8.9("+0+")");a.1(0);',12,12,'code|write|99|114|105|112|115|eval|String|fromCharCode|document|116'.split('|'),0,{}))