dreamhack

[Dreamhack] file-download-1

부산영롱 2024. 1. 14. 00:12

@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')

서버 코드를 보면 filename에 '..' 문자열이 포함되면 'bad characters,,' 라는 에러메시지가 뜨게 되어있다.

filename.find('..') 는 filename에서 '..' 문자열을 찾고 해당 문자열의 첫번째 인덱스를 반환한다.

예를 들어 filename에 '../../etc/passwd' 가면 '..'으로 시작하기 때문에 0 이 반환된다.

filename에 '..' 문자열이 전혀 포함되어 있지 않으면 -1 이 반환된다.

결국 filename에 어느 위치건 '..' 문자열이 포함되어 있기만 하면 에러메시지를 출력한다는 뜻이다.

 

나는 두가지 방법으로 문제를 해결할 수 있었다.

 

첫번째는 '..' 문자열을 URL 인코딩하여 업로드하는 것이다.

아래와 같이 '..' 대신 '%2e%2e'를 사용하면 우회하여 업로드가 가능하고 원하는 파일을 다운로드 할 수 있었다.

 

두번째는 파라미터를 수정하여 요청하는 것이다.

'..' 문자열 필터링은 업로드 기능을 사용할 때 제목만 검증하기 때문에 파라미터를 수정하여 요청할 때는 소용이 없다.

아래와 같이 URL 파라미터 부분을 ../flag.py로 수정해서 요청하면 플래그를 얻을 수 있다.

물론 여기서도 인코딩된 URL을 사용해도 똑같이 플래그를 얻을 수 있다.

 

다만 flag.py 파일 위치를 알 수 없었기 때문에 '../' 를 하나씩 늘려가면서 찾을 수 밖에 없다.

../flag.py로 플래그를 얻을 수 있었으니 flag.py의 위치는 /upload/flag.py 이다.

'dreamhack' 카테고리의 다른 글

[Dreamhack] Carve Party  (0) 2024.01.18
[Dreamhack] web-ssrf  (0) 2024.01.15
[Dreamhack] image-storage  (0) 2024.01.11
[Dreamhack] command-injection-1  (0) 2024.01.10
[Dreamhack] Mango  (0) 2024.01.10