In my school's assignment I've been tasked to bruteforce a SHA1 hash in order to find the key.
We're provided with the flag (in SHA1), a password (in SHA1) and they told us that the key was [AAAAAA-ZZZZZZ]. The flag was in the format of SHA1(PASSWORD_KEY).
I was able to get the password via rainbow table method, and now I need to bruteforce the key from AAAAAA-ZZZZZZ. Below is the code that I came up with
function guess(flag, password) {
for (let char1 = 65; char1 <= 90; char1++) {
for (let char2 = 65; char2 <= 90; char2++) {
for (let char3 = 65; char3 <= 90; char3++) {
for (let char4 = 65; char4 <= 90; char4++) {
for (let char5 = 65; char5 <= 90; char5++) {
for (let char6 = 65; char6 <= 90; char6++) {
const key_guess = String.fromCharCode(char1, char2, char3, char4, char5, char6);
const guess = `${password}_${key_guess}`;
const shasum = crypto.createHash('sha1');
shasum.update(guess);
const hashed_guess = shasum.digest('hex');
if (hashed_guess === flag) {
return key_guess;
}
}
}
}
}
}
}
}
This works and all but it took my PC ~23s to crack the key. Since I'm writing this in nodejs I thought about utilizing promise wrapping to offload the bruteforce to multiple cores (I'm using a AMD 5600x so there's 6 physical cores) so i came up with this code
async function guessKey(flag, password) {
return new Promise(async (resolve) => {
async function guessPromise(startCharAscii, endCharAscii) {
return new Promise((resolve) => {
for (let char1 = startCharAscii; char1 <= endCharAscii; char1++) {
for (let char2 = 65; char2 <= 90; char2++) {
for (let char3 = 65; char3 <= 90; char3++) {
for (let char4 = 65; char4 <= 90; char4++) {
for (let char5 = 65; char5 <= 90; char5++) {
for (let char6 = 65; char6 <= 90; char6++) {
const key_guess = String.fromCharCode(char1, char2, char3, char4, char5, char6);
const guess = `${password}_${key_guess}`;
const shasum = crypto.createHash('sha1');
shasum.update(guess);
const hashed_guess = shasum.digest('hex');
if (hashed_guess === flag) {
resolve(key_guess);
}
}
}
}
}
}
}
});
}
const NUMBER_OF_CORES = 6;
const promiseList = [];
let startCharAscii = 65;
// 6 cores
for (let i = 0; i < NUMBER_OF_CORES; i++) {
// split into 5, 5, 4, 4, 4, 4
// btwn cores 0, 1, 2, 3, 4, 5
// core 0: [65, 69]
// core 1: [70, 74]
// core 2: [75, 78]
// core 3: [79, 82]
// core 4: [83, 86]
// core 5: [87, 90]
if (i === 0 || i === 1) {
// 5 letters
promiseList.push(guessPromise(startCharAscii, startCharAscii + 4));
startCharAscii += 5;
} else {
promiseList.push(guessPromise(startCharAscii, startCharAscii + 3));
startCharAscii += 4;
}
}
await Promise.all(promiseList);
resolve(promiseList.find((x) => x !== undefined));
});
}
(async () => {
console.time(`time`);
console.log(await guessKey(flag, password));
console.timeEnd(`time`);
})();
But pushing the pending promises into the list seems to take forever, which shouldn't happen because it's not fulfilled yet. Am I missing something or does asynchronous operations in nodeJS not utilize multi-cores?