Skip to content

Instantly share code, notes, and snippets.

@mkaufmann
Created January 30, 2014 19:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mkaufmann/8716922 to your computer and use it in GitHub Desktop.
Save mkaufmann/8716922 to your computer and use it in GitHub Desktop.
Stripe-CTF3 Solutions Level -3
Diff for Level0, read file into HashSet:
========================================
+require 'set'
path = ARGV.length > 0 ? ARGV[0] : '/usr/share/dict/words'
-entries = File.read(path).split("\n")
+entries = Set.new File.read(path).split("\n")
Diff for Level1, replace calculation in bash with inline python:
================================================================
parent=$(git rev-parse HEAD)
timestamp=$(date +%s)
- counter=0
-
- while let counter=counter+1; do
- echo -n .
-
- body="tree $tree
-parent $parent
-author CTF user <me@example.com> $timestamp +0000
-committer CTF user <me@example.com> $timestamp +0000
-
-Give me a Gitcoin
-
-$counter"
-
- # See http://git-scm.com/book/en/Git-Internals-Git-Objects for
- # details on Git objects.
- sha1=$(git hash-object -t commit --stdin <<< "$body")
-
- if [ "$sha1" "<" "$difficulty" ]; then
- echo
- echo "Mined a Gitcoin with commit: $sha1"
- git hash-object -t commit --stdin -w <<< "$body" > /dev/null
- git reset --hard "$sha1" > /dev/null
- break
- fi
- done
+ body=`python << END
+from hashlib import sha1
+digest = "F"
+i = 0
+base_body = "tree $tree\n" + "parent $parent\n" + "author CTF user <me@example.com> $timestamp +0000" + "\n" + "committer CTF user <me@example.com> $timestamp +0000" + "\n" + "\n" + "Give me a Gitcoin" + "\n" + "\n"
+base_body_len = len(base_body)
+while cmp(digest,"$difficulty") > 0:
+ i = i + 1
+ str_i = str(i)
+ s = sha1()
+ s.update("commit %u\0" % (base_body_len+len(str_i)+1))
+ s.update(base_body)
+ s.update(str_i)
+ s.update("\n")
+ digest = s.hexdigest()
+print base_body + str(i)
+END`
+ sha1=$(git hash-object -t commit --stdin <<< "$body")
+ echo "Mined a Gitcoin with commit: $sha1"
+ git hash-object -t commit --stdin -w <<< "$body" > /dev/null
+ git reset --hard "$sha1" > /dev/null
}
reset() {
Diff for Level2, add bot detection with approx histogram:
========================================================
package.json:
- "seed-random": "*"
+ "seed-random": "*",
+ "fast-stats": "*"
shield:
var url = require('url');
+var Stats = require('fast-stats').Stats
var RequestData = function (request, response, buffer) {
this.request = request;
@@ -23,9 +24,36 @@ function rejectRequest(reqData) {
reqData.response.end();
}
+var BotDet = function() {
+ this.banned = false
+ this.start_time = new Date().getTime();
+ this.count = 0
+ this.rate = 1
+}
+BotDet.prototype.log = function(time, queue) {
+ this.count++;
+ if(this.count == 3) {
+ this.rate = this.count/((time - this.start_time)/1000.0)
+ queue.stats.push(this.rate)
+ }
+}
+BotDet.prototype.isBanned = function(queue, ip) {
+ if(this.banned) {
+ return true
+ }
+ var percentile = queue.stats.percentile(8)
+ if(this.rate > 2*percentile) {
+ this.banned = true
+ console.log("Banned " + ip)
+ return false
+ }
+}
+
var Queue = function (proxies, parameters) {
this.proxies = proxies;
this.parameters = parameters;
+ this.counters = {}
+ this.stats = new Stats({ bucket_precision: 50});
};
Queue.prototype.takeRequest = function (reqData) {
// Reject traffic as necessary:
@@ -34,7 +62,20 @@ Queue.prototype.takeRequest = function (reqData) {
// return;
// }
// Otherwise proxy it through:
- this.proxies[0].proxyRequest(reqData.request, reqData.response, reqData.buffer);
+ var ip = reqData.request.headers["x-forwarded-for"]
+ if(!(ip in this.counters)) {
+ this.counters[ip] = new BotDet()
+ }
+ if(this.counters[ip].banned) {
+ rejectRequest(reqData);
+ return
+ }
+ this.counters[ip].inc(new Date().getTime(), this)
+ if(this.counters[ip].isBanned(this, ip)) {
+ rejectRequest(reqData);
+ return;
+ }
+ this.proxies[Math.floor(Math.random()*this.proxies.length)].proxyRequest(reqData.request, reqData.response, reqData.buffer);
};
Queue.prototype.requestFinished = function () {
return;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment