From 32ae95a01d9ae97feb3bbe1c853bf586cc7f500f Mon Sep 17 00:00:00 2001 From: Laurent Ghigonis Date: Wed, 17 Apr 2013 23:27:47 +0200 Subject: toys: start to work on brhute - asynchronous URL fetcher based on asyhttp --- toys/brhute.py | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ toys/pphidden_async.py | 16 +++++++- 2 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 toys/brhute.py diff --git a/toys/brhute.py b/toys/brhute.py new file mode 100644 index 0000000..a301713 --- /dev/null +++ b/toys/brhute.py @@ -0,0 +1,101 @@ +from collections import deque +import time +from asynhttp import http_evented +import warnings + +# grbrute - asynchronous URL fetcher based on asyhttp +# Uses multiple simultaneous connections and multiple requests per connections +# 2013, Laurent Ghigonis + +# Python grequests ressources : +# http://stackoverflow.com/questions/16015749/in-what-way-is-grequests-asynchronous +# https://github.com/kennethreitz/grequests/issues/13 +# http://stackoverflow.com/questions/13809650/using-grequests-to-send-a-pool-of-requests-how-can-i-get-the-response-time-of-e +# https://gist.github.com/ibrahima/3153647 - request_queue.py +# http://rubydoc.info/github/typhoeus/typhoeus/frames/Typhoeus - Ruby Typhoeus + +class SessionQueue: + def __init__(self, pool, cb_response): + self.pool = pool + self.cb_response = cb_response + self.session = requests.Session() + self.ongoing = 0 + + def add(self, url): + req = grequests.get(url, session=self.session, + hooks = {'response' : self._cb_response_session}) + grequests.send(req, self.pool, exception_handler=self._cb_exception) + self.ongoing += 1 + + def _cb_response_session(self, res, verify=None, cert=None, proxies=None, timeout=None, stream=None): + self.ongoing -= 1 + if self.cb_response(res) is False: + self.pool.kill() + + def _cb_exception(self, req, e): + print "ERROR: sending of %s failed, retrying :\n%s" % (req.url, e) + grequests.send(req, self.pool, exception_handler=self._cb_exception) + +class Brhute_ip: + """ Fetch URLs from one IP + url_iter is the iterator that provides the URLs. + cb_response should return True for the processing to continue, and False + to terminate. + If you want to integrate it in a gevent driven program, use block=False""" + def __init__(self, url_iter, ip, port=80, cb_response=None, + nb_connections=3, sleep=0, verbose=False, block=True): + warnings.warn("XXX WARNING: WORK IN PROGRESS") + warnings.warn("XXX WARNING: Don't excpect this to work") + self.url_iter = url_iter + self.ip = ip + self.port = port + self.cb_response_user = cb_response + self.nb_sessions = nb_sessions + self.sleep = sleep + self.verbose = verbose + self.pool = grequests.Pool() + self.sessions = deque() + self.ongoing_total = 0 + + hev = http_evented.http_evented((ip, port)) + self._send() + if block: + self.pool.join() + + def _send(self): + while self.ongoing_total < self.nb_sessions * self.req_per_session: + # get an URL to send + try: + url = next(self.url_iter) + except StopIteration, e: + return + if self.verbose: + print "[-] %s" % url + # select a session that has room to send + while self.sessions[0].ongoing == self.req_per_session: + self.sessions.rotate(1) + # send URL using selected sessions + self.sessions[0].add(url) + self.ongoing_total += 1 + self.sessions.rotate(1) + + def _cb_response(self, res): + self.ongoing_total -= 1 + cont = True + if self.cb_response_user: + cont = self.cb_response_user(res) + self._send() + time.sleep(self.sleep) + return cont + +class Brhute_multi_ip: + """Fetch URLs from multiple IPs pointing to the same content""" + def __init__(self): + warnings.warn("XXX WARNING: WORK IN PROGRESS") + warnings.warn("XXX WARNING: Don't excpect this to work") + +class Brhute: + """Fetch URLs""" + def __init__(self): + warnings.warn("XXX WARNING: WORK IN PROGRESS") + warnings.warn("XXX WARNING: Don't excpect this to work") diff --git a/toys/pphidden_async.py b/toys/pphidden_async.py index 1b6a576..6dd1b86 100644 --- a/toys/pphidden_async.py +++ b/toys/pphidden_async.py @@ -1,6 +1,7 @@ import sys import argparse import grbrute +import brhute # http://www.pointerpointer.com/gridPositions.json @@ -26,7 +27,7 @@ class Pp_url: raise StopIteration return res -def cb_response(res): +def cb_response_grbrute(res): global found if not found: print "[-] %s : %d" % (res.url, res.status_code) @@ -43,13 +44,24 @@ parser.add_argument('start_x', action="store", type=int, help="Start at coordinate X=") parser.add_argument('start_y', action="store", type=int, help="Start at coordinate Y=") +parser.add_argument('-b', action="store_true", dest="backend", default="gbrute", + help="Backend, can be gbrute (default) or brhute (work in progress)") parser.add_argument('-v', action="store_true", dest="verbose", default=False, help="verbose") args = parser.parse_args() found = None url_iter = Pp_url(args.image, args.start_x, args.start_y) -grbrute.Grbrute(url_iter, cb_response, verbose=args.verbose) + +if args.backend == "gbrute": + grbrute.Grbrute(url_iter, cb_response_grbrute, verbose=args.verbose) +elif args.backend == "brhute": + brhute.Brhute_ip(url_iter, ip, + cb_response=cb_response_brute, verbose=args.verbose) +else: + print "Error: Unknown backend specified" + sys.exit(1) + if found is False: print "[*] not found" sys.exit(1) -- cgit v1.2.3-59-g8ed1b