๐๏ธAccess
File Download ์ทจ์ฝ์ ์ด ์กด์ฌํ๋ ์น ์๋น์ค์ด๋ค.
flag.py๋ฅผ ๋ค์ด๋ก๋ ๋ฐ์ผ๋ฉด ํ๋๊ทธ๋ฅผ ํ๋ํ ์ ์๋ค.
๐พExploit Algorithm & Payload
#!/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)
#1
: '/upload' ํ์ด์ง์์๋ ์ฌ์ฉ์๊ฐ ์์ฑํ ๋ฉ๋ชจ๋ฅผ ์ ๋ก๋ ํ ์ ์๋ ํ์ด์ง์ด๋ค.
: '/read' ํ์ด์ง์์๋ uploadํ ํ์ผ๋ค์ด Filename(test1)์ ์ด๋ฆ ํํ๋ก ๋งํฌ๋์ด ์๋ค.
: ํด๋น ๋งํฌ๋ฅผ ํ์ธํ๋ฉด ๋ฐฉ๊ธ ์์ฑํ ๋ฉ๋ชจ๊ฐ ์ฐ๊ฒฐ๋๋ค๋ ๊ฒ์ ํ์ธํ ์ ์๊ณ , GET์ ํ๋ผ๋ฏธํฐ ํํ๋ฅผ ์ ์ ์๋ค.
(read?name=[ํ์ผ๋ช
]์ ๊ตฌ์กฐ)
: ์ฆ, ํด๋น ํ์ผ ์ ๋ก๋ ๋ฐ ๋ค์ด๋ก๋ ๊ฒฝ๋ก๋ฅผ ์กฐ์ํ๋ฉด(file vulnerability) FLAG๋ฅผ ํ๋ํ ์ ์์ ๊ฒ ๊ฐ๋ค.
#2
: burp suite ๋๊ตฌ๋ฅผ ์ด์ฉํ์ฌ uploadํ์ ๊ฒฝ์ฐ์ ํจํท์ ๋ถ์ํ๋ค.
: POST๋ฐฉ์์ผ๋ก filename, content๋ฅผ ๋ณด๋ด๋ ๊ฒ์ ํ์ธํ๋ค.
: ์ ๋ก๋ ๊ฒฐ๊ณผ๋ฅผ Proxyํ์ฌ ํจํท์ ๋ถ์ํ ๊ฒฝ์ฐ ๋ฐฉ๊ธ ์ ์ ์ ๋ ฅํ๋ ํด๋น filename๊ณผ content๋ฅผ ์๋ต๊ฐ์ผ๋ก ํ์ธํ ์ ์๋ค.
: ์ด์ read?name=test1์ ํ์ผ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ ํ์ธํ๊ณ , ํด๋น ์๋ฒ์ ์์น์ ํ์ผ์ด ์กด์ฌํ๋ฉด ํ์ธ ๊ฐ๋ฅํ ๊ฒ์ด๋ผ ์์ํ๋ค.
('../', './' , '~', ... )
#3
: ์๋ฒ์ ํ์ผ ์์๊ฒ์ด๋ผ ํ๋จ๋๋ ๊ฒ์ ์ ๋ ฅํ์ฌ ์์ ํด๋๋ก ์ด๋ํ๋ฉฐ ๋์ ์์ผฐ๋๋ ๊ฐ์ ํ์ธํ ์ ์์๋ค.
: ์ด์ FLAG๋ฅผ ์ฐพ๊ธฐ ์ํ flag.py๋ฅผ ์ฐพ์ผ๋ฉด ๋๋ ๊ฒ์ด๋ค.
(์ฃผ์ ํ์ผ ๊ฒฝ๋ก ์ค ํ๋์ธ /etc/passwd๋ฅผ ์ด๋)
(์น ์๋ฒ๊ฐ ๋์ํ๋ ๋๋ ํ ๋ฆฌ๋ฅผ ๋ฒ์ด๋ ์์์ ์์น์ ์๋ ํ์ผ๊น์ง ์ด๋๋์ด ์๋ฒ ์ฃผ์ ํ์ผ์ด ๋ ธ์ถ๋๋ ์ํ)
๐Analysis and results for obtaining the Flag DH{…}
: '../flag.py' ๊ฒฝ๋ก์์ FLAG๋ฅผ ํ๋ํ ์ ์์๋ค.
๐Summary
File Vulnerability(File Download)
-๋ฐ์ ์์ธ-
1) ํ์ผ ๋ค์ด๋ก๋ ์ ํ์ผ์ ์ ๋๊ฒฝ๋ก ๋๋ ์๋ ๊ฒฝ๋ก๊ฐ ๋
ธ์ถ
2) ๋ค์ด๋ก๋ ๋ชจ๋์ด ํ์ผ์ ๊ฒฝ๋ก, ์ด๋ฆ, ํ๋ผ๋ฏธํฐ, …๋ก ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ
3) ํ์ผ ๊ฒฝ๋ก์ ํ์ผ๋ช
ํํฐ๋ง ๋ฏธํก( ‘.’ , ‘..’ , ‘~’ ,…)
4) ๋ค์ด๋ก๋ ๊ฒฝ๋ก๊ฐ ๋
ธ์ถ๋์ง ์๋๋ผ๋ ๊ตฌ์กฐ๊ฐ ๋จ์ํ์ฌ ํ๋ผ๋ฏธํฐ ๋ณ์กฐ๋ฅผ ํตํด ์ ๊ทผ์ด ํ์ฉ๋์ง ์์ ํ์ผ์ ์ ๊ทผ์ด ๊ฐ๋ฅํ ๊ฒฝ์ฐ
...
-๋์ ๋ฐฉ์-
1) ํ์ผ๋ช
๊ณผ ๊ฒฝ๋ก๋ช
์ DB์์ ๊ด๋ฆฌ
2) ํ์ฉ๋์ง ์์ ํ์ผ์ ์ ๊ทผํ ์ ์๋๋ก ๋ฎ์ ๊ถํ์ผ๋ก ์๋น์ค ์ด์
3) ๊ฒฝ๋ก ์ด๋ ๋ฌธ์์ด์ ํํฐ๋งํ์ฌ ์์ ๋๋ ํฐ๋ฆฌ์ ๋ํ ์ ๊ทผ์ ์ฐจ๋จ
4) ์๋น์ค๊ฐ ํน์ ํ์ฅ์์ ํ์ผ๋ง์ ๋ค์ด๋ก๋ ๋ฐ๋๋ค๋ฉด ๋ค์ด๋ก๋ ํ์ผ์ ๋ํ ํ์ฅ์ ๊ฒ์ฆ ์ํ
5) ํ์ผ ๋ค์ด๋ก๋ ๊ฒฝ๋ก๋ฅผ staticํ๊ฒ ์ค์ ํ์ฌ, ๋ค๋ฅธ ๋๋ ํ ๋ฆฌ์ ์ ๊ทผํ์ง ๋ชปํ๋๋ก ์ฐจ๋จ
...
'[Dreamhack]WebHacking > ๋ก๋๋งต_Basic' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Dreamhack] Level2: blind-command (0) | 2024.01.05 |
---|---|
[Dreamhack] Level2: web-ssrf (0) | 2023.09.09 |
[Dreamhack] Level1: image-storage (0) | 2023.08.26 |
[Dreamhack] Level1: command-injection-1 (0) | 2023.08.24 |
[Dreamhack] Level2: Mango (0) | 2023.08.23 |