본문 바로가기

SWLUG/CTF

[CTF/ Dreamhack] file-download-1

 

file-download-1

File Download 취약점이 존재하는 웹 서비스입니다. flag.py를 다운로드 받으면 플래그를 획득할 수 있습니다. Reference Introduction of Webhacking

dreamhack.io

 

 

 

문제 확인

 

 

 

 

 

 

문제 풀이

 

 

서버를 생성하여 접속한다

 

 

메모를 업로드 하란다...

 

 

 

상단에 'Upload My Memo'를 누르면 아래와 같은 화면이 출력된다.

 

 

 

 

저기서 아무렇게나 작성하여 upload 해본 결과, Home 화면에 아래와 같이 upload 되는 것을 확인할 수 있다.

 

 

 

 

a가 Filename인데, 클릭해보면 이렇게 뜬다.

 

url은 다음과 같다. read 함수에서 name 파라미터에 Filename = a인 메모를 다운받은 것이다.

 

 

일단 다운로드 받은 파일에서 코드를 확인하면서 맥락을 파악해보자

 

전체 코드이다.

#!/usr/bin/env python3
import os
import shutil

from flask import Flask, request, render_template, redirect

from flag import FLAG

APP = Flask(__name__)

UPLOAD_DIR = 'uploads'


@APP.route('/')
def index():
    files = os.listdir(UPLOAD_DIR)
    return render_template('index.html', files=files)


@APP.route('/upload', methods=['GET', 'POST'])
def upload_memo():
    if request.method == 'POST':
        filename = request.form.get('filename')
        content = request.form.get('content').encode('utf-8')

        if filename.find('..') != -1:
            return render_template('upload_result.html', data='bad characters,,')

        with open(f'{UPLOAD_DIR}/{filename}', 'wb') as f:
            f.write(content)

        return redirect('/')

    return render_template('upload.html')


@APP.route('/read')
def read_memo():
    error = False
    data = b''

    filename = request.args.get('name', '')

    try:
        with open(f'{UPLOAD_DIR}/{filename}', 'rb') as f:
            data = f.read()
    except (IsADirectoryError, FileNotFoundError):
        error = True


    return render_template('read.html',
                           filename=filename,
                           content=data.decode('utf-8'),
                           error=error)


if __name__ == '__main__':
    if os.path.exists(UPLOAD_DIR):
        shutil.rmtree(UPLOAD_DIR)

    os.mkdir(UPLOAD_DIR)

    APP.run(host='0.0.0.0', port=8000)

 

/upload (파일 업로드)

> POST 요청
filename과 content 데이터를 폼에서 받아옴.
filename에 .. 문자열이 포함된 경우는 디렉터리 이동을 시도할 수 있으므로 보안 목적으로 업로드 차단.
검사를 통과하면 uploads 디렉터리에 filename 이름의 파일을 생성, content를 바이너리로 파일에 씀.
업로드 후에는 / 경로로 리다이렉트하여 파일 목록을 다시 보여줌.

 

 

/read (파일 읽기)

name 파라미터로 파일명을 받으며, uploads 디렉터리에서 filename을 찾고 내용을 읽어 출력.
파일이 디렉터리이거나 존재하지 않는 경우 error 플래그를 True로 설정하여 에러를 나타냄.

여기에서 open() 안에  " UPLOAD_DIR / filename "을 통해 업로드된 파일들이 filename의 상위  디렉터리임을 알 수 있다.

 

 

따라서 url을 아래와 같이 수정해주면 FLAG를 획득할 수 있다.

 

 

 

 

 

 

'SWLUG > CTF' 카테고리의 다른 글

[CTF/ Dreamhack] DOM XSS  (0) 2024.11.13
[CTF/ RootMe] Directory traversal  (1) 2024.11.04
[CTF/ Dreamhack] pathtraversal  (1) 2024.11.04
[CTF/WebGoat] SQL Injection (advanced)  (0) 2024.10.30
[CTF/ Dreamhack] sql injection bypass WAF  (0) 2024.10.30