Skip to content

Instantly share code, notes, and snippets.

@wfn
Last active August 29, 2015 14:00
Show Gist options
  • Save wfn/11070928 to your computer and use it in GitHub Desktop.
Save wfn/11070928 to your computer and use it in GitHub Desktop.
hacky flask script to get an intersection of vulnerable tor relay fingerprints and a tor relay consensus
#!/usr/bin/env python
import sys
from torsearch import onionoo_api # https://github.com/wfn/torsearch
from datetime import datetime
INPUT_FILE = "vuln-keys-2014-04-08b_fingerprints.txt"
FP_LEN = 40
from flask import Flask
app = Flask(__name__)
#app.debug = True
@app.route("/")
@app.route("/consensus/")
def return_result_for_newest_consensus():
global input_fingerprints
return form_result(*intersect_with_running(input_fingerprints))
@app.route("/consensus/<string:consensus_date>")
def return_for_consensus(consensus_date):
global input_fingerprints
try:
datetime.strptime(consensus_date, "%Y-%m-%d %H:%M:%S")
except:
return "<p>Your valid-after consensus date <b>%s</b> could not be parsed</p>\n"\
"<p>Valid example: <b>2014-04-18 23:00:00</b></p>" % consensus_date
return form_result(*intersect_with_consensus(input_fingerprints, consensus_date))
def get_all_results(args):
if not args:
args = {}
offset = 0
all_results = []
while True:
args['offset'] = offset
consensus, results = onionoo_api.get_results(args=args)
if not results:
break
offset += onionoo_api.UPPER_LIMIT
all_results.extend(results)
return consensus, all_results
def intersect_with_running(input_fingerprints):
consensus, results = get_all_results({'running': 'true'})
intersect = set(r.fingerprint for r in results) & set(input_fingerprints)
return consensus, results, intersect
def intersect_with_consensus(input_fingerprints, consensus_valid_after):
consensus = onionoo_api.Consensus.query.filter(
onionoo_api.Consensus.valid_after==consensus_valid_after).first()
if not consensus:
return None, None, None
status_entries = onionoo_api.StatusEntry.query.filter(
onionoo_api.StatusEntry.validafter==consensus.valid_after)
intersect = \
set(r.fingerprint for r in status_entries) & set(input_fingerprints)
return consensus, list(status_entries), intersect
def form_result(consensus, all_results, intersect):
if not (consensus and all_results and intersect):
return "Your search query returned no results!"
str = "<pre>\n"
str += "# Consensus valid-after: %s\n" % consensus.valid_after
str += "# number of input fingerprints: %d\n" % len(input_fingerprints)
str += "# number of relays in consensus: %d\n" % len(all_results)
str += "# number of intersected results: %d\n\n" % len(intersect)
str += '\n'.join(intersect) + '\n'
str += "</pre>"
return str
def get_input(fn):
input_fingerprints = []
with open(fn) as f:
for line in f:
line = line.strip()
if len(line) != FP_LEN:
print "this line is weird:"
print "<<<"+line+">>>"
else:
input_fingerprints.append(line)
return input_fingerprints
if __name__ == '__main__':
global input_fingerprints
input_fingerprints = get_input(INPUT_FILE)
app.run(host="0.0.0.0", port=7777)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment