logging.error(err) exit(1) portrange = getRange(options.port) if options.randomize: scanrandomstore = '.sipviciousrandomtmp' resumescan = False if options.save is not None: scanrandomstore = os.path.join(exportpath, 'random') resumescan = True scaniter = scanrandom(map(getranges, args), portrange, options.method.split(','), randomstore=scanrandomstore, resume=resumescan) else: scaniter = scanlist(iprange, portrange, options.method.split(',')) else: if len(args) < 1: parser.error('Provide at least one target') exit(1) logging.debug('parsing range of ports: %s' % options.port) portrange = getRange(options.port) if options.randomize: scanrandomstore = '.sipviciousrandomtmp' resumescan = False if options.save is not None: scanrandomstore = os.path.join(exportpath, 'random') resumescan = True scaniter = scanrandom(map(getranges, args), portrange, options.method.split(','),
def main(): usage = "usage: %prog [options] host1 host2 hostrange\r\n" usage += 'Scans for SIP devices on a given network\r\n\r\n' usage += "examples:\r\n\r\n" usage += "%prog 10.0.0.1-10.0.0.255 " usage += "172.16.131.1 sipvicious.org/22 10.0.1.1/24" usage += "1.1.1.1-20 1.1.2-20.* 4.1.*.*\r\n\r\n" usage += "%prog -s session1 --randomize 10.0.0.1/8\r\n\r\n" usage += "%prog --resume session1 -v\r\n\r\n" usage += "%prog -p5060-5062 10.0.0.3-20 -m INVITE\r\n\r\n" parser = OptionParser(usage, version="%prog v" + str(__version__) + __GPL__) parser.add_option( "-p", "--port", dest="port", default="5060", help= "Destination port or port ranges of the SIP device - eg -p5060,5061,8000-8100", metavar="PORT") parser = standardoptions(parser) parser = standardscanneroptions(parser) parser.add_option("--randomscan", dest="randomscan", action="store_true", default=False, help="Scan random IP addresses") parser.add_option( "-i", "--input", dest="input", help= "Scan IPs which were found in a previous scan. Pass the session name as the argument", metavar="scan1") parser.add_option( "-I", "--inputtext", dest="inputtext", help= "Scan IPs from a text file - use the same syntax as command line but with new lines instead of commas. Pass the file name as the argument", metavar="scan1") parser.add_option( "-m", "--method", dest="method", help="Specify the request method - by default this is OPTIONS.", default='OPTIONS') parser.add_option("-d", "--debug", dest="printdebug", help="Print SIP messages received", default=False, action="store_true") parser.add_option( "--first", dest="first", help= "Only send the first given number of messages (i.e. usually used to scan only X IPs)", type="long") parser.add_option("-e", "--extension", dest="extension", default='100', help="Specify an extension - by default this is not set") parser.add_option( "--randomize", dest="randomize", action="store_true", default=False, help="Randomize scanning instead of scanning consecutive ip addresses") parser.add_option("--srv", dest="srvscan", action="store_true", default=False, help="Scan the SRV records for SIP on the destination domain name." \ "The targets have to be domain names - example.org domain1.com") parser.add_option('--fromname', dest="fromname", default="sipvicious", help="specify a name for the from header") parser.add_option('-6', '--ipv6', dest="ipv6", action='store_true', help="scan an IPv6 address") (options, args) = parser.parse_args() exportpath = None 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.basicConfig(level=calcloglevel(options)) logging.debug('started logging') scanrandomstore = None if options.input is not None: db = os.path.join(os.path.expanduser('~'), '.sipvicious', __prog__, options.input, 'resultua') if dbexists(db): scaniter = scanfromdb(db, options.method.split(',')) else: logging.error( "the session name does not exist. Please use svreport to list existing scans" ) exit(1) elif options.randomscan: logging.debug('making use of random scan') logging.debug('parsing range of ports: %s' % options.port) portrange = getRange(options.port) internetranges = [[16777216, 167772159], [184549376, 234881023], [251658240, 2130706431], [2147549184, 2851995647], [2852061184, 2886729727], [2886795264, 3221159935], [3221226240, 3227017983], [3227018240, 3232235519], [3232301056, 3323068415], [3323199488, 3758096127]] scanrandomstore = '.sipviciousrandomtmp' resumescan = False if options.save is not None: scanrandomstore = os.path.join(exportpath, 'random') resumescan = True scaniter = scanrandom(internetranges, portrange, options.method.split(','), randomstore=scanrandomstore, resume=resumescan) elif options.inputtext: logging.debug('Using IP addresses from input text file') try: f = open(options.inputtext, 'r') args = f.readlines() f.close() except IOError: logging.critical('Could not open %s' % options.inputtext) exit(1) args = list(map(lambda x: x.strip(), args)) args = [x for x in args if len(x) > 0] logging.debug('ip addresses %s' % args) try: iprange = ip4range(*args) except ValueError as err: logging.error(err) exit(1) portrange = getRange(options.port) if options.randomize: scanrandomstore = '.sipviciousrandomtmp' resumescan = False if options.save is not None: scanrandomstore = os.path.join(exportpath, 'random') resumescan = True scaniter = scanrandom(list(map(getranges, args)), portrange, options.method.split(','), randomstore=scanrandomstore, resume=resumescan) else: scaniter = scanlist(iprange, portrange, options.method.split(',')) else: if len(args) < 1: parser.error('Provide at least one target') exit(1) logging.debug('parsing range of ports: %s' % options.port) portrange = getRange(options.port) if options.randomize: scanrandomstore = '.sipviciousrandomtmp' resumescan = False if options.save is not None: scanrandomstore = os.path.join(exportpath, 'random') resumescan = True scaniter = scanrandom(list(map(getranges, args)), portrange, options.method.split(','), randomstore=scanrandomstore, resume=resumescan) elif options.srvscan: logging.debug("making use of SRV records") scaniter = getTargetFromSRV(args, options.method.split(',')) else: if options.resume is not None: lastipsrc = os.path.join(exportpath, 'lastip.pkl') try: f = open(lastipsrc, 'rb') previousip = pickle.load(f, encoding='bytes') f.close() except IOError: logging.critical('Could not read from %s' % lastipsrc) exit(1) logging.debug('Previous args: %s' % args) args = resumeFromIP(previousip, args) logging.debug('New args: %s' % args) logging.info('Resuming from %s' % previousip) if options.ipv6: scaniter = scanlist(ip6range(*args), portrange, options.method.split(',')) else: # normal consecutive scan try: iprange = ip4range(*args) except ValueError as err: logging.error(err) exit(1) scaniter = scanlist(iprange, portrange, options.method.split(',')) 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+')) try: options.extension except AttributeError: options.extension = None 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 = DrinkOrSip( scaniter, selecttime=options.selecttime, compact=options.enablecompact, localport=options.localport, externalip=options.externalip, bindingip=options.bindingip, sessionpath=exportpath, extension=options.extension, printdebug=options.printdebug, first=options.first, fromname=options.fromname, ipv6=options.ipv6, ) start_time = datetime.now() logging.info("start your engines") try: try: sipvicious.start() except AssertionError as err: logging.critical(err) exit(1) if exportpath is not None: open(os.path.join(exportpath, 'closed'), 'w').close() except KeyboardInterrupt: logging.warning('caught your control^c - quiting') pass except Exception as err: if options.reportBack: logging.critical( "Got unhandled exception : sending report to author") 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.nextip is not None and options.randomize is False and options.randomscan is False: lastipdst = os.path.join(exportpath, 'lastip.pkl') logging.debug('saving state to %s' % lastipdst) try: f = open(lastipdst, 'wb+') pickle.dump(sipvicious.nextip, f) f.close() except OSError: logging.warning('Could not save state to %s' % lastipdst) elif options.save is None: if scanrandomstore is not None: #if options.randomize or options.randomscan: try: logging.debug('removing %s' % scanrandomstore) os.unlink(scanrandomstore) except OSError: logging.warning('could not remove %s' % scanrandomstore) pass # display results if not options.quiet: lenres = len(sipvicious.resultua) if lenres > 0: logging.info("we have %s devices" % lenres) if (lenres < 400 and options.save is not None) or options.save is None: width = 60 labels = ('SIP Device', 'User Agent', 'Fingerprint') rows = list() try: for k in sipvicious.resultua.keys(): rows.append( (k.decode(), sipvicious.resultua[k].decode(), sipvicious.resultfp[k].decode())) except AttributeError: for k in sipvicious.resultua.keys(): rows.append((k, sipvicious.resultua[k], sipvicious.resultfp[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(self): #Here is the main function of the class. #Note that it's just a name unlike java... #See below for the entry point of the program. from optparse import OptionParser from datetime import datetime import anydbm import os from libs.svhelper import standardoptions, standardscanneroptions, calcloglevel from sys import exit import logging usage = "usage: %prog [options] host1 host2 hostrange\r\n" usage += 'Scans for SIP devices on a given network\r\n\r\n' usage += "examples:\r\n\r\n" usage += "%prog 10.0.0.1-10.0.0.255 " usage += "172.16.131.1 sipvicious.org/22 10.0.1.1/24" usage += "1.1.1.1-20 1.1.2-20.* 4.1.*.*\r\n\r\n" usage += "%prog svmap -s session1 --randomize 10.0.0.1/8\r\n\r\n" usage += "%prog svmap --resume session1 -v\r\n\r\n" usage += "%prog svmap -p5060-5062 10.0.0.3-20 -m INVITE\r\n\r\n" # Parse arguments. # The OptionParser constructor has no required arguments, but a number of optional keyword arguments. # You should always pass them as keyword arguments, i.e. do not rely on the order in which the arguments are declared. # More about this method of parsing, see there http://docs.python.org/2/library/optparse.html#optparse.OptionParser parser = OptionParser(usage, version="%prog v"+str(__version__)) parser = standardoptions(parser) parser = standardscanneroptions(parser) parser.add_option("--randomscan", dest="randomscan", action="store_true", default=False, help="Scan random IP addresses") parser.add_option("-i", "--input", dest="input", help="Scan IPs which were found in a previous scan. Pass the session name as the argument", metavar="scan1") parser.add_option("-I", "--inputtext", dest="inputtext", help="Scan IPs from a text file - use the same syntax as command line but with new lines instead of commas. Pass the file name as the argument", metavar="scan1") parser.add_option("-m", "--method", dest="method", help="Specify the request method - by default this is OPTIONS.", default='OPTIONS' ) parser.add_option("-d", "--debug", dest="printdebug", help="Print SIP messages received", default=False, action="store_true" ) parser.add_option("--first", dest="first", help="Only send the first given number of messages (i.e. usually used to scan only X IPs)", type="long", ) parser.add_option("-e", "--extension", dest="extension", default='100', help="Specify an extension - by default this is not set") parser.add_option("--randomize", dest="randomize", action="store_true", default=False, help="Randomize scanning instead of scanning consecutive ip addresses") parser.add_option("--srv", dest="srvscan", action="store_true", default=False, help="Scan the SRV records for SIP on the destination domain name." \ "The targets have to be domain names - example.org domain1.com") parser.add_option('--fromname',dest="fromname", default="sipvicious", help="specify a name for the from header") (options, args) = parser.parse_args() from libs.svhelper import getRange, scanfromfile, scanlist, scanrandom, getranges,\ ip4range, resumeFromIP, scanfromdb, dbexists, getTargetFromSRV exportpath = None if options.resume is not None: exportpath = os.path.join('.sipvicious',__prog__,options.resume) if os.path.exists(os.path.join(exportpath,'closed')): # Logs a message with level ERROR on the root logger. 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 # Read a string from the open file object file and interpret it as a pickle data stream, # reconstructing and returning the original object hierarchy. This is equivalent to Unpickler(file).load(). # More about pickle http://docs.python.org/2/library/pickle.html options,args = pickle.load(open(optionssrc,'r')) options.resume = previousresume options.verbose = previousverbose elif options.save is not None: exportpath = os.path.join('.sipvicious',__prog__,options.save) # Does basic configuration for the logging system by creating a StreamHandler with a default Formatter and # adding it to the root logger. logging.basicConfig(level=calcloglevel(options)) logging.debug('started logging') scanrandomstore = None if options.input is not None: db = os.path.join('.sipvicious',__prog__,options.input,'resultua') if dbexists(db): scaniter = scanfromdb(db,options.method.split(',')) else: logging.error("the session name does not exist. Please use svreport to list existing scans") exit(1) # Create random scan elif options.randomscan: logging.debug('making use of random scan') logging.debug('parsing range of ports: %s' % options.port) portrange = getRange(options.port) internetranges =[[16777216,167772159], [184549376,234881023], [251658240,2130706431], [2147549184L,2851995647L], [2852061184L,2886729727L], [2886795264L,3221159935L], [3221226240L,3227017983L], [3227018240L,3232235519L], [3232301056L,3323068415L], [3323199488L,3758096127L] ] scanrandomstore = '.sipviciousrandomtmp' resumescan = False if options.save is not None: scanrandomstore = os.path.join(exportpath,'random') resumescan = True # Make a scan scaniter = scanrandom( internetranges, portrange, options.method.split(','), randomstore=scanrandomstore, resume=resumescan ) elif options.inputtext: logging.debug('Using IP addresses from input text file') try: # Open for reading. Should contains list of IPs f = open(options.inputtext,'r') # Read one entire line from the file. args = f.readlines() # Close file f.close() except IOError: logging.critical('Could not open %s' % options.inputtext) exit(1) args = map(lambda x: x.strip(), args) args = filter(lambda x: len(x) > 0, args) logging.debug('ip addresses %s' % args) try: iprange = ip4range(*args) except ValueError,err: logging.error(err) exit(1) # Create range of port portrange = getRange(options.port) if options.randomize: scanrandomstore = '.sipviciousrandomtmp' resumescan = False if options.save is not None: scanrandomstore = os.path.join(exportpath,'random') resumescan = True # Make a scan scaniter = scanrandom(map(getranges,args),portrange,options.method.split(','),randomstore=scanrandomstore,resume=resumescan) else: # Make a scan from a list scaniter = scanlist(iprange,portrange,options.method.split(','))
def main(): usage = "usage: %prog [options] host1 host2 hostrange\r\n" usage += 'Scans for SIP devices on a given network\r\n\r\n' usage += "examples:\r\n\r\n" usage += "%prog 10.0.0.1-10.0.0.255 " usage += "172.16.131.1 sipvicious.org/22 10.0.1.1/24" usage += "1.1.1.1-20 1.1.2-20.* 4.1.*.*\r\n\r\n" usage += "%prog -s session1 --randomize 10.0.0.1/8\r\n\r\n" usage += "%prog --resume session1 -v\r\n\r\n" usage += "%prog -p5060-5062 10.0.0.3-20 -m INVITE\r\n\r\n" parser = OptionParser(usage, version="%prog v" + str(__version__) + __GPL__) parser = standardoptions(parser) parser = standardscanneroptions(parser) parser.add_option("--randomscan", dest="randomscan", action="store_true", default=False, help="Scan random IP addresses") parser.add_option( "-i", "--input", dest="input", help= "Scan IPs which were found in a previous scan. Pass the session name as the argument", metavar="scan1") parser.add_option( "-I", "--inputtext", dest="inputtext", help= "Scan IPs from a text file - use the same syntax as command line but with new lines instead of commas. Pass the file name as the argument", metavar="scan1") parser.add_option( "-m", "--method", dest="method", help="Specify the request method - by default this is OPTIONS.", default='OPTIONS') parser.add_option("-d", "--debug", dest="printdebug", help="Print SIP messages received", default=False, action="store_true") parser.add_option( "--first", dest="first", help= "Only send the first given number of messages (i.e. usually used to scan only X IPs)", type="long", ) parser.add_option("-e", "--extension", dest="extension", default='100', help="Specify an extension - by default this is not set") parser.add_option( "--randomize", dest="randomize", action="store_true", default=False, help="Randomize scanning instead of scanning consecutive ip addresses") parser.add_option("--srv", dest="srvscan", action="store_true", default=False, help="Scan the SRV records for SIP on the destination domain name." \ "The targets have to be domain names - example.org domain1.com") parser.add_option('--fromname', dest="fromname", default="sipvicious", help="specify a name for the from header") parser.add_option('--crashandburn', dest="crashandburn", action="store_true", default=False) (options, args) = parser.parse_args() exportpath = None 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, 'r')) options.resume = previousresume options.verbose = previousverbose elif options.save is not None: exportpath = os.path.join(os.path.expanduser('~'), '.sipvicious', __prog__, options.save) logging.basicConfig(level=calcloglevel(options)) logging.debug('started logging') scanrandomstore = None if options.input is not None: db = os.path.join(os.path.expanduser('~'), '.sipvicious', __prog__, options.input, 'resultua') if dbexists(db): scaniter = scanfromdb(db, options.method.split(',')) else: logging.error( "the session name does not exist. Please use svreport to list existing scans" ) exit(1) elif options.randomscan: logging.debug('making use of random scan') logging.debug('parsing range of ports: %s' % options.port) portrange = getRange(options.port) internetranges = [[16777216, 167772159], [184549376, 234881023], [251658240, 2130706431], [2147549184L, 2851995647L], [2852061184L, 2886729727L], [2886795264L, 3221159935L], [3221226240L, 3227017983L], [3227018240L, 3232235519L], [3232301056L, 3323068415L], [3323199488L, 3758096127L]] scanrandomstore = '.sipviciousrandomtmp' resumescan = False if options.save is not None: scanrandomstore = os.path.join(exportpath, 'random') resumescan = True scaniter = scanrandom(internetranges, portrange, options.method.split(','), randomstore=scanrandomstore, resume=resumescan) elif options.inputtext: logging.debug('Using IP addresses from input text file') try: f = open(options.inputtext, 'r') args = f.readlines() f.close() except IOError: logging.critical('Could not open %s' % options.inputtext) exit(1) args = map(lambda x: x.strip(), args) args = filter(lambda x: len(x) > 0, args) logging.debug('ip addresses %s' % args) try: iprange = ip4range(*args) except ValueError, err: logging.error(err) exit(1) portrange = getRange(options.port) if options.randomize: scanrandomstore = '.sipviciousrandomtmp' resumescan = False if options.save is not None: scanrandomstore = os.path.join(exportpath, 'random') resumescan = True scaniter = scanrandom(map(getranges, args), portrange, options.method.split(','), randomstore=scanrandomstore, resume=resumescan) else: scaniter = scanlist(iprange, portrange, options.method.split(','))
f.close() except IOError: logging.critical('Could not read from %s' % lastipsrc) exit(1) logging.debug('Previous args: %s' % args) args = resumeFromIP(previousip,args) logging.debug('New args: %s' % args) logging.info('Resuming from %s' % previousip) # normal consecutive scan try: iprange = ip4range(*args) except ValueError,err: logging.error(err) exit(1) scaniter = scanlist(iprange,portrange,options.method.split(',')) if options.save is not None: if options.resume is None: exportpath = os.path.join('.sipvicious',__prog__,options.save) if os.path.exists(exportpath): logging.warn('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=0700) 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,'w'))