Wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 pyc_decompile 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


이번에는 매우 간단한 문제이지만, 조금 꼬아놓은 문제입니다.

대강 코드 해석만 할 줄 알면 풀 수 있는 문제입니다.




 

 문제 이해


문제는 다음과 같습니다.


다짜고짜 bughela.pyc 파일을 제공해주는데, 이 파일을 다운로드 받으면 인코딩된 python 코드인 것을 볼 수 있습니다.

이 파일을 디컴파일 하기 위해서는 Easy Python Decompiler 프로그램을 이용하면 간단히 디컴파일 할 수 있습니다.

디컴파일 한 파일의 내용은 다음과 같습니다.


# Embedded file name: bughela.py
import time
from sys import exit
from hashlib import sha512

def main():
    print 'import me :D'


def GIVE_ME_FLAG(flag):
    if flag[:43] != 'http://wargame.kr:8080/pyc_decompile/?flag=':
        die()
    flag = flag[43:]
    now = time.localtime(time.time())
    seed = time.strftime('%m/%d/HJEJSH', time.localtime())
    hs = sha512(seed).hexdigest()
    start = now.tm_hour % 3 + 1
    end = start * (now.tm_min % 30 + 10)
    ok = hs[start:end]
    if ok != flag:
        die()
    print 'GOOD!!!'


def die():
    print 'NOPE...'
    exit()


if __name__ == '__main__':
    main()


여기서 GIVE_ME_FLAG의 코드를 이용하여 문제를 풀어야 함을 볼 수 있습니다.

import 해서 사용하면서 문제를 풀 수도 있지만, 그것만으로는 풀이가 불가능할 것 같아 새로 코드를 작성해보았습니다.




 

 문제 풀이


url을 들어가보면 제가 파이썬을 실행시킨 localtime이 서버와 다른 것을 알 수 있습니다.

대략 1분 34초? 정도 차이가 나는 것을 알 수 있습니다.


그러나 여기서는 시간과 분을 이용하여 쿼리 값을 가져오는 URL을 생성하는 것을 알 수 있는데, 시간 차이가 1분이 날 때가 있고 2분이 날 때가 있기 때문에 이런 경우를 없애기 위해 그냥 코드를 작성해보았습니다.


서버에서 시간을 읽어와서, 로컬 시간과 맞춘 후 hash화 한 다음, hash값의 특정 부분을 가져와 URL로 다시 날리는 구조입니다.

import requests
import time, datetime
from sys import exit
from hashlib import sha512

requests.packages.urllib3.disable_warnings()
sess = requests.session()
URL = 'http://wargame.kr:8080/pyc_decompile/?flag='
headers = {'Cookie': 'Cookie: chat_id=%22; ci_session=a%3A11%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%221c29bf1b489fed7b640ddc06dab12598%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22210.217.38.14%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A115%3A%22Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F74.0.3729.131+Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1557989373%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3Bs%3A4%3A%22name%22%3Bs%3A9%3A%22KKAMIKOON%22%3Bs%3A5%3A%22email%22%3Bs%3A17%3A%22hjs5576%40naver.com%22%3Bs%3A4%3A%22lang%22%3Bs%3A3%3A%22eng%22%3Bs%3A11%3A%22achievement%22%3Bs%3A7%3A%22default%22%3Bs%3A5%3A%22point%22%3Bs%3A4%3A%224925%22%3Bs%3A14%3A%22last_auth_time%22%3Bi%3A1557980940%3B%7D7fe70fc0fc030be3a34180a8d6f553637fb89ce3'}

res        = sess.get(url=URL[:-6], headers=headers, verify=False)
pos1       = res.text.find('<h1>') +4
pos2       = res.text.find('</h1>')
ServerTime = datetime.datetime.strptime(res.text[pos1:pos2], '%Y/%m/%d %H:%M:%S')

print("GET Server Time[=] : ", res.text[pos1:pos2])

now   = datetime.datetime.now()
diff  = ServerTime.minute - now.minute

print("GET Different  [=] : ", diff)

seed  = time.strftime('%m/%d/HJEJSH', time.localtime())
hs    = sha512(seed.encode()).hexdigest()
start = now.hour % 3 + 1
end   = start * ((now.minute+diff) % 30 + 10)
ok    = hs[start:end]

payload = ok
res     = sess.get(url=URL+payload, headers=headers, verify=False)

print('GET res.text[=]    : ', res.text)


이 결과는 다음과 같습니다.




+ Recent posts