Created
February 17, 2020 23:55
-
-
Save manciuszz/ddddf1b19a2be781d60406c132f92ddc to your computer and use it in GitHub Desktop.
The new CloudFlare JS Challenge via POST request minimal solution.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Before executing, make a break point on "#jschl_answer" element so when it gets a value, debugger kicks in... | |
(function() { | |
let form = document.querySelector("#challenge-form"); | |
if (!form) | |
return console.log("No JS Challenge detected!"); | |
let request = function(params, callbackFn) { | |
fetch(params.requestURL, { | |
"method": "POST", | |
"headers": { | |
"content-type": "application/x-www-form-urlencoded", | |
}, | |
"body": `r=${params.r}&jschl_vc=${params.jschl_vc}&pass=${params.pass}&jschl_answer=${params.jschl_answer}`, | |
}).then(res => res.text()).then(res => { | |
callbackFn(res); | |
}); | |
}; | |
let solveChallenge = function(htmlResponse) { | |
let doc = new DOMParser().parseFromString(htmlResponse, 'text/html'); | |
let operation = doc.head.innerHTML.match(new RegExp("setTimeout\\(function\\(\\)\\{\\s+(var (?:\\w,)+f.+?\\r?\\n[\\s\\S]+?a\\.value =.+?)\\r?\\n")); | |
operation = operation[1] | |
.replace(new RegExp("a\\.value = (.+ \\+ t\\.length.+?)\'?;.+", "g"), "$1") | |
.replace(new RegExp("(e\\s=\\sfunction\\(s\\)\\s\\{.*?};)", "gms"), "") | |
.replace(new RegExp("\\s{3,}[a-z](?: = |\\.).+", "g"), "") | |
.replace("t.length", (location.host.length + 1).toString()) | |
.replace("\\n", ""); | |
return { | |
"requestURL": doc.querySelector("#challenge-form").action, | |
"r": doc.querySelector("input[name=r]").value, | |
"jschl_vc": doc.querySelector("input[name=jschl_vc]").value, | |
"pass": doc.querySelector("input[name=pass]").value, | |
"jschl_answer": eval(operation.toString()), | |
}; | |
}; | |
// Disable form submit functions, so it doesn't automatically redirect the browser page (since we want do confirm everything works manually) | |
form.submit = function() {}; | |
let bypass = function(currentHTML) { | |
request(solveChallenge(currentHTML), function(responseHTML) { | |
setTimeout(() => { | |
bypass(responseHTML); | |
}, 5000); | |
}); | |
}; | |
// Function that takes a document HTML string as input and calculates the solution which is then used for comparison to see if both solutions are identical | |
// This was mainly used for confirming cloudflare bypass implementation calculations on other languages (like Kotlin)... | |
let testSolution = function(testHTML) { | |
let current = { | |
"requestURL": document.querySelector("#challenge-form").action, | |
"r": document.querySelector("input[name=r]").value, | |
"jschl_vc": document.querySelector("input[name=jschl_vc]").value, | |
"pass": document.querySelector("input[name=pass]").value, | |
"jschl_answer": document.querySelector("#jschl-answer").value, | |
}; | |
let solved = solveChallenge(testHTML || document.documentElement.innerHTML); | |
return [current, solved]; | |
}; | |
bypass(document.documentElement.innerHTML); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The gist of how CF challenge works in pretty details - https://stackoverflow.com/a/60131975