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