aboutsummaryrefslogtreecommitdiffstats
path: root/src/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'src/scripts')
-rw-r--r--src/scripts/fuzzer.xml17
-rwxr-xr-xsrc/scripts/run_tls_attacker.py138
-rw-r--r--src/scripts/tls_scanner/policy.txt19
-rw-r--r--src/scripts/tls_scanner/readme.txt5
-rwxr-xr-xsrc/scripts/tls_scanner/tls_scanner.py60
-rw-r--r--src/scripts/tls_scanner/urls.txt61
6 files changed, 300 insertions, 0 deletions
diff --git a/src/scripts/fuzzer.xml b/src/scripts/fuzzer.xml
new file mode 100644
index 000000000..9c3d86551
--- /dev/null
+++ b/src/scripts/fuzzer.xml
@@ -0,0 +1,17 @@
+<!-- This is a template for a config file for fuzzing with TLS-Attacker -->
+
+<startupCommandsHolder>
+ <serverCommand>$botan_cli </serverCommand>
+ <serverPort>$tls_port</serverPort>
+ <workflowFolder>$workflow_dir</workflowFolder>
+ <modifiedVariableTypes>TLS_CONSTANT,LENGTH,COUNT,PUBLIC_KEY,PADDING,SIGNATURE,PLAIN_PROTOCOL_MESSAGE</modifiedVariableTypes>
+ <outputFolder>/tmp/</outputFolder>
+ <startupCommandsList>
+ <startupCommands>
+ <fuzzerCommand>simple_fuzzer -connect localhost:$PORT</fuzzerCommand>
+ <serverCommandParameters>tls_server $rsa_cert $rsa_key --port=$PORT --policy=$fuzz_policy --output=/tmp/botan_output.log --error-output=/tmp/botan_error_output.log </serverCommandParameters>
+ <shortName>botan-rsa</shortName>
+ </startupCommands>
+ <!-- TODO ECDSA -->
+ </startupCommandsList>
+</startupCommandsHolder>
diff --git a/src/scripts/run_tls_attacker.py b/src/scripts/run_tls_attacker.py
new file mode 100755
index 000000000..a77364633
--- /dev/null
+++ b/src/scripts/run_tls_attacker.py
@@ -0,0 +1,138 @@
+#!/usr/bin/python
+
+import os
+import sys
+import subprocess
+import tempfile
+import time
+import random
+import optparse
+import string
+
+def run_subprocess(cmd):
+ print("Running '%s'" % (' '.join(cmd)))
+
+ proc = subprocess.Popen(cmd, bufsize=-1)
+ proc.communicate()
+
+ if proc.returncode != 0:
+ print('Running "%s" failed rc %d' % (' '.join(cmd), proc.returncode))
+ sys.exit(proc.returncode)
+
+def spawn_server(cmd):
+ print("Spawning '%s'" % (' '.join(cmd)))
+ return subprocess.Popen(cmd, bufsize=-1)#,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+
+def main(args=None):
+ if args is None:
+ args = sys.argv
+
+ parser = optparse.OptionParser()
+
+ parser.add_option('--type', default='tests',
+ help='Which TLS-Attacker tests to run (tests, policy, fuzzer)')
+ parser.add_option('--src-dir', metavar='DIR', default='./src',
+ help='Specify path to botan sources (default "%default")')
+ parser.add_option('--verbose', action='store_true',
+ help='Be noisy')
+
+ (options, args) = parser.parse_args(args)
+
+ if len(args) != 3:
+ print("Usage: %s botan_cli_exe botan_ci_tools" % (args[0]))
+ return 1
+
+ cli_exe = args[1]
+ ci_tools = args[2]
+ test_type = options.type
+ src_dir = options.src_dir
+
+ if test_type not in ['tests', 'policy', 'fuzzer']:
+ print("Unknown --type %s" % (options.test_type))
+ return 1
+
+ if os.access(cli_exe, os.X_OK) != True:
+ print("Unable to find CLI tool at %s" % (cli_exe))
+ return 1
+
+ if os.access(src_dir, os.X_OK) != True:
+ print("Unable to find src dir at %s" % (src_dir))
+ return 1
+
+ test_data_dir = os.path.join(src_dir, 'tests/data')
+
+ lax_policy_txt = os.path.join(test_data_dir, 'tls-policy/compat.txt')
+ bsi_policy_txt = os.path.join(test_data_dir, 'tls-policy/bsi.txt')
+
+ tls_attacker_dir = os.path.join(ci_tools, 'TLS-Attacker')
+ tls_attacker_jar = os.path.join(tls_attacker_dir, 'TLS-Attacker-1.2.jar')
+ tls_attacker_testsuites = os.path.join(tls_attacker_dir, 'resources/testsuite')
+ tls_fuzzer_workflows = os.path.join(tls_attacker_dir, 'resources/fuzzing/workflows')
+
+ if os.access(tls_attacker_jar, os.R_OK) != True:
+ print("Unable to find TLS-Attacker jar at %s" % (tls_attacker_jar))
+ return 1
+
+ rsa_key = tempfile.NamedTemporaryFile(prefix='rsa_key_')
+ rsa_crt = tempfile.NamedTemporaryFile(prefix='rsa_crt_')
+
+ run_subprocess([cli_exe, 'keygen', '--algo=RSA', '--params=2048', '--output=%s' % (rsa_key.name)])
+ run_subprocess([cli_exe, 'gen_self_signed', rsa_key.name, 'localhost', '--output=%s' % (rsa_crt.name)])
+
+ server_log = 'botan_log.txt'
+ server_err_log = 'botan_err_log.txt'
+
+ tls_port = random.randint(50000, 60000)
+
+ botan_server_cmd = [cli_exe, 'tls_server', rsa_crt.name, rsa_key.name,
+ '--port=%d' % (tls_port),
+ '--output='+server_log,
+ '--error-output='+server_err_log]
+
+ java_tls_attacker = ['java', '-jar', tls_attacker_jar,
+ '-loglevel', 'DEBUG' if options.verbose else 'ERROR']
+ tls_attacker_opts = ['-tls_timeout', '300', '-connect', 'localhost:%d' % (tls_port)]
+
+ if test_type == 'tests':
+ try:
+ server_process = spawn_server(botan_server_cmd +
+ ['--policy=%s' % (lax_policy_txt)])
+ time.sleep(1)
+ run_subprocess(java_tls_attacker + ['testsuite_server'] + tls_attacker_opts +
+ ['-folder', tls_attacker_testsuites])
+ finally:
+ server_process.terminate()
+ elif test_type == 'policy':
+ try:
+ server_process = spawn_server(botan_server_cmd +
+ ['--policy=%s' % (bsi_policy_txt)])
+ time.sleep(1)
+ run_subprocess(java_tls_attacker + ['testtls_server'] + tls_attacker_opts +
+ ['-policy', bsi_policy_txt])
+ finally:
+ server_process.terminate()
+ elif test_type == 'fuzzer':
+
+ template_mapping = {
+ 'rsa_key': rsa_key.name,
+ 'rsa_cert': rsa_crt.name,
+ 'botan_cli': cli_exe,
+ 'workflow_dir': tls_fuzzer_workflows,
+ 'fuzz_policy': lax_policy_txt,
+ 'tls_port': str(tls_port),
+ 'PORT': '$PORT' # this is a var for TLS-Attacker don't touch it
+ }
+
+ template_txt = open(os.path.join(src_dir, 'scripts/fuzzer.xml')).read()
+
+ config = string.Template(template_txt).substitute(template_mapping)
+
+ fuzzer_config = tempfile.NamedTemporaryFile(prefix='fuzzer_cfg_', delete=False)
+ fuzzer_config.write(config.encode('ascii'))
+ fuzzer_config.close()
+
+ run_subprocess(java_tls_attacker + ['multi_fuzzer'] +
+ ['-startup_command_file', fuzzer_config.name])
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/src/scripts/tls_scanner/policy.txt b/src/scripts/tls_scanner/policy.txt
new file mode 100644
index 000000000..a9854ee54
--- /dev/null
+++ b/src/scripts/tls_scanner/policy.txt
@@ -0,0 +1,19 @@
+allow_tls10=true
+allow_tls11=true
+allow_tls12=true
+allow_dtls10=false
+allow_dtls12=false
+
+# Camellia first just to see if there is anyone out there who will negotiate it with us
+ciphers=Camellia-128 Camellia-256 Camellia-128/GCM Camellia-256/GCM ChaCha20Poly1305 AES-256/GCM AES-128/GCM AES-256 AES-128
+signature_hashes=SHA-384 SHA-256 SHA-1
+macs=AEAD SHA-384 SHA-256 SHA-1
+key_exchange_methods=CECPQ1 ECDH DH RSA
+signature_methods=ECDSA RSA DSA
+ecc_curves=x25519 secp256r1 secp384r1
+minimum_dh_group_size=1024
+minimum_ecdh_group_size=255
+minimum_rsa_bits=2048
+
+allow_insecure_renegotiation=false
+allow_server_initiated_renegotiation=false
diff --git a/src/scripts/tls_scanner/readme.txt b/src/scripts/tls_scanner/readme.txt
new file mode 100644
index 000000000..a4754b02d
--- /dev/null
+++ b/src/scripts/tls_scanner/readme.txt
@@ -0,0 +1,5 @@
+
+Simple script to scan hosts to check basic TLS client compatability.
+
+URL list chosen mostly from large tech/software vendors, feel free to
+send suggestions.
diff --git a/src/scripts/tls_scanner/tls_scanner.py b/src/scripts/tls_scanner/tls_scanner.py
new file mode 100755
index 000000000..8fdf046ca
--- /dev/null
+++ b/src/scripts/tls_scanner/tls_scanner.py
@@ -0,0 +1,60 @@
+#!/usr/bin/python2
+
+import sys
+import time
+import subprocess
+import re
+
+def format_report(client_output):
+ version_re = re.compile('TLS (v1\.[0-2]) using ([A-Z0-9_]+)')
+
+ version_match = version_re.search(client_output)
+
+ #print client_output
+
+ if version_match:
+ return "Established %s %s" % (version_match.group(1), version_match.group(2))
+ else:
+ return client_output
+
+def scanner(args = None):
+ if args is None:
+ args = sys.argv
+
+ if len(args) != 2:
+ print "Error: Usage tls_scanner.py host_file"
+ return 2
+
+ scanners = {}
+
+ for url in [s.strip() for s in open(args[1]).readlines()]:
+ scanners[url] = subprocess.Popen(['../../../botan', 'tls_client', '--policy=policy.txt', url],
+ stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ for url in scanners.keys():
+ scanners[url].stdin.close()
+
+ report = {}
+ timeout = 10
+
+ for url in scanners.keys():
+ print "waiting for", url
+
+ for i in range(timeout):
+ scanners[url].poll()
+ if scanners[url].returncode != None:
+ break
+ #print "Waiting %d more seconds for %s" % (timeout-i, url)
+ time.sleep(1)
+
+ if scanners[url].returncode != None:
+ output = scanners[url].stdout.read() + scanners[url].stderr.read()
+ report[url] = format_report(output)
+
+ for url in report.keys():
+ print url, ":", report[url]
+
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(scanner())
diff --git a/src/scripts/tls_scanner/urls.txt b/src/scripts/tls_scanner/urls.txt
new file mode 100644
index 000000000..a5bcf349e
--- /dev/null
+++ b/src/scripts/tls_scanner/urls.txt
@@ -0,0 +1,61 @@
+adobe.com
+adp.com
+airbnb.com
+akamai.com
+amazon.com
+apache.org
+apple.com
+bbc.co.uk
+bing.com
+ca.com
+cisco.com
+citrix.com
+cloudflare.com
+craigslist.org
+dell.com
+ebay.com
+facebook.com
+github.com
+gmail.com
+google.com
+hp.com
+huawei.com
+ibm.com
+ietf.org
+intuit.com
+linkedin.com
+medium.com
+microsoft.com
+mikestoolbox.org
+nec.com
+netflix.com
+openssl.org
+oracle.com
+sgi.com
+chase.com
+bankofamerica.com
+citibank.com
+wellsfargo.com
+ebay.com
+paypal.com
+pwc.com
+randombit.net
+reddit.com
+redhat.com
+salesforce.com
+sas.com
+siemens.com
+sony.com
+stripe.com
+symantec.com
+tls.mbed.org
+twitter.com
+uber.com
+vmware.com
+whatsapp.com
+wikipedia.org
+www.iso.org
+www.lg.com
+yahoo.com
+yandex.ru
+youtube.com