def main(): usage = "usage: %prog [options] target\r\n" usage += "examples:\r\n" usage += "%prog -e100-999 10.0.0.1\r\n" usage += "%prog -d dictionary.txt 10.0.0.2\r\n" parser = OptionParser(usage, version="%prog v" + str(__version__) + __GPL__) parser.add_option("-p", "--port", dest="port", default="5060", help="Destination port of the SIP device - eg -p 5060", metavar="PORT") parser = standardoptions(parser) parser = standardscanneroptions(parser) parser.add_option("-d", "--dictionary", dest="dictionary", type="string", help="specify a dictionary file with possible extension names", metavar="DICTIONARY") parser.add_option("-m", "--method", dest="method", type="string", help="specify a request method. The default is REGISTER. Other possible methods are OPTIONS and INVITE", default="REGISTER", metavar="OPTIONS") parser.add_option("-e", "--extensions", dest="range", default='100-999', help="specify an extension or extension range\r\nexample: -e 100-999,1000-1500,9999", metavar="RANGE") parser.add_option("-z", "--zeropadding", dest="zeropadding", type="int", help="""the number of zeros used to padd the username. the options "-e 1-9999 -z 4" would give 0001 0002 0003 ... 9999""", default=0, metavar="PADDING") parser.add_option('--force', dest="force", action="store_true", default=False, help="Force scan, ignoring initial sanity checks.") parser.add_option('--template', '-T', action="store", dest="template", help="""A format string which allows us to specify a template for the extensions example svwar.py -e 1-999 --template="123%#04i999" would scan between 1230001999 to 1230999999" """) parser.add_option('--enabledefaults', '-D', action="store_true", dest="defaults", default=False, help="""Scan for default / typical extensions such as 1000,2000,3000 ... 1100, etc. This option is off by default. Use --enabledefaults to enable this functionality""") parser.add_option('--maximumtime', action='store', dest='maximumtime', type="int", default=10, help="""Maximum time in seconds to keep sending requests without receiving a response back""") parser.add_option('--domain', dest="domain", help="force a specific domain name for the SIP message, eg. -d example.org") parser.add_option("--debug", dest="printdebug", help="Print SIP messages received", default=False, action="store_true" ) parser.add_option('-6', dest="ipv6", action="store_true", help="scan an IPv6 address") (options, args) = parser.parse_args() global exportpath exportpath = None logging.basicConfig(level=calcloglevel(options)) logging.debug('started logging') if options.force: initialcheck = False else: initialcheck = True if options.template is not None: try: options.template % 1 except TypeError: logging.critical( "The format string template is not correct. Please provide an appropiate one") exit(1) if options.resume is not None: exportpath = os.path.join(os.path.expanduser( '~'), '.sipvicious', __prog__, options.resume) if os.path.exists(os.path.join(exportpath, 'closed')): logging.error("Cannot resume a session that is complete") exit(1) if not os.path.exists(exportpath): logging.critical( 'A session with the name %s was not found' % options.resume) exit(1) optionssrc = os.path.join(exportpath, 'options.pkl') previousresume = options.resume previousverbose = options.verbose options, args = pickle.load(open(optionssrc, 'rb'), encoding='bytes') options.resume = previousresume options.verbose = previousverbose elif options.save is not None: exportpath = os.path.join(os.path.expanduser( '~'), '.sipvicious', __prog__, options.save) if len(args) != 1: parser.error("provide one hostname") else: host = args[0] if options.dictionary is not None: guessmode = 2 try: dictionary = open(options.dictionary, 'r', encoding='utf-8', errors='ignore') except IOError: logging.error("could not open %s" % options.dictionary) exit(1) if options.resume is not None: lastextensionsrc = os.path.join(exportpath, 'lastextension.pkl') previousposition = pickle.load(open(lastextensionsrc, 'rb'), encoding='bytes') dictionary.seek(previousposition) guessargs = dictionary else: guessmode = 1 if options.resume is not None: lastextensionsrc = os.path.join(exportpath, 'lastextension.pkl') try: previousextension = pickle.load(open(lastextensionsrc, 'rb'), encoding='bytes') except IOError: logging.critical('Could not read from %s' % lastextensionsrc) exit(1) logging.debug('Previous range: %s' % options.range) options.range = resumeFrom(previousextension, options.range) logging.debug('New range: %s' % options.range) logging.info('Resuming from %s' % previousextension) extensionstotry = getRange(options.range) guessargs = (extensionstotry, options.zeropadding, options.template, options.defaults) if options.save is not None: if options.resume is None: exportpath = os.path.join(os.path.expanduser( '~'), '.sipvicious', __prog__, options.save) if os.path.exists(exportpath): logging.warning( 'we found a previous scan with the same name. Please choose a new session name') exit(1) logging.debug('creating an export location %s' % exportpath) try: os.makedirs(exportpath, mode=0o700) except OSError: logging.critical( 'could not create the export location %s' % exportpath) exit(1) optionsdst = os.path.join(exportpath, 'options.pkl') logging.debug('saving options to %s' % optionsdst) pickle.dump([options, args], open(optionsdst, 'wb+')) if options.autogetip: tmpsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tmpsocket.connect(("msn.com", 80)) options.externalip = tmpsocket.getsockname()[0] tmpsocket.close() enableack = False if options.method.upper() == 'INVITE': enableack = True sipvicious = TakeASip( host, port=options.port, selecttime=options.selecttime, method=options.method, compact=options.enablecompact, guessmode=guessmode, guessargs=guessargs, sessionpath=exportpath, initialcheck=initialcheck, externalip=options.externalip, enableack=enableack, maxlastrecvtime=options.maximumtime, localport=options.localport, domain=options.domain, printdebug=options.printdebug, ipv6=options.ipv6, ) start_time = datetime.now() #logging.info("scan started at %s" % str(start_time)) logging.info("start your engines") try: sipvicious.start() if exportpath is not None: open(os.path.join(exportpath, 'closed'), 'w').close() except KeyboardInterrupt: logging.warning('caught your control^c - quiting') except Exception as err: if options.reportBack: logging.critical( "Got unhandled exception : %s\nSending report to author" % err.__str__()) reportBugToAuthor(traceback.format_exc()) else: logging.critical( "Unhandled exception - please run same command with the -R option to send me an automated report") pass logging.exception("Exception") if options.save is not None and sipvicious.nextuser is not None: lastextensiondst = os.path.join(exportpath, 'lastextension.pkl') logging.debug('saving state to %s' % lastextensiondst) try: if guessmode == 1: pickle.dump(sipvicious.nextuser, open( os.path.join(exportpath, 'lastextension.pkl'), 'wb')) logging.debug('logged last extension %s' % sipvicious.nextuser) elif guessmode == 2: pickle.dump(sipvicious.guessargs.tell(), open( os.path.join(exportpath, 'lastextension.pkl'), 'wb')) logging.debug('logged last position %s' % sipvicious.guessargs.tell()) except IOError: logging.warning('could not log the last extension scanned') # display results if not options.quiet: lenres = len(sipvicious.resultauth) if lenres > 0: logging.info("we have %s extensions" % lenres) if (lenres < 400 and options.save is not None) or options.save is None: labels = ('Extension', 'Authentication') rows = list() try: for k in sipvicious.resultauth.keys(): rows.append((k.decode(), sipvicious.resultauth[k].decode())) except AttributeError: for k in sipvicious.resultauth.keys(): rows.append((k, sipvicious.resultauth[k])) print(to_string(rows, header=labels)) else: logging.warning("too many to print - use svreport for this") else: logging.warning("found nothing") end_time = datetime.now() total_time = end_time - start_time logging.info("Total time: %s" % total_time)
def main(): usage = "usage: %prog -u username [options] target\r\n" usage += "examples:\r\n" usage += "%prog -u100 -d dictionary.txt 10.0.0.1\r\n" usage += "%prog -u100 -r1-9999 -z4 10.0.0.1\r\n" parser = OptionParser(usage, version="%prog v" + str(__version__) + __GPL__) parser.add_option("-p", "--port", dest="port", default="5060", help="Destination port of the SIP device - eg -p 5060", metavar="PORT") parser = standardoptions(parser) parser = standardscanneroptions(parser) parser.add_option("-u", "--username", dest="username", help="username to try crack", metavar="USERNAME") parser.add_option("-d", "--dictionary", dest="dictionary", type="string", help="specify a dictionary file with passwords", metavar="DICTIONARY") parser.add_option("-r", "--range", dest="range", default="100-999", help="specify a range of numbers. example: 100-200,300-310,400", metavar="RANGE") parser.add_option("-e", "--extension", dest="extension", help="Extension to crack. Only specify this when the extension is different from the username.", metavar="EXTENSION") parser.add_option("-z", "--zeropadding", dest="zeropadding", type="int", default=0, help="""the number of zeros used to padd the password. the options "-r 1-9999 -z 4" would give 0001 0002 0003 ... 9999""", metavar="PADDING") parser.add_option("-n", "--reusenonce", dest="reusenonce", default=False, help="Reuse nonce. Some SIP devices don't mind you reusing the nonce (making them vulnerable to replay attacks). Speeds up the cracking.", action="store_true", ) parser.add_option('--template', '-T', action="store", dest="template", help="""A format string which allows us to specify a template for the extensions example svwar.py -e 1-999 --template="123%#04i999" would scan between 1230001999 to 1230999999" """) parser.add_option('--maximumtime', action='store', dest='maximumtime', type="int", default=10, help="Maximum time in seconds to keep sending requests without receiving a response back") parser.add_option('--enabledefaults', '-D', action="store_true", dest="defaults", default=False, help="""Scan for default / typical passwords such as 1000,2000,3000 ... 1100, etc. This option is off by default. Use --enabledefaults to enable this functionality""") parser.add_option('--domain', dest="domain", help="force a specific domain name for the SIP message, eg. example.org") parser.add_option('--requesturi', dest="requesturi", help="force the first line URI to a specific value; e.g. sip:[email protected]") parser.add_option('-6', dest="ipv6", action="store_true", help="Scan an IPv6 address") parser.add_option('-m','--method', dest='method', default='REGISTER', help="Specify a SIP method to use") (options, args) = parser.parse_args() exportpath = None logging.basicConfig(level=calcloglevel(options)) logging.debug('started logging') if options.resume is not None: exportpath = os.path.join(os.path.expanduser( '~'), '.sipvicious', __prog__, options.resume) if os.path.exists(os.path.join(exportpath, 'closed')): logging.error("Cannot resume a session that is complete") exit(1) if not os.path.exists(exportpath): logging.critical( 'A session with the name %s was not found' % options.resume) exit(1) optionssrc = os.path.join(exportpath, 'options.pkl') previousresume = options.resume previousverbose = options.verbose options, args = pickle.load(open(optionssrc, 'rb'), encoding='bytes') options.resume = previousresume options.verbose = previousverbose elif options.save is not None: exportpath = os.path.join(os.path.expanduser( '~'), '.sipvicious', __prog__, options.save) logging.debug('Session path: %s' % exportpath) if options.resume is not None: exportpath = os.path.join(os.path.expanduser( '~'), '.sipvicious', __prog__, options.resume) if not os.path.exists(exportpath): logging.critical( 'A session with the name %s was not found' % options.resume) exit(1) optionssrc = os.path.join(exportpath, 'options.pkl') previousresume = options.resume previousverbose = options.verbose options, args = pickle.load(open(optionssrc, 'rb'), encoding='bytes') options.resume = previousresume options.verbose = previousverbose elif options.save is not None: exportpath = os.path.join(os.path.expanduser( '~'), '.sipvicious', __prog__, options.save) if len(args) != 1: parser.error("provide one hostname") else: host = args[0] if options.username is None: parser.error("provide one username to crack") if options.dictionary is not None: crackmode = 2 try: dictionary = open(options.dictionary, 'r', encoding='utf-8', errors='ignore') except IOError: logging.error("could not open %s" % options.dictionary) if options.resume is not None: lastpasswdsrc = os.path.join(exportpath, 'lastpasswd.pkl') previousposition = pickle.load(open(lastpasswdsrc, 'rb'), encoding='bytes') dictionary.seek(previousposition) crackargs = dictionary else: crackmode = 1 if options.resume is not None: lastpasswdsrc = os.path.join(exportpath, 'lastpasswd.pkl') try: previouspasswd = pickle.load(open(lastpasswdsrc, 'rb'), encoding='bytes') except IOError: logging.critical('Could not read from %s' % lastpasswdsrc) exit(1) logging.debug('Previous range: %s' % options.range) options.range = resumeFrom(previouspasswd, options.range) logging.debug('New range: %s' % options.range) logging.info('Resuming from %s' % previouspasswd) rangelist = getRange(options.range) crackargs = (rangelist, options.zeropadding, options.template, options.defaults, [options.username]) if options.save is not None: if options.resume is None: exportpath = os.path.join(os.path.expanduser( '~'), '.sipvicious', __prog__, options.save) if os.path.exists(exportpath): logging.warning( 'we found a previous scan with the same name. Please choose a new session name') exit(1) logging.debug('creating an export location %s' % exportpath) try: os.makedirs(exportpath, mode=0o700) except OSError: logging.critical( 'could not create the export location %s' % exportpath) exit(1) optionsdst = os.path.join(exportpath, 'options.pkl') logging.debug('saving options to %s' % optionsdst) pickle.dump([options, args], open(optionsdst, 'wb+')) if options.autogetip: tmpsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tmpsocket.connect(("msn.com", 80)) options.externalip = tmpsocket.getsockname()[0] tmpsocket.close() sipvicious = ASipOfRedWine( host, username=options.username, selecttime=options.selecttime, compact=options.enablecompact, crackmode=crackmode, crackargs=crackargs, reusenonce=options.reusenonce, extension=options.extension, sessionpath=exportpath, port=options.port, externalip=options.externalip, maxlastrecvtime=options.maximumtime, localport=options.localport, domain=options.domain, requesturi=options.requesturi, ipv6=options.ipv6, method=options.method, ) start_time = datetime.now() logging.info("scan started at %s" % str(start_time)) try: sipvicious.start() if exportpath is not None: open(os.path.join(exportpath, 'closed'), 'w').close() except KeyboardInterrupt: logging.warning('caught your control^c - quiting') except Exception as err: if options.reportBack: logging.critical( "Got unhandled exception : %s\nsending report to author" % err.__str__()) reportBugToAuthor(traceback.format_exc()) else: logging.critical( "Unhandled exception - please run same command with the -R option to send me an automated report") pass logging.exception("Exception") if options.save is not None and sipvicious.previouspassword is not None: lastextensiondst = os.path.join(exportpath, 'lastpasswd.pkl') logging.debug('saving state to %s' % lastextensiondst) try: if crackmode == 1: pickle.dump(sipvicious.previouspassword, open( os.path.join(exportpath, 'lastpasswd.pkl'), 'wb+')) logging.debug('logged last password %s' % sipvicious.previouspassword) elif crackmode == 2: pickle.dump(sipvicious.crackargs.tell(), open( os.path.join(exportpath, 'lastpasswd.pkl'), 'wb+')) logging.debug('logged last position %s' % sipvicious.crackargs.tell()) except IOError: logging.warning('could not log the last tried password') # display results if not options.quiet: lenres = len(sipvicious.resultpasswd) if lenres > 0: logging.info("we have %s cracked users" % lenres) if (lenres < 400 and options.save is not None) or options.save is None: labels = ('Extension', 'Password') rows = list() try: for k in sipvicious.resultpasswd.keys(): rows.append((k.decode(), sipvicious.resultpasswd[k].decode())) except AttributeError: for k in sipvicious.resultpasswd.keys(): rows.append((k, sipvicious.resultpasswd[k])) print(to_string(rows, header=labels)) else: logging.warning("too many to print - use svreport for this") else: logging.warning("found nothing") end_time = datetime.now() total_time = end_time - start_time logging.info("Total time: %s" % total_time)