The Python Challenge – Level 20

http://www.pythonchallenge.com/pc/hex/idiot2.html

첫 페이지에 접속하면 이미지만 하나 달랑 주어진다. 이 이미지를 살펴보면 파일명이 unreal.jpg 이다. 이미지 파일에 무언가 있을듯하여 살펴보면 다음과 같다.

우선 해당 파일일 요청 시 헤더를 살펴보면 Range가 특이한 걸 알 수 있다. 따라서 Range를 변경시켜 가다보면 특정 메세지를 받을 수 있고 최종 파일을 다운로드 할 수 있게 된다.

아래는 특정 메세지 및 최종 파일을 다운로드 하는 코드이다.

[code]
#!c:\python26\python.exe
import httplib, re

def gogo(number, menu):
    if menu == 1:
        headers = {
            ‘Host’:’www.pythonchallenge.com’,
            ‘User-Agent’:’Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5′,
            ‘Accept’:’image/jpeg’,
            ‘Authorization’:’Basic YnV0dGVyOmZseQ==’,
            ‘Range’:’bytes=’ + str(number) + ‘-2123456789’}

    elif menu == 2:
        headers = {
            ‘Host’:’www.pythonchallenge.com’,
            ‘User-Agent’:’Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5′,
            ‘Accept’:’image/jpeg’,
            ‘Authorization’:’Basic YnV0dGVyOmZseQ==’,
            ‘Range’:’bytes=’ + str(2123456789-number) + ‘-2123456789’}

    elif menu == 3:
        headers = {
            ‘Host’:’www.pythonchallenge.com’,
            ‘User-Agent’:’Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5′,
            ‘Accept’:’image/jpeg’,
            ‘Authorization’:’Basic YnV0dGVyOmZseQ==’,
            ‘Range’:’bytes=1152983631-2123456789′}

    params = ”
    conn = httplib.HTTPConnection("www.pythonchallenge.com:80")
    conn.request(‘GET’, ‘/pc/hex/unreal.jpg’, params, headers)
    response = conn.getresponse()
    headers = response.getheaders()
   
    status = response.status
    data = response.read()
    conn.close()
   
    headers.sort()

    if status == 200 or status == 206:
        write(data, number)
        pos = re.search(‘\d+-\d+’, headers[0][1]).group()
        center = pos.index(‘-‘)
        first = pos[:center]
        second = pos[center+1:]
        if menu == 2:
            return 1
        return int(second) – int(first)

    else:
        return 1

def write(data, number):
    file = open(‘output’ + str(number), ‘wb’)
    file.write(data)
    file.close()

print ‘—-M e n u —-‘
print ‘1. First’
print ‘2. Get hint’
print ‘3. Get File’
print ‘—————-‘
print ‘Select :’,
menu = input()

count = 0
while 1:
    print count
    ret = gogo(count, menu)
    count += int(ret)
[/code]

메뉴에서 1번을 선택하면 특정 메세지를 받을 수 있게 된다.
2번을 선택하면 힌트를 받게 되며 3번을 선택하면 최종 파일을 다운로드 하게 된다.

1번을 선택하여 Range 값을 0부터 시작하여 탐색했을 시 특정 메세지가 나오며 이러한 메세지를 받다 보면 몇몇 메세지만 보내준 후 더이상 메세지가 나오지 않는것을 알 수 있다.

따라서 Range 값을 처음부터가 아닌 맨 마지막부터 다시 탐색을 하면 힌트가 나오게 되며 어떤 범위의 파일을 받아야 하는지 알려주게 된다.

이제 해당 범위의 파일을 받아 보면 ZIP 파일이며 암호가 걸려 있다. 해당 암호는 힌트에서 별명이라고 암시를 하고 있다. 이전에 1번을 선택하여 나온 메세지 중 "invader" 라고 나왔기 때문에 "invader" 가 패스워드 인것으로 보인다.

하지만 그냥 입력하면 틀리며 "invader"를 거꾸로 입력해야 압축이 풀린다.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다