2015-01-31 17:24:31 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#
|
|
|
|
# Tool to parse output of ssldump (not compiled with OpenSSL) to dump raw certificate
|
|
|
|
#
|
|
|
|
# Software is free software released under the GNU General Public License version 3 and later
|
|
|
|
#
|
|
|
|
# Copyright (c) 2015 Alexandre Dulaunoy - a@foo.be
|
|
|
|
|
|
|
|
import fileinput
|
|
|
|
import re
|
|
|
|
import binascii
|
|
|
|
import OpenSSL
|
2015-02-01 12:16:30 +00:00
|
|
|
import argparse
|
2015-02-02 06:38:17 +00:00
|
|
|
import json
|
2015-02-02 07:10:44 +00:00
|
|
|
import base64
|
2015-02-01 12:16:30 +00:00
|
|
|
|
|
|
|
argParser = argparse.ArgumentParser(description='Extract certificate to PEM format from an ssldump output')
|
2015-02-01 13:03:16 +00:00
|
|
|
argParser.add_argument('-v', default=False, action='store_true', help='Verbose output')
|
2015-02-02 07:10:44 +00:00
|
|
|
argParser.add_argument('-f', default=False, action='store_true', help='CSV format - IP, certificate fingerprint, CN (scans.io host format)')
|
|
|
|
argParser.add_argument('-s', default=False, action='store_true', help='CSV format - certificate fingerprint, base64 DER encoded certificate (scans.io certs format)')
|
2015-02-02 06:38:17 +00:00
|
|
|
argParser.add_argument('-j', default=False, action='store_true', help='Dump JSON object per certificate')
|
2015-02-01 12:16:30 +00:00
|
|
|
argParser.add_argument('-r', default='-', help='Read from a file, default is stdin')
|
|
|
|
args = argParser.parse_args()
|
2015-01-31 17:24:31 +00:00
|
|
|
|
|
|
|
cert = None
|
|
|
|
certstring = ""
|
2015-02-02 06:38:17 +00:00
|
|
|
c = {}
|
2015-02-01 12:04:27 +00:00
|
|
|
certtag = re.compile('^\s+Certificate\s*$')
|
|
|
|
certtagend = re.compile('^\S+')
|
2015-02-01 13:32:25 +00:00
|
|
|
ipv4re = '\d+\.\d+\.\d+\.\d+'
|
|
|
|
flowre = 'New TCP connection #(\d+): ('+ipv4re+')\(\d+\) <-> ('+ipv4re+')\((\d+)\)'
|
|
|
|
flow = re.compile(flowre)
|
2015-02-01 12:16:30 +00:00
|
|
|
for l in fileinput.input(args.r):
|
2015-02-01 12:04:27 +00:00
|
|
|
if certtag.match(l):
|
2015-01-31 17:24:31 +00:00
|
|
|
cert = True
|
|
|
|
continue
|
2015-02-01 12:04:27 +00:00
|
|
|
elif certtagend.match(l):
|
2015-01-31 17:24:31 +00:00
|
|
|
cert = None
|
2015-02-01 13:32:25 +00:00
|
|
|
if flow.search(l):
|
|
|
|
m = flow.match(l)
|
2015-02-01 13:41:15 +00:00
|
|
|
if m is not None:
|
2015-02-02 06:38:17 +00:00
|
|
|
c['session'] = m.group(1)
|
|
|
|
c['srcip'] = m.group(2)
|
|
|
|
c['dstip'] = m.group(3)
|
|
|
|
c['dstport'] = m.group(4)
|
2015-01-31 17:24:31 +00:00
|
|
|
|
|
|
|
if (cert is True):
|
|
|
|
certstring += l.rstrip('\n')
|
|
|
|
|
|
|
|
if ((cert is None) and (len(certstring) > 0)):
|
|
|
|
y = re.sub(" ", "", certstring).split('=')
|
2015-04-22 15:08:28 +00:00
|
|
|
a = y[1].split('certificate')[0]
|
2015-04-22 15:04:25 +00:00
|
|
|
try:
|
|
|
|
dercert = binascii.unhexlify(a)
|
|
|
|
except TypeError:
|
|
|
|
continue
|
2015-04-24 06:08:27 +00:00
|
|
|
try:
|
|
|
|
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, dercert)
|
|
|
|
except OpenSSL.crypto.Error:
|
|
|
|
continue
|
|
|
|
|
2015-02-02 06:38:17 +00:00
|
|
|
c['fp'] = x509.digest('sha1').replace(':','').lower()
|
2015-02-01 13:03:16 +00:00
|
|
|
if args.v:
|
2015-02-02 06:38:17 +00:00
|
|
|
print "("+c['session']+") "+c['srcip']+"<->"+c['dstip']+":"+c['dstport']
|
2015-04-22 15:04:25 +00:00
|
|
|
Issuer = x509.get_issuer().CN
|
|
|
|
if Issuer is not None:
|
|
|
|
print "Issuer: "+ Issuer
|
|
|
|
else:
|
|
|
|
print "Issuer: None"
|
|
|
|
CN = x509.get_subject().CN
|
|
|
|
if CN is not None:
|
|
|
|
print "CN: "+ CN
|
|
|
|
else:
|
|
|
|
print "Issuer: None"
|
2015-02-02 06:38:17 +00:00
|
|
|
c['pem'] = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, x509)
|
|
|
|
if args.j:
|
|
|
|
print (json.dumps(c))
|
|
|
|
elif args.f:
|
2015-04-23 11:59:00 +00:00
|
|
|
subject = x509.get_subject().CN
|
|
|
|
if subject is None:
|
|
|
|
subject = ""
|
2015-04-23 12:00:43 +00:00
|
|
|
print (c['dstip']+","+c['fp']+","+subject)
|
2015-02-02 07:10:44 +00:00
|
|
|
elif args.s:
|
|
|
|
print (c['fp']+","+base64.standard_b64encode(dercert))
|
2015-02-02 06:17:44 +00:00
|
|
|
else:
|
2015-02-02 06:38:17 +00:00
|
|
|
print (c['pem'])
|
2015-01-31 17:24:31 +00:00
|
|
|
certstring = ""
|
|
|
|
y = ""
|