2021-07-21 19:51:50 -04:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import re
|
|
|
|
import csv
|
|
|
|
import pprint
|
|
|
|
import requests
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
|
|
|
|
url = 'https://crt.sh/?dNSName=%25.onion&exclude=expired&match=ILIKE'
|
|
|
|
session = requests.Session()
|
|
|
|
response = session.get(url)
|
|
|
|
results = []
|
2021-11-21 22:48:15 -05:00
|
|
|
onion_re = re.compile(r'[2-7a-z]{56}\.onion(\s|$)')
|
2021-07-21 19:51:50 -04:00
|
|
|
|
|
|
|
status = response.status_code
|
|
|
|
if status != 200: raise RuntimeError('http status: {}'.format(status))
|
|
|
|
|
|
|
|
html_doc = response.text
|
|
|
|
soup = BeautifulSoup(html_doc, 'html.parser')
|
|
|
|
|
|
|
|
table = soup.find_all('table')[2]
|
|
|
|
table_rows = table.find_all('tr')
|
|
|
|
|
|
|
|
for tr in table_rows: # skip header
|
|
|
|
for br in tr.find_all("br"): br.replace_with(" ")
|
|
|
|
td = tr.find_all('td')
|
|
|
|
fields = [i.text for i in td]
|
2021-07-22 06:26:56 -04:00
|
|
|
if not fields: continue
|
2021-07-21 19:51:50 -04:00
|
|
|
result = dict()
|
|
|
|
result['id'] = fields[0]
|
|
|
|
result['at'] = fields[1]
|
|
|
|
result['nb'] = fields[2]
|
|
|
|
result['na'] = fields[3]
|
|
|
|
result['cn'] = fields[4]
|
|
|
|
result['san'] = fields[5]
|
|
|
|
result['in'] = fields[6]
|
|
|
|
results.append(result)
|
|
|
|
|
|
|
|
done = dict()
|
|
|
|
for r in results:
|
|
|
|
# pprint.pprint(r)
|
2021-07-22 06:37:56 -04:00
|
|
|
dates = 'date={0} not_before={1} not_after={2}'.format(r['at'], r['nb'], r['na'])
|
2021-07-21 19:51:50 -04:00
|
|
|
sans = r['cn'].split()
|
2021-07-22 10:15:48 -04:00
|
|
|
sans.extend(r['san'].split())
|
2021-07-22 06:26:56 -04:00
|
|
|
ca_data = [ x.strip() for x in r['in'].lower().split(',') ]
|
2021-07-22 10:15:48 -04:00
|
|
|
ca_data.append('cn=BAD OR MISSING CN FIELD IN CT LOG')
|
2021-07-22 06:26:56 -04:00
|
|
|
ca = [x for x in ca_data if x.startswith('cn=')][0][3:]
|
2021-07-21 19:51:50 -04:00
|
|
|
for san in sans:
|
|
|
|
if not onion_re.search(san): continue
|
|
|
|
if done.get(san, False): continue
|
|
|
|
done[san] = True
|
|
|
|
if re.match(r'\*', san):
|
2021-07-22 06:37:56 -04:00
|
|
|
print('* `{}`'.format(san))
|
2021-07-21 19:51:50 -04:00
|
|
|
else:
|
2021-07-22 06:37:56 -04:00
|
|
|
print('* [`{san}`](https://{san})'.format(san=san))
|
|
|
|
print(' * {0}'.format(dates))
|
|
|
|
print(' * **{0}**'.format(ca))
|