Attack - Easyhaskell(200 pts)




문제를 확인해보면 Haskell로 짜여진 바이너리인 것 같다. 문제 설명의 플래그를 확인해보면 뭔가 암호화 된 것 같다. 이를 분석하기 위해 IDA로 열어보았으나, 함수가 너무 많고 알아볼 수 없어 실행을 시켜보았더니 플래그 포맷과 비슷한 문자열이 나타났다. 실행 시 argv에 값을 넣어봐도 변하지 않는 것과, stdin 등으로 입력을 받는 부분이 없는 것으로 보아 파일명을 이용하여 암호화를 할 것이라고 생각했다.




파일명을 바꿔서 실행시켜보니 예상했던대로 다른 문자열이 나타났다. 플래그 포맷이 SCTF{...}이기 때문에 SCTF{로 파일명을 바꿔 보냈더니 플래그와 일치하는 부분이 나타났다. 이를 이용하여 브루트포싱 스크립트를 작성하여 플래그를 얻어냈다.






#coding: utf-8
import os, re
import time

flag = "=ze=/<fQCGSNVzfDnlk$&?N3oxQp)K/CVzpznK?NeYPx0sz5"
goal = "=ze=/<f"

strings = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*-=+~?"

while 1:
       n = raw_input(">> ")
       name = ""
       for i in strings:
               l = os.listdir('.')
               for j in l:
                       if "SCTF" in j:
                               name = j
               next = "SCTF{"+n+i+"}"
               os.rename(name, next)
               print next
               p = os.popen("./"+next).read()
               print p
               if goal in p:
                       print next
                       break
               time.sleep(0.05)

payload.py


FLAG : SCTF{D0_U_KNoW_fUnc10N4L_L4n9U4g3?}

[H3X0R CTF 2016]

Reversing_200

RPG Game


코드게이트 대학생 세션을 제외하고는 2016년에 처음 참가하는 CTF입니다.

디미고 H3X0R 팀에서 주최하는 CTF인데, 초반 대회 운영 및 문제마다 자잘한 버그/취약점이 하나,둘씩 있어 약간 아쉬웠던 대회였습니다.

이 문제는 대회 초반에 공개된 RPG Game 문제입니다.



바이너리를 실행했을 때의 화면입니다.

Stage1부터 30까지 이루어져있으며 아무 키나 입력하면 HP가 1씩 줄어듭니다. HP를 모두 소진시키면 다음 스테이지로 자동으로 넘어갑니다. 하지만 스테이지가 다음으로 넘어가면 넘어갈수록 기하급수적으로 HP가 늘어나기 때문에 직접 HP를 깎기엔 힘드니 디버거를 통해 값을 바꿔줘야합니다. 일단 이뮤니티로 해당 바이너리를 열어보았습니다.



스트링 값을 확인 해 봤더니 위에서 언급한대로 30까지의 스테이지가 있다는 것을 유추 해 볼 수 있고, WSAStartup() 함수와 hSocketet() 함수, connect() 함수의 존재로 보아 소켓 통신을 한다는 사실을 알 수 있습니다.



conncet() 부분으로 이동 해 보니 send 함수가 있습니다. 여기로 어떤 값을 보내고, recv로 응답값을 수신하는 것 같습니다. 아마 이 부분에서 flag를 받아올 것 같습니다.



HP와 스테이지 값을 손쉽게 바꾸기 위해 Cheat Engine을 추가로 붙여주었습니다.

HP 값과 스테이지 값을 찾아 값을 변경 후, FIX 해 줍시다.



HP값을 왼쪽의 Active 버튼을 눌러 FIX 한 후, 이뮤니티에서 send 부분에 브포를 걸고 어떤 값을 송/수신 하는지 확인 해 보았습니다.



처음 봤을땐 Base64 인코딩인 줄 알았지만, 중간중간에 섞인 특수문자로 보아, 암호화 된 스트링인 것 같습니다.



recv 부분을 보니 받아온 값이 CRACKED! 라는 응답값이었습니다. 아마도 send 부분에서 올바른 값을 보내지 않으면 CRACKED!라는 문구를 뱉어내는 것 같습니다. 여기서 생각 해 볼 수 있는 것은 1에서 바로 30단계로 갔기 때문에 송신 값이 제대로 복호화 되지 않은 채로 넘어갔기 때문이라고 볼 수 있습니다. 그렇다면 1 -> 30이 아닌, 차례대로 30단계까지 가는 방법을 이용해보죠.



스테이지 값을 찾을 필요가 없으니, HP값만 찾아 FIX해줍시다.



10단계까지 왔을 때 HP 양입니다.

1410065408로, 여기서 2배가 된다면 4Byte INT형 변수의 최대 값인 2147483647을 넘어가게 됩니다.



그래서 11단계로 왔을 때 -값에서 더이상 다음 스테이지로 넘어가지 않습니다.



따라서 Cheat Engine에서 값의 Type를 4Byte에서 8Byte로 확장해줍시다.



그러면 값의 제한이 없어 30단계까지 정상적으로 클리어 할 수 있습니다.



다시 이뮤니티로 넘어와 send하는 값을 보니, flag같은 값이 넘어갑니다. 하지만 여기는 send하는 부분이니 recv 값까지 확인 해 봅시다.



위와 같이 base64로 인코딩 된 것 같은 스트링 값을 뱉어냈습니다.



notepad로 복사 해두고, 디코딩 해 봅시다.


Flag is RpG_G@mE_CraCk!

+ Recent posts