Ejemplo n.º 1
0
                          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('.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('.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,
Ejemplo n.º 2
0
def main():
    commandsusage = """Supported commands:\r\n
                - list:\tlists all scans\r\n
                - export:\texports the given scan to a given format\r\n
                - delete:\tdeletes the scan\r\n
                - stats:\tprint out some statistics of interest\r\n
                - search:\tsearch for a specific string in the user agent (svmap)\r\n
"""
    commandsusage += "examples:\r\n\r\n"
    commandsusage += "      %s.py list\r\n\r\n" % __prog__
    commandsusage += "      %s.py export -f pdf -o scan1.pdf -s scan1\r\n\r\n" % __prog__
    commandsusage += "      %s.py delete -s scan1\r\n\r\n" % __prog__
    usage = "%prog [command] [options]\r\n\r\n"
    usage += commandsusage
    parser = OptionParser(usage=usage, version="%prog v" +
                          str(__version__) + __GPL__)
    parser.add_option('-v', '--verbose', dest="verbose", action="count",
                      help="Increase verbosity")
    parser.add_option('-q', '--quiet', dest="quiet", action="store_true",
                      default=False,
                      help="Quiet mode")
    parser.add_option("-t", "--type", dest="sessiontype",
                      help="Type of session. This is usually either svmap, svwar or svcrack. If not set I will try to find the best match")
    parser.add_option("-s", "--session", dest="session",
                      help="Name of the session")
    parser.add_option("-f", "--format", dest="format",
                      help="Format type. Can be stdout, pdf, xml, csv or txt")
    parser.add_option("-o", "--output", dest="outputfile",
                      help="Output filename")
    parser.add_option("-n", dest="resolve", default=True,
                      action="store_false", help="Do not resolve the ip address")
    parser.add_option("-c", "--count", dest="count", default=False,
                      action="store_true", help="Used togather with 'list' command to count the number of entries")
    (options, args) = parser.parse_args()
    if len(args) < 1:
        parser.error("Please specify a command.\r\n")
        exit(1)
    command = args[0]
    from libs.svhelper import listsessions, deletesessions, createReverseLookup, dbexists
    from libs.svhelper import getsessionpath, getasciitable, outputtoxml, outputtopdf, calcloglevel
    validcommands = ['list', 'export', 'delete', 'stats', 'search']
    if command not in validcommands:
        parser.error('%s is not a supported command' % command)
        exit(1)
    logging.basicConfig(level=calcloglevel(options))
    sessiontypes = ['svmap', 'svwar', 'svcrack']
    logging.debug('started logging')
    if command == 'list':
        listsessions(options.sessiontype, count=options.count)
    if command == 'delete':
        if options.session is None:
            parser.error("Please specify a valid session.")
            exit(1)
        sessionpath = deletesessions(options.session, options.sessiontype)
        if sessionpath is None:
            parser.error(
                'Session could not be found. Make sure it exists by making use of %s.py list' % __prog__)
            exit(1)
    elif command == 'export':
        from datetime import datetime
        start_time = datetime.now()
        if options.session is None:
            parser.error("Please specify a valid session")
            exit(1)
        if options.outputfile is None and options.format not in [None, 'stdout']:
            parser.error("Please specify an output file")
            exit(1)
        tmp = getsessionpath(options.session, options.sessiontype)
        if tmp is None:
            parser.error(
                'Session could not be found. Make sure it exists by making use of %s list' % __prog__)
            exit(1)
        sessionpath, sessiontype = tmp
        resolve = False
        resdb = None
        if sessiontype == 'svmap':
            dbloc = os.path.join(sessionpath, 'resultua')
            labels = ['Host', 'User Agent']
        elif sessiontype == 'svwar':
            dbloc = os.path.join(sessionpath, 'resultauth')
            labels = ['Extension', 'Authentication']
        elif sessiontype == 'svcrack':
            dbloc = os.path.join(sessionpath, 'resultpasswd')
            labels = ['Extension', 'Password']
        if not dbexists(dbloc):
            logging.error('The database could not be found: %s' % dbloc)
            exit(1)
        db = anydbm.open(dbloc, 'r')

        if options.resolve and sessiontype == 'svmap':
            resolve = True
            labels.append('Resolved')
            resdbloc = os.path.join(sessionpath, 'resolved')
            if not dbexists(resdbloc):
                logging.info('Performing DNS reverse lookup')
                resdb = anydbm.open(resdbloc, 'c')
                createReverseLookup(db, resdb)
            else:
                logging.info('Not Performing DNS lookup')
                resdb = anydbm.open(resdbloc, 'r')

        if options.outputfile is not None:
            if options.outputfile.find('.') < 0:
                if options.format is None:
                    options.format = 'txt'
                options.outputfile += '.%s' % options.format

        if options.format in [None, 'stdout', 'txt']:
            o = getasciitable(labels, db, resdb)
            if options.outputfile is None:
                print o
            else:
                open(options.outputfile, 'w').write(o)
        elif options.format == 'xml':
            from xml.dom.minidom import Document
            doc = Document()
            node = doc.createElement(sessiontype)
            o = outputtoxml('%s report' % sessiontype, labels, db, resdb)
            open(options.outputfile, 'w').write(o)
        elif options.format == 'pdf':
            outputtopdf(options.outputfile, '%s report' %
                        sessiontype, labels, db, resdb)
        elif options.format == 'csv':
            import csv
            writer = csv.writer(open(options.outputfile, "w"))
            for k in db.keys():
                row = [k, db[k]]
                if resdb is not None:
                    if resdb.has_key(k):
                        row.append(resdb[k])
                    else:
                        row.append('N/A')
                writer.writerow(row)
        logging.info("That took %s" % (datetime.now() - start_time))
    elif command == 'stats':
        from operator import itemgetter
        import re
        if options.session is None:
            parser.error("Please specify a valid session")
            exit(1)
        if options.outputfile is None and options.format not in [None, 'stdout']:
            parser.error("Please specify an output file")
            exit(1)
        tmp = getsessionpath(options.session, options.sessiontype)
        if tmp is None:
            parser.error(
                'Session could not be found. Make sure it exists by making use of %s list' % __prog__)
            exit(1)
        sessionpath, sessiontype = tmp
        if sessiontype != 'svmap':
            parser.error('Only takes svmap sessions for now')
            exit(1)
        dbloc = os.path.join(sessionpath, 'resultua')
        if not dbexists(dbloc):
            logging.error('The database could not be found: %s' % dbloc)
            exit(1)
        db = anydbm.open(dbloc, 'r')
        useragents = dict()
        useragentconames = dict()
        for k in db.keys():
            v = db[k]
            if not useragents.has_key(v):
                useragents[v] = 0
            useragents[v] += 1
            useragentconame = re.split('[ /]', v)[0]
            if not useragentconames.has_key(useragentconame):
                useragentconames[useragentconame] = 0
            useragentconames[useragentconame] += 1

        _useragents = sorted(useragents.iteritems(),
                             key=itemgetter(1), reverse=True)
        suseragents = map(lambda x: '\t- %s (%s)' % (x[0], x[1]), _useragents)
        _useragentsnames = sorted(
            useragentconames.iteritems(), key=itemgetter(1), reverse=True)
        suseragentsnames = map(lambda x: '\t- %s (%s)' %
                               (x[0], x[1]), _useragentsnames)
        print "Total number of SIP devices found: %s" % len(db.keys())
        print "Total number of useragents: %s\r\n" % len(suseragents)
        print "Total number of useragent names: %s\r\n" % len(suseragentsnames)

        print "Most popular top 30 useragents:\r\n"
        print '\r\n'.join(suseragents[:30])
        print '\r\n\r\n'
        print "Most unpopular top 30 useragents:\r\n\t"
        print '\r\n'.join(suseragents[-30:])
        print "\r\n\r\n"
        print "Most popular top 30 useragent names:\r\n"
        print '\r\n'.join(suseragentsnames[:30])
        print '\r\n\r\n'
        print "Most unpopular top 30 useragent names:\r\n\t"
        print '\r\n'.join(suseragentsnames[-30:])
        print "\r\n\r\n"
    elif command == 'search':
        if options.session is None:
            parser.error("Please specify a valid session")
            exit(1)
        if len(args) < 2:
            parser.error('You need to specify a search string')
        searchstring = args[1]
        tmp = getsessionpath(options.session, options.sessiontype)
        if tmp is None:
            parser.error(
                'Session could not be found. Make sure it exists by making use of %s list' % __prog__)
            exit(1)
        sessionpath, sessiontype = tmp
        if sessiontype != 'svmap':
            parser.error('Only takes svmap sessions for now')
            exit(1)
        dbloc = os.path.join(sessionpath, 'resultua')
        if not dbexists(dbloc):
            logging.error('The database could not be found: %s' % dbloc)
            exit(1)
        db = anydbm.open(dbloc, 'r')
        useragents = dict()
        useragentconames = dict()
        labels = ['Host', 'User Agent']
        for k in db.keys():
            v = db[k]
            if searchstring.lower() in v.lower():
                print k + '\t' + v
Ejemplo n.º 3
0
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(','))
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
                'Session could not be found. Make sure it exists by making use of %s list'
                % __prog__)
            exit(1)
        sessionpath, sessiontype = tmp
        resolve = False
        resdb = None
        if sessiontype == 'svmap':
            dbloc = os.path.join(sessionpath, 'resultua')
            labels = ['Host', 'User Agent']
        elif sessiontype == 'svwar':
            dbloc = os.path.join(sessionpath, 'resultauth')
            labels = ['Extension', 'Authentication']
        elif sessiontype == 'svcrack':
            dbloc = os.path.join(sessionpath, 'resultpasswd')
            labels = ['Extension', 'Password']
        if not dbexists(dbloc):
            logging.error('The database could not be found: %s' % dbloc)
            exit(1)
        db = anydbm.open(dbloc, 'r')

        if options.resolve and sessiontype == 'svmap':
            resolve = True
            labels.append('Resolved')
            resdbloc = os.path.join(sessionpath, 'resolved')
            if not dbexists(resdbloc):
                logging.info('Performing DNS reverse lookup')
                resdb = anydbm.open(resdbloc, 'c')
                createReverseLookup(db, resdb)
            else:
                logging.info('Not Performing DNS lookup')
                resdb = anydbm.open(resdbloc, 'r')
Ejemplo n.º 6
0
    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.
        commandsusage = """Supported commands:\r\n
                - list:\tlists all scans\r\n
                - export:\texports the given scan to a given format\r\n
                - delete:\tdeletes the scan\r\n
                - stats:\tprint out some statistics of interest\r\n
                - search:\tsearch for a specific string in the user agent (svmap)\r\n
        """
        commandsusage += "examples:\r\n\r\n"
        commandsusage += "      %s.py list\r\n\r\n" % __prog__
        commandsusage += "      %s.py svreport export -f pdf -o scan1.pdf -s scan1\r\n\r\n" % __prog__
        commandsusage += "      %s.py svreport delete -s scan1\r\n\r\n" % __prog__
        usage = "%prog [command] [options]\r\n\r\n"
        usage += commandsusage
        # 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=usage,version="%prog v"+str(__version__))
        parser.add_option('-v', '--verbose', dest="verbose", action="count",
                          help="Increase verbosity")
        parser.add_option('-q', '--quiet', dest="quiet", action="store_true",
                          default=False,
                          help="Quiet mode")
        parser.add_option("-t", "--type", dest="sessiontype",
                        help="Type of session. This is usually either svmap, svwar or svcrack. If not set I will try to find the best match")
        parser.add_option("-s", "--session", dest="session",
                        help="Name of the session")
        parser.add_option("-f", "--format", dest="format",
                        help="Format type. Can be stdout, pdf, xml, csv or txt")
        parser.add_option("-o", "--output", dest="outputfile",
                        help="Output filename")
        parser.add_option("-n", dest="resolve", default=True,
                          action="store_false", help="Do not resolve the ip address")
        parser.add_option("-c", "--count", dest="count", default=False,
                          action="store_true", help="Used togather with 'list' command to count the number of entries")
        (options,args) = parser.parse_args()
        # Check that there is no empty arg.
        if len(args) <= 1:
                parser.error("Please specify a command.\r\n")
                exit(1)
        command = args[1]
        # Import additional modules
        from libs.svhelper import listsessions,deletesessions,createReverseLookup, dbexists
        from libs.svhelper import getsessionpath,getasciitable,outputtoxml,outputtopdf, calcloglevel
        # Create list of valid commands that can use
        validcommands = ['list','export','delete','stats','search']
        if command not in validcommands:
                parser.error('%s is not a supported command' % command)
                exit(1)
        # Does basic configuration for the logging system by creating a StreamHandler with a default
        # Formatter and adding it to the root logger. The functions debug(), info(), warning(), error() and
        # critical() will call basicConfig() automatically if no handlers are defined for the root logger.
        logging.basicConfig(level=calcloglevel(options))
        sessiontypes = ['svmap','svwar','svcrack']
        logging.debug('started logging')        
        if command == 'list':
                # Get current sessions. If they are
                listsessions(options.sessiontype,count=options.count)
        if command == 'delete':
                if options.session is None:
                        parser.error("Please specify a valid session.")
                        exit(1)
                sessionpath = deletesessions(options.session,options.sessiontype)
                if sessionpath is None:
                        parser.error('Session could not be found. Make sure it exists by making use of %s.py list' % __prog__)
                        exit(1)
        elif command == 'export':
                start_time = datetime.now()
                if options.session is None:
                        parser.error("Please specify a valid session")
                        exit(1)
                if options.outputfile is None and options.format not in [None,'stdout']:
                        parser.error("Please specify an output file")
                        exit(1)
                tmp = getsessionpath(options.session,options.sessiontype)                
                if tmp is None:
                        parser.error('Session could not be found. Make sure it exists by making use of %s list' % __prog__)
                        exit(1)
                sessionpath,sessiontype = tmp
                resolve = False
                resdb = None
                if sessiontype == 'svmap':
                        dbloc = os.path.join(sessionpath,'resultua')
                        labels = ['Host','User Agent']
                elif sessiontype == 'svwar':
                        dbloc = os.path.join(sessionpath,'resultauth')
                        labels = ['Extension','Authentication']
                elif sessiontype == 'svcrack':
                        dbloc = os.path.join(sessionpath,'resultpasswd')
                        labels = ['Extension','Password']
                if not dbexists(dbloc):
                        logging.error('The database could not be found: %s'%dbloc)
                        exit(1)
                db = anydbm.open(dbloc,'r')

                if options.resolve and sessiontype == 'svmap':
                        resolve = True
                        labels.append('Resolved')                                
                        resdbloc = os.path.join(sessionpath,'resolved')
                        if not dbexists(resdbloc):
                                logging.info('Performing DNS reverse lookup')
                                resdb = anydbm.open(resdbloc,'c')
                                createReverseLookup(db,resdb)
                        else:
                                logging.info('Not Performing DNS lookup')
                                resdb = anydbm.open(resdbloc,'r')

                if options.outputfile is not None:
                        if options.outputfile.find('.') < 0:
                                if options.format is None:
                                        options.format = 'txt'
                                options.outputfile += '.%s' % options.format

                if options.format in [None,'stdout','txt']:
                        o = getasciitable(labels,db,resdb)
                        if options.outputfile is None:
                                print o
                        else:
                                open(options.outputfile,'w').write(o)
                elif options.format == 'xml':
                        doc = Document()
                        node = doc.createElement(sessiontype)                        
                        o = outputtoxml('%s report' % sessiontype,labels,db,resdb)
                        open(options.outputfile,'w').write(o)
                elif options.format == 'pdf':
                        outputtopdf(options.outputfile,'%s report' % sessiontype,labels,db,resdb)
                elif options.format == 'csv':
                        import csv
                        writer = csv.writer(open(options.outputfile,"w"))
                        for k in db.keys():
                                row = [k,db[k]]
                                if resdb is not None:
                                        if resdb.has_key(k):
                                                row.append(resdb[k])
                                        else:
                                                row.append('N/A')
                                writer.writerow(row)
                logging.info( "That took %s" % (datetime.now() - start_time))
        elif command == 'stats':
                from operator import itemgetter
                import re                
                if options.session is None:
                        parser.error("Please specify a valid session")
                        exit(1)
                if options.outputfile is None and options.format not in [None,'stdout']:
                        parser.error("Please specify an output file")
                        exit(1)
                tmp = getsessionpath(options.session,options.sessiontype)                
                if tmp is None:
                        parser.error('Session could not be found. Make sure it exists by making use of %s list' % __prog__)
                        exit(1)
                sessionpath,sessiontype = tmp
                if sessiontype != 'svmap':
                        parser.error('Only takes svmap sessions for now')
                        exit(1)
                dbloc = os.path.join(sessionpath,'resultua')
                if not dbexists(dbloc):
                        logging.error('The database could not be found: %s'%dbloc)
                        exit(1)
                db = anydbm.open(dbloc,'r')
                useragents = dict()
                useragentconames = dict()
                for k in db.keys():
                        v = db[k]
                        if not useragents.has_key(v):
                                useragents[v] = 0
                        useragents[v]+=1
                        useragentconame = re.split('[ /]',v)[0]
                        if not useragentconames.has_key(useragentconame):
                                useragentconames[useragentconame] = 0
                        useragentconames[useragentconame] += 1
                        
                _useragents = sorted(useragents.iteritems(), key=itemgetter(1), reverse=True)
                suseragents = map(lambda x: '\t- %s (%s)' % (x[0],x[1]), _useragents)
                _useragentsnames = sorted(useragentconames.iteritems(), key=itemgetter(1), reverse=True)
                suseragentsnames = map(lambda x: '\t- %s (%s)' % (x[0],x[1]), _useragentsnames)
                print "Total number of SIP devices found: %s" % len(db.keys())
                print "Total number of useragents: %s\r\n" % len(suseragents)
                print "Total number of useragent names: %s\r\n" % len(suseragentsnames)
                
                print "Most popular top 30 useragents:\r\n"
                print '\r\n'.join(suseragents[:30])
                print '\r\n\r\n'
                print "Most unpopular top 30 useragents:\r\n\t"
                print '\r\n'.join(suseragents[-30:])
                print "\r\n\r\n"
                print "Most popular top 30 useragent names:\r\n"
                print '\r\n'.join(suseragentsnames[:30])
                print '\r\n\r\n'
                print "Most unpopular top 30 useragent names:\r\n\t" 
                print '\r\n'.join(suseragentsnames[-30:])
                print "\r\n\r\n"
        elif command == 'search':
                if options.session is None:
                        parser.error("Please specify a valid session")
                        exit(1)
                if len(args) < 2:
                        parser.error('You need to specify a search string')
                searchstring = args[1]
                tmp = getsessionpath(options.session,options.sessiontype)                
                if tmp is None:
                        parser.error('Session could not be found. Make sure it exists by making use of %s list' % __prog__)
                        exit(1)
                sessionpath,sessiontype = tmp
                if sessiontype != 'svmap':
                        parser.error('Only takes svmap sessions for now')
                        exit(1)
                dbloc = os.path.join(sessionpath,'resultua')
                if not dbexists(dbloc):
                        logging.error('The database could not be found: %s'%dbloc)
                        exit(1)
                db = anydbm.open(dbloc,'r')
                useragents = dict()
                useragentconames = dict()
                labels = ['Host','User Agent']
                for k in db.keys():
                        v = db[k]
                        if searchstring.lower() in v.lower():
                                print k+'\t'+v
Ejemplo n.º 7
0
                if tmp is None:
                        parser.error('Session could not be found. Make sure it exists by making use of %s list' % __prog__)
                        exit(1)
                sessionpath,sessiontype = tmp
                resolve = False
                resdb = None
                if sessiontype == 'svmap':
                        dbloc = os.path.join(sessionpath,'resultua')
                        labels = ['Host','User Agent']
                elif sessiontype == 'svwar':
                        dbloc = os.path.join(sessionpath,'resultauth')
                        labels = ['Extension','Authentication']
                elif sessiontype == 'svcrack':
                        dbloc = os.path.join(sessionpath,'resultpasswd')
                        labels = ['Extension','Password']
                if not dbexists(dbloc):
                        logging.error('The database could not be found: %s'%dbloc)
                        exit(1)
                db = anydbm.open(dbloc,'r')

                if options.resolve and sessiontype == 'svmap':
                        resolve = True
                        labels.append('Resolved')                                
                        resdbloc = os.path.join(sessionpath,'resolved')
                        if not dbexists(resdbloc):
                                logging.info('Performing DNS reverse lookup')
                                resdb = anydbm.open(resdbloc,'c')
                                createReverseLookup(db,resdb)
                        else:
                                logging.info('Not Performing DNS lookup')
                                resdb = anydbm.open(resdbloc,'r')
Ejemplo n.º 8
0
    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(','))
Ejemplo n.º 9
0
         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],