본문 바로가기

챌린지/Wargame.kr

bughela - fly me to the moon

wargame.kr의 6번째 문제인 fly me to the moon이다. 이번 문제는 HTTP 패킷을 분석하는 능력이 요구된다.

자바스크립트 게임에서 특정 스코어를 달성해야 플래그를 얻을 수 있는 문제다. 치트 방지 시스템을 우회하라고 되어있는데 자세히 알아보기 위해 Start 버튼을 눌러 플레이해보자.

화면 가운데에 위와 같은 간단한 게임이 제공된다. 일단 어떤 게임인지 알아보기 위해 클릭해서 플레이하면 오른쪽 그림과 같이 구불구불한 막대를 피해서 달리는 일종의 레이싱 게임인 것을 알 수 있다.

만약 벽에 닿아서 죽으면 위와 같은 메시지와 함께 게임이 종료된다. 설명을 읽어보면 31337점을 달성해야 한다고 하는데 점수는 1초에 약 5점씩 올라가므로 이를 달성하려면 6000초, 약 100분은 이 게임을 해야 한다는 말이 된다. 당연히 그게 가능할리도 없고, 의도한 풀이도 아닐테니 다른 방법을 찾아보자. 첫번째 단계는 물론 웹페이지의 소스를 보고 분석하는 것이다.

HTML 태그 자체에서는 별다른 단서를 찾을 수 없었는데 그냥 단순히 웹페이지의 img 요소가 자바스크립트로 조정되며 플레이어 캐릭터의 움직임과 벽의 위치를 나타내는 것을 확인할 수 있었다. 그렇다면 이 게임이 어떻게 동작하는지 확인하고 악용하기 위해 자바스크립트 소스 코드를 분석해야 할까?

script 태그의 난독화된 자바스크립트 코드를 분석해보니 오른쪽과 같이 복잡한 코드가 나타나는 것을 볼 수 있었다. 이걸 DOM이라고 하는지 뭔지 지식이 부족해서 잘 모르겠지만, 여기서 어떤 점수 계산 로직을 찾아서 수정하는 것은 조금 복잡하고 번거로워 보인다. 다른 정보를 조금 더 살펴보면 어떨까?

브라우저 개발자 도구의 Network 탭을 살펴보니 자바스크립트 소스를 보는 동안 주고받은 수많은 네트워크 통신을 확인할 수 있었다. Initiator 측을 보니 jquery 소스 코드의 어느 부분에서 호출되는 요청인데 jquery도 결국 자바스크립트 라이브러리인 만큼 결국은 자바스크립트 코드, 추측하기로는 게임 코드에서 이 token.php로 요청을 보내고 있다는 말이 된다. 그렇다면 이 토큰이 문제에서 설명했던 치트 방지 시스템의 매개체가 되지 않을까? 확인을 위해 웹 프록시 애플리케이션(버프 슈트 커뮤니티)으로 토큰을 잡았다가 조금 시간이 지난 후에 포워딩해보았다.

토큰 에러라는 메시지와 함께 치트 방지 시스템이 작동되었다는 메시지가 나타난 것을 알 수 있다. 그렇다면 정상적으로 게임을 한 판 플레이했을때 네트워크에서 어떤 요청과 응답이 오고가는지 확인해보기 위해 새로고침 후 다시 게임을 플레이해보자.

기본적인 파일을 제외하고 눈여겨 볼 것은 token.php와 high-scores.php다. token.php는 아까 보았듯이 치트 방지 시스템으로 일정 시간마다 인증을 수행하는 요청이다. 딱히 요청, 응답 헤더에 눈여겨 볼 만한 것은 없으며 약 5초 간격으로 전송되는 것을 알 수 있었다. 그렇다면 high-scores.php는 무엇일까? 바로 방금 플레이한 게임의 점수를 서버로 보내는 요청임을 확인할 수 있었다.

POST 데이터로 보내진 데이터를 보면 토큰값과 점수값이 포함되어 있는 것을 확인할 수 있었다. 그렇다면 이를 수정해서 점수값을 31337로 바꾸면 서버측에서 우리가 31337점을 달성했다고 인정할 것이기 때문에 문제를 풀 수 있으리라 추측할 수 있다. 그렇다면 이를 어떻게 수정할 수 있을까? 가장 쉬운 방법은 웹 프록시를 이용하여 중간에 score 값을 수정해서 포워딩하는 것이다. 물론 토큰값으로 인증하고 있기 때문에 다음 토큰이 보내지기 전에 빨리 수정해서 보내는 게 중요할 것이다.

버프 슈트 기준, 그냥 프록시로 잡다 보면 토큰도 프록시에 걸리기 때문에 치트 방지 시스템에 걸릴 수 있다. 그래서 클라이언트 요청을 잡는 기준에 바디에 'score' 라는 문자열을 포함하고 있으면, 즉 high-scores.php 요청만 프록시에서 잡아서 빠르게 수정할 수 있도록 약간의 옵션을 추가할 수 있다.

잘 잡혔다면 위처럼 나타날 것인데 여기서 score 파라미터를 빠르게 31337로 수정해서 포워딩해주면 다음처럼 플래그를 얻을 수 있다. 만약 좀 늦어서 토큰값이 달라졌다면 아까처럼 치트 방지 시스템이 작동할 것이다. 몇 번 시도해보자.

얻은 플래그 값을 auth에 입력해주면 문제를 풀 수 있다.

 

 

사실 이번 문제는 워게임.kr에 입문한지 얼마 안됐을 때 채팅창에서 얘기가 나오던 문제라서 한번 도전해 본 문제다. 처음에는 자바스크립트를 수정해야하는 줄 알고 이걸 어떻게 해석해야 하나 고민하고 있었는데 위에서 본 개발자 도구의 네트워크란에 수많은 요청과 응답이 오고가는 것을 보고 프록시로 풀 수 있겠다는 생각을 해서 해결할 수 있었다. 토큰이 좀 더 빡빡했다면 아마 직접 수정해서 포워딩하는 것은 불가능했을 텐데 이 경우에는 스크립트를 작성해서 풀 수 있으리라 생각한다.

'챌린지 > Wargame.kr' 카테고리의 다른 글

bughela - md5 password  (0) 2020.12.22
bughela - strcmp  (0) 2020.12.18
bughela - WTF_CODE  (0) 2020.12.14
bughela - login filtering  (0) 2020.12.11
bughela - QR CODE PUZZLE  (0) 2020.12.09