Write-up

[SuNiNaTas] level 5

ch4rli3kop 2019. 4. 13. 21:48
반응형

Suninatas level 5

keyword : packing

<script>
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}('g l=m o(\'0\',\'1\',\'2\',\'3\',\'4\',\'5\',\'6\',\'7\',\'8\',\'9\',\'a\',\'b\',\'c\',\'d\',\'e\',\'f\');p q(n){g h=\'\';g j=r;s(g i=t;i>0;){i-=4;g k=(n>>i)&u;v(!j||k!=0){j=w;h+=l[k]}}x(h==\'\'?\'0\':h)}',34,34,'||||||||||||||||var|result||start|digit|digitArray|new||Array|function|PASS|true|for|32|0xf|if|false|return'.split('|'),0,{}))
</script>
<!--Hint : 12342046413275659 -->
<!-- M@de by 2theT0P -->

굉장히 지저분한 무언가가 보인다.

eval(function(p, a, c, k, e, r) {
   e = function(c) {
     //console.log(c.toString(a))
     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]);
   console.log(p)
   return p
}('g l=m o(\'0\',\'1\',\'2\',\'3\',\'4\',\'5\',\'6\',\'7\',\'8\',\'9\',\'a\',\'b\',\'c\',\'d\',\'e\',\'f\');p q(n){g h=\'\';g j=r;s(g i=t;i>0;){i-=4;g k=(n>>i)&u;v(!j||k!=0){j=w;h+=l[k]}}x(h==\'\'?\'0\':h)}', 34, 34, '||||||||||||||||var|result||start|digit|digitArray|new||Array|function|PASS|true|for|32|0xf|if|false|return'.split('|'), 0, {}))

결국 function(p,a,c,k,e,r)의 리턴 값이 p를 eval()로 실행하기 때문에, p 리턴 직전에 console.log(p)를 삽입하여 p를 출력해보면 어떤 스크립트를 실행하는지 알 수 있다.

var digitArray = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');

function PASS(n) {
   var result = '';
   var start = true;
   for (var i = 32; i > 0;) {
       i -= 4;
       var digit = (n >> i) & 0xf;
       if (!start || digit != 0) {
           start = false;
           result += digitArray[digit]
      }
  }
   return (result == '' ? '0' : result)
}

hint로 줬던 숫자를 잊지않고 여기에 집어넣어 PASS(12342046413275659)를 실행시켜보면, 9c43c20c 를 얻을 수 있다.

이 값을 입력하고 check 버튼을 누르면 플래그가 똳


사실 중간에 구한 9c43c20c가 플래그인 줄 알고 여기서 한참 헤매다가 재미있는 걸 발견했다. 12342046413275659는 실제로 2BD9069C43C20B이다. 여기서는 4바이트만 구하기 때문에 9C43C20B인데, 실제 script를 돌려서 나온 값은 이보다 1이 크다. ㅇ.ㅇ???

알고 보니, 1234204641327565912342046413275660로 인식한다.

> console.log(12342046413275659)
12342046413275660
> console.log(12342046413275660)
12342046413275660
> console.log(12342046413275661)
12342046413275660
> console.log(12342046413275662)
12342046413275662
> console.log(12342046413275663)
12342046413275664
> console.log(12342046413275664)
12342046413275664
> console.log(12342046413275665)
12342046413275664

JavaScript가 53 bit integer를 지원하기 때문이라고한다. 자세한 사항은 http://2ality.com/2012/07/large-integers.html를 참고해보는게 좋겠다.


반응형

'Write-up' 카테고리의 다른 글

[SuNiNaTas] level 7  (0) 2019.04.13
[SuNiNaTas] level 6  (1) 2019.04.13
[SuNiNaTas] level 4  (0) 2019.04.13
[SuNiNaTas] level 3  (0) 2019.04.13
[SuNiNaTas] level 2  (0) 2019.04.13