Skip to content

Commit

Permalink
Works at last. Need to fix chal parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
evyatarmeged committed Oct 16, 2018
1 parent 2dd614f commit 549fa4f
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 56 deletions.
3 changes: 1 addition & 2 deletions humanoidReqHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const Response = require("./response");


class HumanoidReqHandler {
constructor(ignoreHttpErrors = true) {
constructor() {
this.cookieJar = rpn.jar()
this._userAgentList = fs.readFileSync(__dirname + "/ua.text").toString().split("\n");
this.UA = this._getRandomUA(); // Set UserAgent
Expand Down Expand Up @@ -67,7 +67,6 @@ class HumanoidReqHandler {

// Send the request
let res = await rpn(url, currConfig);
console.log(res)
return new Response(
res.statusCode,
res.statusMessage,res.headers,
Expand Down
33 changes: 22 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ const HumanoidReqHandler = require("./humanoidReqHandler")

class Humanoid extends HumanoidReqHandler {
// TODO: Implement c'tor params: autoRetry=false, maxRetries=3
constructor(ignoreHttpErrors=true) {
super(ignoreHttpErrors)
constructor() {
super()
this._getRandomTimeout = () => Math.floor(Math.random() * (7000 - 5000 + 1)) + 5000;
this.timeout = undefined;
// this.autoRetry = autoRetry;
Expand Down Expand Up @@ -40,25 +40,34 @@ class Humanoid extends HumanoidReqHandler {
}
}

async sendRequestAndSolve(url, method=undefined, headers=undefined, ignoreNoChallenge=false) {
}

// async sendRequestAndSolve(url, method=undefined, headers=undefined, ignoreNoChallenge=false) {
// }
//
async get(url, queryString=undefined, headers=undefined) {
return await this.sendRequest(url, "GET", queryString, headers)
}

async post(url, postBody=undefined, headers=undefined) {
async post(url, postBody=undefined, headers=undefined, dataType=undefined) {
return await this.sendRequest(url, "POST", postBody, headers, dataType)
}

async sendRequest(url, method=undefined, data=undefined, headers=undefined, dataType=undefined) {
let response = await super.sendRequest(url, method, data, headers, dataType);
console.log(`Got ${response.statusCode}`)
if (response.statusCode === 503 && this.isChallengeInResponse(response.body)) {
return await this._bypassJSChallenge(response);
let challengeResponse = await this._bypassJSChallenge(response);
// Session is definitely challenged
challengeResponse.isSessionChallenged = true;
// If we got a 200, mark challenge and solved and return
challengeResponse.isChallengeSolved = challengeResponse.statusCode === 200;
return challengeResponse;
}
return response;
}

async _bypassJSChallenge(response) {
let {...solution} = Solver.solveChallenge(response);
let timeout = Solver._extractTimeoutFromScript(response.data) || this._getRandomTimeout();
let timeout = Solver._extractTimeoutFromScript(response.body) || this._getRandomTimeout();
if (![solution.vc, solution.pass, solution.answer, solution.origin].every(elem => !!elem)) {
throw Error(`Failed to Extract one or more necessary values.
Values obtained:
Expand All @@ -74,11 +83,13 @@ class Humanoid extends HumanoidReqHandler {
headers["Referer"] = response.origin;

// Examine this and continue
let responseForChal = await this.sendRequest(answerUrl, "GET", answerObj, headers)

return await this.sendRequest(answerUrl, "GET", answerObj, headers);
}
}
}

let humanoid = new Humanoid();
humanoid.sendRequest("https://canyoupwn.me/")
humanoid.sendRequest("https://canyoupwn.me/")
.then(res => {
console.log(res)
})
56 changes: 33 additions & 23 deletions solver.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Solver {

static _extractTimeoutFromScript(html) {
let $ = cheerio.load(html);
let script = $("script");
let script = $("script").html();
let match = script.match(/,\s[0-9]0{3}\);/g);
if (match) {
match = match[0].replace(/,|\s|\)|;/g, "");
Expand Down Expand Up @@ -45,39 +45,49 @@ class Solver {
for (let ans of answerMutations) {
let operator = ans.slice(0,2);
let expr = ans.slice(3);
currResult = Solver._operateOnResult(operator, expr, currResult);
currResult = this._operateOnResult(operator, expr, currResult);
}
return currResult;
}

static _parseChallenge(matches) {
// Perform the necessary parsing on both challenge parts
let [challengeInit, challengeMutations] = [...matches];
// Perform the necessary parsing
challengeInit = challengeInit.replace(/[;}]/g, "");
challengeMutations = challengeMutations
.split(";")
.map(s => s.match(/(.=.)?(\(\(!\+).*/g))
.filter(s => s !== null)
.map(s => s[0])

return challengeInit, challengeMutations;
}

static _matchChallengeFromScript(script) {
let testMatches = script.match(/(.=\+)?(\(\(!\+).*/g); // Match the challenge part
if (testMatches.length === 2) {
return testMatches;
}
throw Error("Failed to match JS challenge with Regular Expressions")
}

static solveChallenge(response) {
// TODO: We need the length of the URL without the protocol or forward slash
// TODO: Origin == Referer, Host == t.length to add to the answer
let {html, host, origin} = {html: response.data, host: response.host, origin: response.origin};
let answerDeclaration, answerMutations, answer;
let script = Solver._extractChallengeFromHTML(html);
let [vc, pass] = [...Solver._extractInputValuesFromHTML(html)];
let {html, host, origin} = {html: response.body, host: response.host, origin: response.origin};
let script = this._extractChallengeFromHTML(html);
let [vc, pass] = [...this._extractInputValuesFromHTML(html)];

try {
// Parse only the actual math challenge parts from the script tag and assign them
let testMatches = script.match(/(.=\+)?(\(\(!\+).*/g); // Match the challenge part
if (testMatches.length === 2) {
[answerDeclaration, answerMutations] = [...testMatches];
// Perform the necessary parsing
answerDeclaration = answerDeclaration.replace(/[;}]/g, "");
answerMutations = answerMutations
.split(";")
.map(s => s.match(/(.=.)?(\(\(!\+).*/g))
.filter(s => s !== null)
.map(s => s[0])
answer = Solver._buildAnswer(answerMutations, safeEval(answerDeclaration));
answer = parseFloat(answer.toFixed(10)) + host.length;
return {vc: vc, pass: pass, answer: answer, origin: origin}
}
let challengeMatches = this._matchChallengeFromScript(script);
let [challengeInit, challengeMutations] = this._parseChallenge(challengeMatches);
let answer = this._buildAnswer(challengeMutations, safeEval(challengeInit));
answer = parseFloat(answer.toFixed(10)) + host.length;

return {vc: vc, pass: pass, answer: answer, origin: origin}
} catch (err) {
throw Error(`Could not solve or parse JavaScript challenge. Caused due to error:\n${err}`);
}
throw Error("Failed to match JS challenge with Regular Expressions")
}
}

Expand Down
20 changes: 0 additions & 20 deletions tests.js
Original file line number Diff line number Diff line change
@@ -1,20 +0,0 @@
const request = require("request-promise-native");
const tough = require("tough-cookie");
const Cookie = tough.Cookie;

let cookieJar = request.jar()

options = {
jar: cookieJar,
resolveWithFullResponse: true
}

async function roflol() {
await request("http://localhost:5000/setc", options)
console.log(cookieJar)
cookieJar = request.jar()
console.log(cookieJar)
// await request("http://localhost:5000/setc", options)
}

roflol()

0 comments on commit 549fa4f

Please sign in to comment.