문제
문제는 다음과 같으며 flag.py
에 플래그가 존재한다.

Write-Up
문제에서 주어지는 URL로 접속하면 다음과 같이 파일 업로드 하는 기능과 업로드한 파일들을 확인하는 기능이 구현되어 있다.

비록, 문제는 파일 다운로드 취약점을 사용하여 해결하는 문제이지만, 파일 업로드 취약점도 가능한지 확인하였다.
퍼알 업로드 취약점 공격이 가능하다면, 가장 우선적으로 생각하는 접근 방식은 웹 쉘을 올린 후 cat flag.py와 같이 flag.py를 확인하는 명령어를 통해 플래그를 획득하는 방식이다.
하지만, 해당 웹 페이지는 글의 내용을 Content로 변경하여 업로드를 진행하기 때문에 웹 쉘을 올리는 것이 불가능하다.

또한, 파일 업로드 시 파일 제목의 ..문자열 필터링도 진행하기 때문에 파일 업로드 취약점 공격은 불가능하다.
@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')
반면, 파일을 읽은 후 화면에 표시해주는 read 부분을 살펴보면 filename을 별다른 검증 없이 처리하고 있다.
별다른 검증 로직이 존재하지 않기 때문에 filename을 변조해서 read페이지로 Request할 경우 파일 다운로드 취약점 공격이 정상적으로 이루어진다.
@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)
실제 업로드한 파일을 열어보면 http://host3.dreamhack.games:[포트번호]/read?name=[업로드한 파일명]
형태로 리다이렉션되며 파일 내용을 확인할 수 있다.
업로드한 파일명
부분에 별다른 검증 로직이 없으므로 ../flag.py
를 파일명으로 넣게 된다면 상위 경로에 존재하는 flag.py를 확인하여 Flag를 획득할 수 있다.
http://host3.dreamhack.games:11417/read?name=../flag.py
로 Request할 경우 Flag를 획득할 수 있다.

Flag
DH{uploading_webshell_in_python_program_is_my_dream}
오류, 잘못된 점 또는 궁금한 점이 있으시다면 댓글 남겨주세요❗
Uploaded by N2T
'Dreamhack > Web hacking' 카테고리의 다른 글
Command Injection and Command Injection-1 Write Up (2) | 2023.01.30 |
---|---|
비관계형 데이터 베이스 그리고 NoSQL Injection (0) | 2023.01.30 |
simple-sqli Write-Up (0) | 2023.01.23 |
SQL Injection (0) | 2023.01.21 |
csrf-2 Write-Up (0) | 2023.01.21 |