예제 #1
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)
예제 #2
0
                                  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, 'r')
                    previousip = pickle.load(f)
                    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(
예제 #3
0
파일: svmap.py 프로젝트: akalex/DevProject
                scaniter = scanrandom(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,'r')
                        previousip = pickle.load(f)
                        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')