Esempio n. 1
0
def main():

    parser = argparse.ArgumentParser(
        description=
        'Verify SSL certificate validation for one or more tested application')
    parser.add_argument('app_or_capture',
                        metavar='appname',
                        nargs='?',
                        help='Application name or network capture file')
    args = parser.parse_args()

    app = args.app_or_capture

    if args.app_or_capture:
        check_app(app)
    else:
        for entry in os.listdir('results'):
            if os.path.isdir(os.path.join('results', entry)):
                app = entry
                check_app(app)

        eprint('')
        eprint(color.bright('SSL test summary:'))
        eprint(color.bright(color.red(('Failed:'))))
        for app in ssl_failed:
            eprint(app)
        if ssl_notest:
            eprint(color.bright('Not tested:'))
            for app in ssl_notest:
                eprint(app)
        eprint(color.bright(color.green(('Passed:'))))
        for app in ssl_passed:
            eprint(app)
Esempio n. 2
0
def get_search_results(pkt):
    '''
    Parse through packets that match tshark filter for search
    '''
    global found, foundunenc, searchterm

    # Searches are case insensitive
    pcre = re.compile('(?i)' + searchterm)
    print(
        color.green(
            color.bright('Found match in %s packet [%d] (%s):' %
                         (pcapfile, int(pkt.number), pkt.highest_layer))))
    found = True
    foundunenc = True

    for layer in pkt.layers:
        for field_line in layer._get_all_field_lines():
            if pcre.search(field_line):
                print('%s: %s' % (layer.layer_name, field_line.rstrip()))
                print(
                    color.bright(
                        color.red('%s found in unencrypted %s traffic!' %
                                  (searchterm, pkt.highest_layer))))

    if args.verbose:
        print('----- Full packet dump begin -----')
        print(pkt)
        print('----- Full packet dump end -------')
Esempio n. 3
0
def check_app(app):
    failedssltest = False
    badrequests = []

    # Get mitmproxy log file location
    if app.endswith('.log'):
        flowfile = app
        jsonfile = '%s.%s' % (flowfile, json_output)
        if os.path.exists(flowfile):
            sys.stdout = Logger('%s.%s' % (flowfile, report_output))
    else:
        flowfile = os.path.join('results', app, 'ssltest.log')
        jsonfile = os.path.join(os.path.dirname(flowfile), json_output)
        if os.path.exists(flowfile):
            sys.stdout = Logger(os.path.join('results', app, report_output))

    if os.path.exists(flowfile):
        badsslmsgs = []

        with open(flowfile, "rb") as logfile:
            freader = io.FlowReader(logfile)
            pp = pprint.PrettyPrinter(indent=4)
            try:
                for msg in freader.stream():
                    scheme = msg.request.scheme
                    if scheme == 'https':
                        failedssltest = True
                        badsslmsgs.append(msg)
                if failedssltest:
                    ssl_failed.append(app)
                    print(
                        color.bright(
                            '%s fails to validate SSL certificates properly' %
                            app))
                    print('Offending URIs accessed:')
                    for msg in badsslmsgs:
                        method = msg.request.method
                        uri = msg.request.pretty_url
                        request = '%s %s' % (method, uri)
                        badrequests.append(request)
                        request = color.bright(color.red((request)))
                        print(request)
                else:
                    print('No HTTPS traffic detected for app %s' % app)
                    ssl_passed.append(app)
            except FlowReadException as e:
                print("Flow file corrupted: {}".format(e))

        report = {}
        report['app'] = app
        report['testtime'] = os.path.getmtime(flowfile)
        report['failedtest'] = failedssltest
        report['ssl_failed'] = badrequests

        with open(jsonfile, 'w') as fp:
            json.dump(report, fp)

    else:
        ssl_notest.append(app)
Esempio n. 4
0
def run_all(app, analyzers):
    for analyzer in analyzers:
        print(
            color.bright('----- Begin %s report for %s -----' % (analyzer, color.cyan(app))))
        subprocess.call(['./%s' % analyzer, app])
        print(
            color.bright('----- End %s report for %s -------' % (analyzer, color.cyan(app))))
        print('')
Esempio n. 5
0
def main():
    global args, searchterm

    parser = argparse.ArgumentParser(
        description='Search captured traffic for a pattern')
    parser.add_argument('app_or_capture',
                        metavar='appname',
                        help='Application name or network capture file')
    parser.add_argument('searchterm', type=str, help='String to search for')
    parser.add_argument('-v',
                        '--verbose',
                        dest='verbose',
                        action='store_true',
                        help='display packet contents')
    parser.add_argument('-m',
                        '--multi',
                        dest='multi',
                        action='store_true',
                        help='search multiple encodings')

    args = parser.parse_args()

    app = args.app_or_capture
    searchterm = args.searchterm
    appdir = os.path.join('results', app)
    search_output = get_search_outname(searchterm)
    if os.path.isdir(appdir):
        sys.stdout = Logger(os.path.join(appdir, search_output))

    if args.app_or_capture:
        # Check only one app
        # Option to use full packets perhaps specified
        if args.multi:
            check_multi(app, searchterm)
        else:
            check_app(app, searchterm)
    else:
        # Check all apps tested
        for entry in os.listdir('results'):
            if os.path.isdir(os.path.join('results', entry)):
                app = entry
                if args.multi:
                    check_multi(app, searchterm)
                else:
                    check_app(app, searchterm)
            elif os.path.isdir(os.path.join('results', entry.lower())):
                app = entry
                if args.multi:
                    check_multi(app, searchterm)
                else:
                    check_app(app, searchterm)
    print('')
    # Flush stdout log file
    sys.stdout = sys.__stdout__
    # Copy log file to universally-named one
    copy2(os.path.join(appdir, search_output),
          os.path.join(appdir, report_output))
    eprint(color.bright('Done!'))
Esempio n. 6
0
def generate_report(app, fullpacket=False, pcapfile=''):
    '''
    Print report based on collected data
    '''

    report = {}
    report['app'] = app
    report['testtime'] = os.path.getmtime(pcapfile)
    # This is an un-failable test
    report['failedtest'] = False
    report['targets'] = net.targets
    report['dnsreqs'] = net.dnsreqs

    if app.endswith('.pcap'):
        app_or_pcap = 'pcap'
        jsonfile = '%s.%s' % (app, json_output)
    else:
        app_or_pcap = 'application'
        jsonfile = os.path.join(os.path.dirname(pcapfile), 'net.json')

    print('')
    print('Summary for %s: %s' % (app_or_pcap, color.bright(color.cyan(app))))
    print('')
    print(color.bright('Hosts contacted:'))
    # For each target (unsorted)
    for target in net.targets:
        # Get protocols used
        if fullpacket:
            protos = get_protos_full(net.targets[target])
        else:
            protos = get_protos(net.targets[target])
        # Get host name
        host = net.get_hostname(target)
        protolist = ', '.join(protos)
        print('%s : %s : %s' % (color.bright('CONNECT'), host, protolist))
    print('')
    print(color.bright('DNS queries made:'))
    for dnsreq in net.dnsreqs:
        print('%s : %s' % (color.bright('LOOKUP'), dnsreq))

    with open(jsonfile, 'w') as fp:
        json.dump(report, fp)
Esempio n. 7
0
def print_header(logfile):
    global pcapfile, fullmitmfile, ssltestfile
    traffictype = ''
    logfile = os.path.basename(logfile)
    if logfile == pcapfile:
        traffictype = 'unencrypted'
    elif logfile == fullmitmfile:
        traffictype = 'protected HTTPS'
    elif logfile == ssltestfile:
        traffictype = 'UNPROTECTED HTTPS'
    print(
        color.bright('===== Search hits in %s traffic below =====' % traffictype))
Esempio n. 8
0
def main():

    parser = argparse.ArgumentParser(
        description='Run all reports for one or more tested application')
    parser.add_argument('app_or_capture', metavar='appname', nargs='?',
                        help='Application name or network capture file')
    args = parser.parse_args()

    app = args.app_or_capture

    if args.app_or_capture:
        # Check only one app
        runreports(app)
    else:
        # Check all apps tested
        for app in getapps():
            runreports(app)

    eprint(color.bright('Done!'))
Esempio n. 9
0
def generate_report(app, pcapfile=''):
    '''
    Print report based on collected data
    '''

    global sslpacketcount

    if app.endswith('.pcap'):
        app_or_pcap = 'pcap'
        jsonfile = '%s.%s' % (pcapfile, json_output)
    else:
        app_or_pcap = 'application'
        jsonfile = os.path.join(os.path.dirname(pcapfile), json_output)

    report = {}
    report['app'] = app
    report['testtime'] = os.path.getmtime(pcapfile)
    report['sslversions'] = net.sslversions
    report['requestedciphers'] = net.requestedciphers
    report['negotiatedciphers'] = net.negotiatedciphers
    report['dtlsversions'] = net.dtlsversions
    report['negotiateddtlsciphers'] = net.negotiateddtlsciphers

    seen_mandatory_ciphers = []
    seen_optional_ciphers = []
    seen_other_ciphers = []
    failedtest = False
    failedreasons = []

    print('')
    print('Summary for application: %s' % color.bright(color.cyan(app)))
    print('')

    if net.sslpacketcount > 0:
        print(color.bright('TLS/SSL protocols used:'))
        # For each target (unsorted)

        for sslversion in net.sslversions:
            if sslversion == 'TLS 1.2':
                sslversion = color.bright(color.green(sslversion))
            else:
                failedtest = True
                failedreasons.append('%s is used, rather than TLS 1.2' %
                                     sslversion)
                sslversion = color.bright(color.red(sslversion))
            print(sslversion)
            print(
                color.bright('Hosts using %s:' % color.decolorize(sslversion)))
            for host in net.sslversions[color.decolorize(sslversion)]:
                print(host)
        print('')

        for ciphersuite in net.requestedciphers:
            if ciphersuite in net.mandatory_ciphers:
                #ciphersuite = color.bright(color.green(ciphersuite))
                seen_mandatory_ciphers.append(ciphersuite)
            elif ciphersuite in net.optional_ciphers:
                #ciphersuite = color.bright(ciphersuite)
                seen_optional_ciphers.append(ciphersuite)
            else:
                #ciphersuite = color.dim(ciphersuite)
                seen_other_ciphers.append(ciphersuite)

        if len(seen_mandatory_ciphers) == 0:
            failedtest = True
            failedreasons.append('%s is not supported by client' %
                                 net.mandatory_ciphers[0])

        print(
            color.bright(
                'Observed mandatory ciphers in TLS/SSL client requests:'))
        for cipher in seen_mandatory_ciphers:
            print(color.bright(color.green(cipher)))
        report['seen_mandatory_ciphers'] = seen_mandatory_ciphers
        print('')
        print(
            color.bright(
                'Observed optional ciphers in TLS/SSL client requests:'))
        for cipher in seen_optional_ciphers:
            print(cipher)
        report['seen_optional_ciphers'] = seen_optional_ciphers
        print('')
        print(
            color.bright('Observed other ciphers in TLS/SSL client requests:'))
        for cipher in seen_other_ciphers:
            print(color.dim(cipher))
        report['seen_other_ciphers'] = seen_other_ciphers
        print('')

        print(color.bright('Negotiated TLS/SSL ciphers:'))

        for ciphersuite in net.negotiatedciphers:
            if ciphersuite in net.mandatory_ciphers:
                ciphersuite = color.bright(color.green(ciphersuite))
            elif ciphersuite in net.optional_ciphers:
                pass
                #ciphersuite = color.bright(ciphersuite)
            else:
                ciphersuite = color.dim(ciphersuite)

            print(ciphersuite)
            print(
                color.bright('Hosts using %s:' %
                             color.decolorize(ciphersuite)))
            for host in net.negotiatedciphers[color.decolorize(ciphersuite)]:
                print(host)
            print('')
        print('')
    else:
        print(color.bright(color.green('No TLS/SSL traffic seen')))
        print('')

    if net.dtlspacketcount > 0:
        print(color.bright('DTLS protocols used:'))

        # For each target (unsorted)
        for dtlsversion in net.dtlsversions:
            if dtlsversion == 'DTLS 1.2':
                dtlsversion = color.bright(color.green(dtlsversion))
            else:
                failedtest = True
                failedreasons.append('%s is used, rather than DTLS 1.2' %
                                     dtlsversion)
                dtlsversion = color.bright(color.red(dtlsversion))
            print(dtlsversion)
            print(
                color.bright('Hosts using %s:' %
                             color.decolorize(dtlsversion)))
            for host in net.dtlsversions[color.decolorize(dtlsversion)]:
                print(host)
        print('')

        report['dtlsciphers'] = net.requesteddtlsciphers
        for ciphersuite in net.requesteddtlsciphers:
            if ciphersuite in net.mandatory_ciphers:
                #ciphersuite = color.bright(color.green(ciphersuite))
                seen_mandatory_ciphers.append(ciphersuite)
            elif ciphersuite in net.optional_ciphers:
                #ciphersuite = color.bright(ciphersuite)
                seen_optional_ciphers.append(ciphersuite)
            else:
                #ciphersuite = color.dim(ciphersuite)
                seen_other_ciphers.append(ciphersuite)

        if len(seen_mandatory_ciphers) == 0:
            failedtest = True
            failedreasons.append('%s is not supported by client' %
                                 net.mandatory_ciphers[0])

        print(
            color.bright(
                'Observed mandatory ciphers in DTLS client requests:'))
        for cipher in seen_mandatory_ciphers:
            print(color.bright(color.green(cipher)))
        print('')
        report['seen_mandatory_dtls_ciphers'] = seen_mandatory_ciphers
        print(
            color.bright('Observed optional ciphers in DTLS client requests:'))
        for cipher in seen_optional_ciphers:
            print(cipher)
        print('')
        report['seen_optional_dtls_ciphers'] = seen_optional_ciphers
        print(color.bright('Observed other ciphers in DTLS client requests:'))
        for cipher in seen_other_ciphers:
            print(color.dim(cipher))
        print('')
        report['seen_other_dtls_ciphers'] = seen_other_ciphers

        print(color.bright('Negotiated DTLS ciphers:'))
        for ciphersuite in net.negotiateddtlsciphers:
            if ciphersuite in net.mandatory_ciphers:
                ciphersuite = color.bright(color.green(ciphersuite))
            elif ciphersuite in net.optional_ciphers:
                pass
                #ciphersuite = color.bright(ciphersuite)
            else:
                ciphersuite = color.dim(ciphersuite)

            print(ciphersuite)
            print(
                color.bright('Hosts using %s:' %
                             color.decolorize(ciphersuite)))
            for host in net.negotiateddtlsciphers[color.decolorize(
                    ciphersuite)]:
                print(host)
            print('')
        print('')

    else:
        print(color.bright(color.green('No DTLS traffic seen')))

    report['failedtest'] = failedtest
    report['failedreasons'] = failedreasons
    if failedtest:
        print(
            color.bright(
                color.red('App %s failed crypto checking because:' % app)))
        for reason in failedreasons:
            print(color.bright(color.red(reason)))
    else:
        print(color.bright(color.green('App %s passed crypto checking' % app)))

    # print(report)

    with open(jsonfile, 'w') as fp:
        json.dump(report, fp)
Esempio n. 10
0
def check_app(app, force=False):
    '''
    Check application based on app name in Tapioca results
    '''

    dnscacheloaded = False
    largewarned = False

    # Get pcap file location
    if app.endswith('.pcap'):
        pcapfile = app
        if os.path.exists(pcapfile):
            sys.stdout = Logger('%s.%s' % (pcapfile, report_output))
    else:
        pcapfile = os.path.join('results', app, 'tcpdump.pcap')
        if os.path.exists(pcapfile):
            sys.stdout = Logger(os.path.join('results', app, report_output))

    if os.path.exists(pcapfile):

        pcapdir = os.path.dirname(pcapfile)
        dnspkl = os.path.join(pcapdir, '.dnsmap.pkl')

        eprint(color.bright('Checking app %s...' % color.cyan(app)))

        if os.path.exists(dnspkl) and not force:
            eprint('Loading cached DNS info...')
            with open(dnspkl, 'rb') as pklhandle:
                try:
                    net.dnsmap = pickle.load(pklhandle)
                    dnscacheloaded = True
                except:
                    pass

        if not dnscacheloaded:
            if os.path.getsize(pcapfile) > 100000000:
                # Over 100MB
                eprint(
                    color.bright(
                        color.yellow(
                            'Warning: capture size is large. Please be patient.'
                        )))
                largewarned = True

            # Get captured DNS info for IP addresses
            eprint('Getting DNS info...')
            dnspackets = pyshark.FileCapture(pcapfile,
                                             keep_packets=False,
                                             display_filter='dns')
            dnspackets.apply_on_packets(net.get_dns_info, timeout=1000)
            with open(dnspkl, 'wb') as pklhandle:
                pickle.dump(net.dnsmap,
                            pklhandle,
                            protocol=pickle.HIGHEST_PROTOCOL)

        if os.path.getsize(pcapfile) > 100000000 and not largewarned:
            # Over 100MB
            eprint(
                color.bright(
                    color.yellow(
                        'Warning: capture size is large. Please be patient.')))
            largewarned = True

        sslpackets = pyshark.FileCapture(pcapfile,
                                         keep_packets=False,
                                         display_filter='ssl')

        eprint('Getting SSL info from capture...')
        # get_indexed_ssl_info(cap)
        sslpackets.apply_on_packets(net.get_ssl_info, timeout=1000)

        dtlspackets = pyshark.FileCapture(pcapfile,
                                          keep_packets=False,
                                          display_filter='dtls')

        eprint('Getting DTLS info from capture...')
        dtlspackets.apply_on_packets(net.get_dtls_info, timeout=1000)

        # Print report
        generate_report(app, pcapfile=pcapfile)

        # Reset globals
        net.clear()
Esempio n. 11
0
def check_app(app, fullpacket=False, force=False):
    '''
    Check application based on app name in Tapioca results
    '''

    dnscacheloaded = False
    targetscacheloaded = False
    largewarned = False

    # load local network from config
    net.set_local()

    # Get pcap file location
    if app.endswith('.pcap'):
        pcapfile = app
        if os.path.exists(pcapfile):
            sys.stdout = Logger('%s.%s' % (pcapfile, report_output))
    else:
        pcapfile = os.path.join('results', app, 'tcpdump.pcap')
        if os.path.exists(pcapfile):
            sys.stdout = Logger(os.path.join('results', app, report_output))

    if os.path.exists(pcapfile):

        pcapdir = os.path.dirname(pcapfile)
        dnspkl = os.path.join(pcapdir, '.dnsmap.pkl')
        targetspkl = os.path.join(pcapdir, '.targets.pkl')

        eprint(color.bright('Checking app %s...' % color.cyan(app)))

        if os.path.exists(dnspkl) and not force:
            eprint('Loading cached DNS info...')
            with open(dnspkl, 'rb') as pklhandle:
                try:
                    net.dnsmap = pickle.load(pklhandle)
                    net.dnsreqs = pickle.load(pklhandle)
                    dnscacheloaded = True
                except:
                    pass

        if not dnscacheloaded:
            if os.path.getsize(pcapfile) > 100000000:
                # Over 100MB
                eprint(
                    color.bright(
                        color.yellow(
                            'Warning: capture size is large. Please be patient.'
                        )))
                largewarned = True
            # Get captured DNS info for IP addresses
            eprint('Getting DNS info...')
            dnspackets = pyshark.FileCapture(pcapfile,
                                             keep_packets=False,
                                             display_filter='dns')
            dnspackets.apply_on_packets(net.get_dns_info, timeout=1000)
            with open(dnspkl, 'wb') as pklhandle:
                pickle.dump(net.dnsmap,
                            pklhandle,
                            protocol=pickle.HIGHEST_PROTOCOL)
                pickle.dump(net.dnsreqs,
                            pklhandle,
                            protocol=pickle.HIGHEST_PROTOCOL)

#        if os.path.exists(targetspkl) and not force:
#            eprint('Loading cached targets...')
#            with open(targetspkl, 'rb') as pklhandle:
#                try:
#                    net.targets = pickle.load(pklhandle)
#                    targetscacheloaded = True
#                except:
#                    pass

        if not targetscacheloaded:
            if fullpacket:
                packets = pyshark.FileCapture(pcapfile, keep_packets=False)
                # Get hosts contacted
                eprint('Getting hosts contacted...')
                packets.apply_on_packets(net.get_hosts_contacted_fullpacket,
                                         timeout=1000)
            else:
                packets = pyshark.FileCapture(pcapfile,
                                              keep_packets=False,
                                              only_summaries=True)
                # Get hosts contacted
                eprint('Getting hosts contacted...')
                packets.apply_on_packets(net.get_hosts_contacted, timeout=1000)


#                with open(targetspkl, 'wb') as pklhandle:
#                    pickle.dump(
# net.targets, pklhandle, protocol=pickle.HIGHEST_PROTOCOL)

# Print report
        generate_report(app, fullpacket=fullpacket, pcapfile=pcapfile)

        # Reset globals
        net.clear()
Esempio n. 12
0
def get_dtls_info(pkt):
    global dtlspacketcount, dtlsversions, negotiateddtlsciphers

    try:
        dtlspkt = pkt.dtls
        dtlspacketcount = dtlspacketcount + 1
        handshake = dtlspkt.handshake
        if handshake == 'Handshake Protocol: Client Hello':
            dtlshost = get_host_contacted(pkt)
            # print(pkt)
            maxdtlsversion = 0
            ciphersuitelist = []
            destination_host = get_host_contacted(pkt)
            for field_line in dtlspkt._get_all_field_lines():
                if field_line.startswith('\tVersion: '):
                    intdtlsversion = extract_intval(field_line)
                    if intdtlsversion > maxdtlsversion:
                        # Newer DTLS version than we've seen so far
                        maxdtlsversion = intdtlsversion
                        dtlsversion = extract_property(
                            field_line, 'Version')

                if field_line.startswith('\tCipher Suite: '):
                    ciphersuite = extract_property(
                        field_line, 'Cipher Suite')
                    if ciphersuite not in requesteddtlsciphers:
                        requesteddtlsciphers.append(ciphersuite)
                    if ciphersuite in mandatory_ciphers:
                        ciphersuite = color.bright(
                            color.green(ciphersuite))
                    elif ciphersuite in optional_ciphers:
                        ciphersuite = color.bright(ciphersuite)
                    ciphersuitelist.append(ciphersuite)
                    # print('%s: %s' %
                    #      (color.bright('Cipher suite'), ciphersuite))

            # Add host to list of hosts contacted per DTLS version
            dtlsversions = addonlynew(
                dtlsversions, dtlsversion, dtlshost)

            if str(dtlsversion) == 'DTLS 1.2':
                dtlsversion = color.green(dtlsversion)
            else:
                dtlsversion = color.red(dtlsversion)
            if args.verbose:
                print('Client request handshake with %s: %s' % (destination_host,
                                                                color.bright(dtlsversion)))
            for ciphersuite in ciphersuitelist:
                if args.verbose:
                    print('%s: %s' %
                          ('Client-supported cipher suite', ciphersuite))

        elif handshake == 'Handshake Protocol: Server Hello':
            dtlshost = get_source_host(pkt)
            #print('Server hello!')
            negotiated_ciphersuite = pkt.dtls.handshake_ciphersuite.showname
            negotiated_ciphersuite = extract_notab_property(
                negotiated_ciphersuite, 'Cipher Suite')
            # print('*** Negotiated DTLS ciphersuite: %s' %
            #      negotiated_ciphersuite)
            # if negotiated_ciphersuite not in negotiateddtlsciphers:
            #    negotiateddtlsciphers.append(negotiated_ciphersuite)
            negotiateddtlsciphers = addonlynew(
                negotiateddtlsciphers, negotiated_ciphersuite, dtlshost)
            if args.verbose:
                print('Negotiated ciphersuite with %s: %s' %
                      (dtlshost, color.bright(negotiated_ciphersuite)))
                print('***********')

    except AttributeError:
        pass
Esempio n. 13
0
def get_ssl_info(pkt):
    global sslpacketcount, sslversions, negotiatedciphers

    try:
        # Assume SSLv3 or TLS
        sslpkt = pkt.ssl
        sslpacketcount = sslpacketcount + 1
        handshake = sslpkt.handshake
        if handshake == 'Handshake Protocol: Client Hello':
            # print(pkt)
            maxsslversion = 0
            ciphersuitelist = []
            sslhost = get_host_contacted(pkt)
            for field_line in sslpkt._get_all_field_lines():
                if field_line.startswith('\tVersion: '):
                    intsslversion = extract_intval(field_line)
                    if intsslversion > maxsslversion:
                        # Newer SSL/TLS version than we've seen so far
                        maxsslversion = intsslversion
                        sslversion = extract_property(
                            field_line, 'Version')

                if field_line.startswith('\tCipher Suite: '):
                    ciphersuite = extract_property(
                        field_line, 'Cipher Suite')
                    if ciphersuite not in requestedciphers:
                        requestedciphers.append(ciphersuite)
                    if ciphersuite in mandatory_ciphers:
                        ciphersuite = color.bright(
                            color.green(ciphersuite))
                    elif ciphersuite in optional_ciphers:
                        ciphersuite = color.bright(ciphersuite)
                    ciphersuitelist.append(ciphersuite)
                    # print('%s: %s' %
                    #      (color.bright('Cipher suite'), ciphersuite))

            # Add host to list of hosts contacted per SSL version
            sslversions = addonlynew(
                sslversions, sslversion, sslhost)

            if str(sslversion) == 'TLS 1.2':
                sslversion = color.green(sslversion)
            else:
                sslversion = color.red(sslversion)
            if args.verbose:
                print('Client request handshake with %s: %s' % (sslhost,
                                                                color.bright(sslversion)))
            for ciphersuite in ciphersuitelist:
                if args.verbose:
                    print('%s: %s' %
                          ('Client-supported cipher suite', ciphersuite))

        elif handshake == 'Handshake Protocol: Server Hello':
            sslhost = get_source_host(pkt)
            #print('Server hello!')
            negotiated_ciphersuite = pkt.ssl.handshake_ciphersuite.showname
            negotiated_ciphersuite = extract_notab_property(
                negotiated_ciphersuite, 'Cipher Suite')
            # print('*** Negotiated SSL/TLS ciphersuite: %s' %
            #      negotiated_ciphersuite)
            # if negotiated_ciphersuite not in negotiatedciphers:
            #    negotiatedciphers.append(negotiated_ciphersuite)
            negotiatedciphers = addonlynew(
                negotiatedciphers, negotiated_ciphersuite, sslhost)

            if args.verbose:
                print('Negotiated ciphersuite with %s: %s' %
                      (sslhost, color.bright(negotiated_ciphersuite)))
                print('***********')

    except AttributeError:
        # SSLv2 doesn't have "handshake" structure
        try:
            sslpkt = pkt.ssl
            sslhost = get_host_contacted(pkt)
            if sslpkt.record == 'SSLv2 Record Layer: Client Hello':
                sslversion = 'SSLv2'
                if sslversion not in sslversions:
                    sslversions.append(str(sslversion))
                destination_host = get_host_contacted(pkt)
                if args.verbose:
                    print('Client request handshake with %s: %s' %
                          (destination_host, color.bright(color.red('SSLv2'))))
                for field_line in sslpkt._get_all_field_lines():
                    if field_line.startswith('\tCipher Spec: '):
                        ciphersuite = extract_property(
                            field_line, 'Cipher Spec')
                        if ciphersuite not in requestedciphers:
                            requestedciphers.append(ciphersuite)
                        if ciphersuite in mandatory_ciphers:
                            ciphersuite = color.bright(
                                color.green(ciphersuite))
                        elif ciphersuite in optional_ciphers:
                            ciphersuite = color.bright(ciphersuite)
                        if args.verbose:
                            print('%s: %s' %
                                  ('Client-supported cipher spec', ciphersuite))
            elif sslpkt.record == 'SSLv2 Record Layer: Server Hello':
                negotiated_cipherspec = pkt.ssl.handshake_cipherspec.showname
                negotiated_cipherspec = extract_notab_property(
                    negotiated_cipherspec, 'Cipher Spec')
                if negotiated_cipherspec not in negotiatedciphers:
                    negotiatedciphers.append(negotiated_cipherspec)
                if negotiated_cipherspec not in optional_ciphers and negotiated_cipherspec not in mandatory_ciphers:
                    negotiated_cipherspec = color.red(
                        negotiated_cipherspec)
                destination_host = get_source_host(pkt)
                if args.verbose:
                    print('Negotiated cipherspec with %s: %s' %
                          (destination_host, color.bright(negotiated_cipherspec)))
                    print('***********')
        except AttributeError:
            pass
Esempio n. 14
0
def check_app(app, searchterm, encoding='string'):
    '''
    Check application based on app name in Tapioca results
    '''

    global pcapfile, ssltestfile, fullmitmfile
    global found, foundunprot, foundprot, foundunenc
    ssltesttime = None
    fullmitmtime = None
    pcaptime = None
    appbase = os.path.basename(app)

    # Get pcap file location
    if appbase == ssltestfile or app == fullmitmfile:
        # Check mitmproxy log
        logfile = app
        jsonfile = '%s.%s' % (app, json_output)
        if os.path.exists(logfile):
            if appbase == ssltestfile:
                ssltesttime = os.path.getmtime(app)
            elif appbase == fullmitmfile:
                fullmitmtime = os.path.getmtime(app)
            print_header(logfile)
            print(
                color.bright('searching %s for %s (%s)') %
                (color.cyan(logfile), searchterm, encoding))
            searchmitmflow(logfile, searchterm)
            print('')
    elif appbase.endswith('.pcap'):
        # Check tcpdump pcap
        logfile = app
        jsonfile = '%s.%s' % (app, json_output)
        if os.path.exists(logfile):
            pcaptime = os.path.getmtime(app)
            print_header(logfile)
            print(
                color.bright('searching %s for %s (%s)') %
                (color.cyan(logfile), searchterm, encoding))
            searchtcpdump(logfile, searchterm)
            print('')
    else:
        # check app (all captures availabale)
        appdir = os.path.join('results', app)
        jsonfile = os.path.join(appdir, json_output)

        # app name, so check all three
        logfile = os.path.join('results', app, pcapfile)
        if os.path.exists(logfile):
            pcaptime = os.path.getmtime(logfile)
            print_header(logfile)
            print(
                color.bright('searching %s for %s (%s)') %
                (color.cyan(logfile), searchterm, encoding))
            searchtcpdump(logfile, searchterm)
            print('')

        logfile = os.path.join('results', app, ssltestfile)
        if os.path.exists(logfile):
            ssltesttime = os.path.getmtime(logfile)
            print_header(logfile)
            print(
                color.bright('searching %s for %s (%s)') %
                (color.cyan(logfile), searchterm, encoding))
            searchmitmflow(logfile, searchterm)
            print('')

        logfile = os.path.join('results', app, fullmitmfile)
        if os.path.exists(logfile):
            fullmitmtime = os.path.getmtime(logfile)
            print_header(logfile)
            print(
                color.bright('searching %s for %s (%s)') %
                (color.cyan(logfile), searchterm, encoding))
            searchmitmflow(logfile, searchterm)
            print('')

        report = {}
        report['app'] = app
        report['pcaptime'] = pcaptime
        report['ssltesttime'] = ssltesttime
        report['fullmitmtime'] = fullmitmtime
        report['searchterm'] = searchterm
        report['found'] = found
        report['foundunenc'] = foundunenc
        report['foundunprot'] = foundunprot
        report['foundprot'] = foundprot

        with open(jsonfile, 'w') as fp:
            json.dump(report, fp)
Esempio n. 15
0
def searchmitmflow(flowfile, searchterm):
    global found, foundunprot, foundprot

    # Searches are case insensitive
    pcre = re.compile('(?i)' + searchterm)

    # Create a dictionary of all of the messages in the flow
    with open(flowfile, 'rb') as logfile:
        fr = io.FlowReader(logfile)
        msgnum = 0
        flowdict = {}
        messages = []
        for msg in fr.stream():
            messagedict = {}
            responsedict = {}
            requestdict = {}

            messagedict['msgnum'] = msgnum

            requestdict['uri'] = msg.request.pretty_url
            requestdict['method'] = msg.request.method
            requestdict['scheme'] = msg.request.scheme
            requestdict['headers'] = msg.request.headers
            requestcontent = msg.request.content
            decodedcontent = decodecontent(requestcontent)
            if decodedcontent:
                # mitmproxy found a way to decode the content
                requestdict['content'] = decodedcontent
            else:
                # just take the raw bytes
                requestdict['content'] = requestcontent

            try:
                responsedict['headers'] = msg.response.headers
            except AttributeError:
                responsedict['headers'] = ''
            try:
                responsecontent = msg.response.content
            except AttributeError:
                responsecontent = ''
            try:
                decodedcontent = decodecontent(responsecontent)
                if decodedcontent:
                    # mitmproxy found a way to decode the content
                    responsedict['content'] = decodecontent(responsecontent)
                else:
                    # just take the raw bytes
                    responsedict['content'] = responsecontent

            except AttributeError:
                responsedict['content'] = ''

            messagedict['request'] = requestdict
            messagedict['response'] = responsedict
            # print(messagedict)
            messages.append(messagedict)
            msgnum = msgnum + 1
    flowdict['messages'] = messages

    # Check for matches in the flow dictionary
    for message in flowdict['messages']:
        msgnum = message['msgnum']
        for key in message:

            if key == 'msgnum':
                continue
            else:
                for value in message[key].values():
                    if pcre.search(str(value)):
                        found = True
                        print(
                            color.bright(
                                color.green(
                                    'Found match for %s in %s message [%s] field [%s]:'
                                    %
                                    (searchterm, flowfile, msgnum + 1, key))))
                        if message['request']['scheme'] == 'https':
                            if flowfile.endswith('ssltest.log'):
                                foundunprot = True
                                print(
                                    color.bright(
                                        color.red(
                                            '%s found in non-validated HTTPS traffic!'
                                            % searchterm)))
                            elif flowfile.endswith('flows.log'):
                                foundprot = True
                                color.bright(
                                    '%s found in validated HTTPS traffic' %
                                    searchterm)
                        elif message['request']['scheme'] == 'http':
                            foundunenc = True
                            print(
                                color.bright(
                                    color.red(
                                        '%s found in unencrypted HTTP traffic!'
                                        % searchterm)))
                        print(str(value))