distributed-jwt-cracker
Advanced tools
Comparing version 0.0.3 to 0.0.4
{ | ||
"name": "distributed-jwt-cracker", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "An experimental distributed JWT token cracker built using Node.js and ZeroMQ", | ||
@@ -14,3 +14,4 @@ "bin": { | ||
"scripts": { | ||
"test": "node_modules/.bin/tap test/ --coverage | node_modules/.bin/tap-spec", | ||
"lint": "./node_modules/.bin/eslint src/", | ||
"test": "npm run lint && node_modules/.bin/tap test/**/*.test.js --coverage | node_modules/.bin/tap-spec", | ||
"posttest": "node_modules/.bin/tap --coverage-report=lcov && node_modules/.bin/codecov" | ||
@@ -47,7 +48,15 @@ }, | ||
"devDependencies": { | ||
"babel-eslint": "^6.1.2", | ||
"codecov": "^1.0.1", | ||
"mockery": "^1.7.0", | ||
"eslint": "^3.5.0", | ||
"eslint-config-xo-space": "^0.14.0", | ||
"eslint-plugin-babel": "^3.3.0", | ||
"mock-require": "^1.3.0", | ||
"sinon": "^1.17.5", | ||
"tap": "^7.1.2", | ||
"tap-spec": "^4.1.1" | ||
}, | ||
"eslintConfig": { | ||
"extends": "xo-space/esnext" | ||
} | ||
} |
@@ -40,3 +40,2 @@ # distributed-jwt-cracker | ||
| -s, --start | The index from where to start the search | number | 0 | | ||
| -m, --maxLength | The maximum length for the generated passwords | number | undefined | | ||
@@ -43,0 +42,0 @@ Example, using the example [JWT.io](https://jwt.io) token over a simple alphabet: |
@@ -37,4 +37,4 @@ #!/usr/bin/env node | ||
const subSocket = zmq.socket('sub'); | ||
const dealer = createDealer(batchSocket, logger); | ||
const subscriber = createSubscriber(subSocket, batchSocket, logger); | ||
const dealer = createDealer(batchSocket, process.exit, logger); | ||
const subscriber = createSubscriber(subSocket, batchSocket, process.exit, logger); | ||
@@ -47,2 +47,2 @@ batchSocket.on('message', dealer); | ||
subSocket.subscribe('exit'); | ||
batchSocket.send(JSON.stringify({"type":"join"})); | ||
batchSocket.send(JSON.stringify({type: 'join'})); |
@@ -6,15 +6,14 @@ 'use strict'; | ||
const createDealer = (batchSocket, logger) => { | ||
const createDealer = (batchSocket, exit, logger) => { | ||
let id; | ||
let getPwd; | ||
let variations; | ||
let token; | ||
const onMessage = (rawMessage) => { | ||
const dealer = rawMessage => { | ||
const msg = JSON.parse(rawMessage.toString()); | ||
switch(msg.type) { | ||
switch (msg.type) { | ||
case 'start': | ||
id = msg.id; | ||
getPwd = generator(msg.alphabet); | ||
variations = generator(msg.alphabet); | ||
token = msg.token; | ||
@@ -24,2 +23,4 @@ if (logger) { | ||
} | ||
break; | ||
case 'batch': | ||
@@ -29,3 +30,3 @@ if (logger) { | ||
} | ||
processBatch(token, getPwd, msg.batch, (pwd, index) => { | ||
processBatch(token, variations, msg.batch, (pwd, index) => { | ||
if (typeof pwd === 'undefined') { | ||
@@ -36,3 +37,3 @@ // request next batch | ||
} | ||
batchSocket.send(JSON.stringify({type:"next"})); | ||
batchSocket.send(JSON.stringify({type: 'next'})); | ||
} else { | ||
@@ -43,8 +44,9 @@ // propagate success | ||
} | ||
batchSocket.send(JSON.stringify({type:"success", password: pwd, index})); | ||
process.exit(0); | ||
batchSocket.send(JSON.stringify({type: 'success', password: pwd, index})); | ||
exit(0); | ||
} | ||
}); | ||
break; | ||
case 'default': | ||
default: | ||
if (logger) { | ||
@@ -54,7 +56,11 @@ logger.error('invalid message received from server', rawMessage.toString()); | ||
} | ||
} | ||
}; | ||
return onMessage; | ||
} | ||
dealer.getId = () => id; | ||
dealer.getToken = () => token; | ||
dealer.getVariations = () => variations; | ||
return dealer; | ||
}; | ||
module.exports = createDealer; |
'use strict'; | ||
const createSubscriber = (subSocket, batchSocket, logger) => { | ||
return (topic, rawMessage) => { | ||
const createSubscriber = (subSocket, batchSocket, exit, logger) => { | ||
const subscriber = (topic, rawMessage) => { | ||
if (topic.toString() === 'exit') { | ||
@@ -11,7 +11,11 @@ if (logger) { | ||
subSocket.close(); | ||
process.exit(0); | ||
if (typeof exit === 'function') { | ||
exit(0); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
return subscriber; | ||
}; | ||
module.exports = createSubscriber; |
@@ -6,4 +6,3 @@ 'use strict'; | ||
const processBatch = (token, getPwd, batch, cb) => { | ||
const processBatch = (token, variations, batch, cb) => { | ||
const chunkSize = 1000; | ||
@@ -18,7 +17,7 @@ const rl = readline.createInterface({ | ||
let pwd; | ||
let progress = Math.floor((from-batch[0])/(batch[1]-batch[0])*100); | ||
rl.write(`> ${progress}% (${getPwd(from)} - ${getPwd(to)})`); | ||
const progress = Math.floor((from - batch[0]) / (batch[1] - batch[0]) * 100); | ||
rl.write(`> ${progress}% (${variations(from)} - ${variations(to)})`); | ||
for (let i=from; i < to; i++) { | ||
pwd = getPwd(i); | ||
for (let i = from; i < to; i++) { | ||
pwd = variations(i); | ||
try { | ||
@@ -37,3 +36,2 @@ jwt.verify(token, pwd, {ignoreExpiration: true, ignoreNotBefore: true}); | ||
//readline.clearLine(process.stdout, 0); | ||
rl.write(null, {ctrl: true, name: 'u'}); | ||
@@ -48,7 +46,7 @@ if (from === to) { | ||
setImmediate(() => processChunk(from, to)); | ||
} | ||
}; | ||
setImmediate(() => processChunk(batch[0], Math.min(batch[1], batch[0] + chunkSize))); | ||
} | ||
}; | ||
module.exports = processBatch; |
@@ -9,9 +9,6 @@ 'use strict'; | ||
new (winston.transports.Console)({ | ||
'timestamp': () => dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss'), | ||
'colorize': true | ||
timestamp: () => dateFormat(new Date(), 'yyyy-mm-dd HH:MM:ss'), | ||
colorize: true | ||
}) | ||
] | ||
}); | ||
@@ -35,16 +35,12 @@ #!/usr/bin/env node | ||
.default('start', 0) | ||
.number('maxLength') | ||
.default('maxLength', undefined) | ||
.alias('m', 'maxLength') | ||
.describe('maxLength', 'The maximum length for the generated passwords') | ||
.help() | ||
.version() | ||
.check((args, opts) => { | ||
const token = jwt.decode(args._[0], {complete:true}); | ||
.check(args => { | ||
const token = jwt.decode(args._[0], {complete: true}); | ||
if (!token) { | ||
throw "Invalid JWT token: cannot decode token"; | ||
throw new Error('Invalid JWT token: cannot decode token'); | ||
} | ||
if (!(token.header.alg === 'HS256' && token.header.typ === 'JWT')) { | ||
throw "Invalid JWT token: only HS256 JWT tokens supported"; | ||
throw new Error('Invalid JWT token: only HS256 JWT tokens supported'); | ||
} | ||
@@ -62,3 +58,2 @@ | ||
const batchSize = argv.batchSize; | ||
const maxLength = argv.maxLength; | ||
const start = argv.start; | ||
@@ -69,5 +64,14 @@ | ||
const addClient = (channel) => { | ||
const assignNextBatch = client => { | ||
const batch = [cursor, cursor + batchSize - 1]; | ||
cursor += batchSize; | ||
client.currentBatch = batch; | ||
client.currentBatchStartedAt = new Date(); | ||
return batch; | ||
}; | ||
const addClient = channel => { | ||
const id = channel.toString('hex'); | ||
const client = {id, channel, joinedAt: new Date()} | ||
const client = {id, channel, joinedAt: new Date()}; | ||
assignNextBatch(client); | ||
@@ -77,12 +81,4 @@ clients.set(id, client); | ||
return client; | ||
} | ||
}; | ||
const assignNextBatch = (client) => { | ||
const batch = [cursor, cursor + batchSize - 1]; | ||
cursor += batchSize; | ||
client.currentBatch = batch; | ||
client.currentBatchStartedAt = new Date(); | ||
return batch; | ||
} | ||
const batchSocket = zmq.socket('router'); | ||
@@ -95,3 +91,3 @@ const signalSocket = zmq.socket('pub'); | ||
switch (msg.type) { | ||
case 'join': | ||
case 'join': { | ||
const client = addClient(channel); | ||
@@ -108,4 +104,4 @@ const response = { | ||
break; | ||
case 'next': | ||
} | ||
case 'next': { | ||
const batch = assignNextBatch(clients.get(channel.toString('hex'))); | ||
@@ -115,4 +111,4 @@ logger.info(`client ${channel.toString('hex')} requested new batch, sending ${batch[0]}-${batch[1]}`); | ||
break; | ||
case 'success': | ||
} | ||
case 'success': { | ||
const pwd = msg.password; | ||
@@ -129,7 +125,6 @@ logger.info(`client ${channel.toString('hex')} found password "${pwd}"`); | ||
break; | ||
} | ||
default: | ||
logger.error('invalid message received from channel', channel.toString('hex'), rawMessage.toString()); | ||
} | ||
}); | ||
@@ -136,0 +131,0 @@ |
14059
268
9
80