forked from CERTCC/tapioca
-
Notifications
You must be signed in to change notification settings - Fork 0
/
checkssl.py
executable file
·144 lines (125 loc) · 4.61 KB
/
checkssl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/env python3.8
# BEGIN LICENSE #
#
# CERT Tapioca
#
# Copyright 2018 Carnegie Mellon University. All Rights Reserved.
#
# NO WARRANTY. THIS CARNEGIE MELLON UNIVERSITY AND SOFTWARE
# ENGINEERING INSTITUTE MATERIAL IS FURNISHED ON AN "AS-IS" BASIS.
# CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
# EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED
# TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY,
# OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON
# UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO
# FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
#
# Released under a BSD (SEI)-style license, please see license.txt or
# contact [email protected] for full terms.
#
# [DISTRIBUTION STATEMENT A] This material has been approved for
# public release and unlimited distribution. Please see Copyright
# notice for non-US Government use and distribution.
# CERT(R) is registered in the U.S. Patent and Trademark Office by
# Carnegie Mellon University.
#
# DM18-0637
#
# END LICENSE #
#
# Simple script showing how to read a mitmproxy dump file
#
from __future__ import print_function
from mitmproxy import io
from mitmproxy.exceptions import FlowReadException
import pprint
import sys
import os
import color
import argparse
import json
from misc import eprint, Logger
report_output = 'ssltest.txt'
json_output = 'ssltest.json'
ssl_passed = []
ssl_failed = []
ssl_notest = []
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)
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)
if __name__ == "__main__":
main()