728x90
반응형
프롤로그
아 개어려운데 풀 수 있을까?
문제
문제코드
#!/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)
코드 분석
@APP.route('/')
def index():
files = os.listdir(UPLOAD_DIR)
return render_template('index.html', files=files)
우선 가장 먼저 접할 수 있는 / 주소이다.
그냥 index.html 로 접근한다는 의미이다. files = os.listdir 로 UPLOAD_DIR 디렉터리의 내부 파일들의 목록을 가져와서 넘겨준다.
@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')
/upload 부분은, 폼으로부터 파일명과 내용을 입력받는데, ".." 이 파일 이름에 들어가게되면 오류를 일으키고, 그렇지 않으면 파일을 작성하여 /로 돌아간다.
@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)
/read 부분은, 파일 이름을 불러오고 그냥 읽는 거다.
풀이 전략
일단 파일을 업로드할 때
이렇게 ..이 들어가있으면
파일이 업로드 되지 않는 다는 것을 볼 수 있다. 이걸 토대로, 실제 flag.py 가 망가지면 안 되니까 그럴수도 있고, flag.py 는 ../ 에 위치할 수 있다고 추측할 수 있다.
그렇다면 read 부분에서 ../flag.py 를 읽는 방식으로 접근하는 것이 좋을 것 같다.
실행
일단 아무 파일이나 업로드해준다.
그럼 내가 작성한 메모가 보이는데, 아무 글이나 들어가준다.
아까 테스트 해본다고 작성한 글이다. 이제 여기 주소창을 확인해보자.
read 뒤에 ? name = flag.py 로 들어가는 것을 확인할 수 있다.
이제 저 부분을 read?name=../flag.py 로 바꿔주자.
여기로 접근했더니
플래그가 나왔다.
플래그는
DH{uploading_webshell_in_python_program_is_my_dream}
이다.
에필로그
알고보니 개쉬웠다.
728x90
반응형
'보안 스터디 > 웹 해킹' 카테고리의 다른 글
[드림핵/웹해킹] ServerSide: SSRF (0) | 2024.01.16 |
---|---|
[드림핵/워게임] image-storage (웹 해킹) (1) | 2024.01.15 |
[드림핵/웹해킹] ServerSide: File Vulnerability (0) | 2024.01.15 |
[드림핵/워게임] command-injection-1 (웹 해킹) (0) | 2024.01.15 |
[드림핵/웹해킹] ServerSide: Command Injection (1) | 2024.01.15 |