[드림핵] Carve Party

SONG's 보안·2024년 3월 31일

드림핵

목록 보기
20/33

https://dreamhack.io/wargame/challenges/96


서버 주소가 없기 때문에 문제 파일을 받아보았다.

한번 호박을 클릭하니 9999가 되었다.

F12를 눌러 코드를 확인해보았다.

누를 때 마다 해당 코드가 바뀌는 것 같다.
그래서 해당 코드를 0으로 수정해보았다.

하지만 누르면 9999로 돌아가는 것을 확인했다.

var pumpkin = [ 124, 112, 59, 73, 167, 100, 105, 75, 59, 23, 16, 181, 165, 104, 43, 49, 118, 71, 112, 169, 43, 53 ];
var counter = 0;
var pie = 1;

function make() {
  if (0 < counter && counter <= 1000) {
    $('#jack-nose').css('opacity', (counter) + '%');
  }
  else if (1000 < counter && counter <= 3000) {
    $('#jack-left').css('opacity', (counter - 1000) / 2 + '%');
  }
  else if (3000 < counter && counter <= 5000) {
    $('#jack-right').css('opacity', (counter - 3000) / 2 + '%');
  }
  else if (5000 < counter && counter <= 10000) {
    $('#jack-mouth').css('opacity', (counter - 5000) / 5 + '%');
  }

  if (10000 < counter) {
    $('#jack-target').addClass('tada');
    var ctx = document.querySelector("canvas").getContext("2d"),
    dashLen = 220, dashOffset = dashLen, speed = 20,
    txt = pumpkin.map(x=>String.fromCharCode(x)).join(''), x = 30, i = 0;

    ctx.font = "50px Comic Sans MS, cursive, TSCu_Comic, sans-serif"; 
    ctx.lineWidth = 5; ctx.lineJoin = "round"; ctx.globalAlpha = 2/3;
    ctx.strokeStyle = ctx.fillStyle = "#1f2f90";

    (function loop() {
      ctx.clearRect(x, 0, 60, 150);
      ctx.setLineDash([dashLen - dashOffset, dashOffset - speed]); // create a long dash mask
      dashOffset -= speed;                                         // reduce dash length
      ctx.strokeText(txt[i], x, 90);                               // stroke letter

      if (dashOffset > 0) requestAnimationFrame(loop);             // animate
      else {
        ctx.fillText(txt[i], x, 90);                               // fill final letter
        dashOffset = dashLen;                                      // prep next char
        x += ctx.measureText(txt[i++]).width + ctx.lineWidth * Math.random();
        ctx.setTransform(1, 0, 0, 1, 0, 3 * Math.random());        // random y-delta
        ctx.rotate(Math.random() * 0.005);                         // random rotation
        if (i < txt.length) requestAnimationFrame(loop);
      }
    })();
  }
  else {
    $('#clicks').text(10000 - counter);
  }
}

$(function() {
  $('#jack-target').click(function () {
    counter += 1;
    if (counter <= 10000 && counter % 100 == 0) {
      for (var i = 0; i < pumpkin.length; i++) {
        pumpkin[i] ^= pie;
        pie = ((pie ^ 0xff) + (i * 10)) & 0xff;
      }
    }
    make();
  });
});

코드 분석을 해보자면 make() 함수는 보이는 호박의 애니메이션을 준다.
--> 클릭을 계속하면 입이 생긴다.

var pumpkin = [ 124, 112, 59, 73, 167, 100, 105, 75, 59, 23, 16, 181, 165, 104, 43, 49, 118, 71, 112, 169, 43, 53 ];

딱 봤을 때 이건 뭐지 싶었는데, 찾아보니 아스키코드 값의 배열이다. 내가 생각하기엔 이 아스키코드가 flag가 아닐까 싶다.

그리고 마지막 함수 실행인 부분을 보면

$(function() {
  $('#jack-target').click(function () {
    counter += 1;
    if (counter <= 10000 && counter % 100 == 0) {
      for (var i = 0; i < pumpkin.length; i++) {
        pumpkin[i] ^= pie;
        pie = ((pie ^ 0xff) + (i * 10)) & 0xff;
      }
    }
    make();
  });
});

#jack-target 요소(잭오랜턴)를 클릭했을 때, 발생하는 이벤트를 처리한다. 클릭을 하면 counter가 증가하고, countercounter <= 10000 && counter % 100 == 0을 만족하는지 확인해 pumpkin 배열을 변경하고 make() 함수를 호출한다.
이때 pie16진수로 표현되어 있고, 그것을 pumkin[i]와 XOR 할당 연산을 했다는 점에서 특정 데이터를 암호화한게 아닐까라는 생각이 들었다.

이 문제를 풀기 위해서 딱 두가지 방법을 떠올렸다.

  • 진짜 10000번을 누르기
  • 반복문을 이용해서 컴퓨터가 대신 클릭하기

나는 후자를 선택하여 코드를 짜주었다.

for(i=0; i<=10000; i++){
    $('#jack-target').trigger("click")
}

반복하면서 trigger() 함수를 사용하여 #jack-target 요소에 "click" 이벤트를 발생시켜 Jack-o'-lantern을 클릭한 것으로 만든다.

trigger() 함수란?

jQuery에서 사용되는 함수로, 지정된 요소에 특정 이벤트를 강제로 발생시키는 역할을 한다.
형식 : $(이벤트를 발생시킬 요소).trigger(이벤트 유형)

원래 function()에서 #jack-target의 click을 이용한 이벤트가 진행되고 있었기에 위 코드처럼 짜주었다.

한번 더 클릭해주면 이쁜 글씨로 변한다.

성공

profile
前) SWLUG 27기

0개의 댓글