-
Notifications
You must be signed in to change notification settings - Fork 1
/
Search-CertTransparency.ps1
127 lines (110 loc) · 3.6 KB
/
Search-CertTransparency.ps1
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
<#
@Author: Bret McDanel
.SYNOPSIS
Fetches data from the SSL Certificate Transparency list for specified domains
.DESCRIPTION
Fetches data from the SSL Certificate Transparency list for specified domains
.PARAMETER wildcard
Search for wildcard domains, eg *.foo.bar
.PARAMETER subdomain
Search for subdomains under the listed domain
.PARAMETER full
Collect all data available
.PARAMETER after
Only get certs newer than a given date
.PARAMETER days
Only get certs newer than X days
.PARAMETER domain
Array of domain to search
.EXAMPLE
# Gets all certs issued after January 1, 2022 including wildcards and subdomains
Search-CertTransparency.ps1 -domain deltadentalins.com -wildcard -subdomain -after 1/1/2022
.EXAMPLE
# Gets all certs issued less than 10 days ago for domains foo.com and bar.com
Search-CertTransparency.ps1 -domain $("foo.com", "bar.com") -days 10
#>
param (
[Switch]$wildcard = $false,
[Switch]$subdomain = $false,
[Switch]$full = $false,
[String]$after,
[Int]$days,
[Parameter(Mandatory=$true)]
[Array]$domain
)
# Free API key can be obtained at https://sslmate.com/ct_search_api/
$Token = "INSERT VALID TOKEN HERE"
$Url = "https://api.certspotter.com/v1/issuances"
# See https://sslmate.com/help/reference/ct_search_api_v1 for what these fields are
$ExpandAll = "expand=type&expand=sha256&expand=data&expand=name&expand=reason&expand=checked_at&expand=time"
$ExpandMin = "expand=dns_names&expand=issuer&expand=revocation&expand=cert"
$header = @{ Authorization = "Bearer $Token" }
# Date filtering
if ($after -and $days) {
Write-Host "You may not use both -after and -days at the same time"
break
} elseif ($PSBoundParameters.ContainsKey('after')) {
try {
$AfterDate = (Get-Date -Date $after)
} catch {
Write-Host "Invalid Date Format"
Write-Host $_
break
}
} elseif ($PSBoundParameters.ContainsKey('days')) {
try {
$AfterDate = (Get-Date).AddDays("-" + $days)
} catch {
Write-Host "Invalid Date Format"
Write-Host $_
break
}
}
# Main loop
foreach ($dom in $domain) {
write-host "Looking up" $dom
# Set request parameters
$Request = $Url + "?domain=" + $dom + "&" + $expandMin
if ($full) { $Request += "&" + $expandAll }
if ($wildcard) { $Request += "&" + "match_wildcards=true" }
if ($subdomain) { $Request += "&" + "include_subdomains=true" }
$certs = $()
$id=$null
do {
if ($null -ne $id) {
$req = $Request + "&after=" + $id
# Avoid rate limiter
Start-Sleep -Seconds 1.5
} else {
$req = $Request
}
# Make the request and set TLS 1.2 for connection method (website rejects 1.0, the default)
try {
if ($PSVERSIONTABLE.PSVersion.Major -ge 6) {
$Response = Invoke-RestMethod $req -Headers $header -SslProtocol Tls12
} else {
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
$Response = Invoke-RestMethod $req -Headers $header
}
} catch {
Write-Host "ERROR: " $_
Exit
}
$certs += $Response
$id=$Response[$Response.Count - 1].id
} while ($Response.length -gt 0)
# Filter by date
if ($null -ne $AfterDate) {
$Response = $Response | Where-Object {(Get-Date -Date $_.not_before) -gt $AfterDate}
}
# Display results
if ($full) {
$Certs | Select-Object *,@{n='Info URL';e={ "https://search.censys.io/certificates/" + ($_.cert -replace '(.*sha256=)(.*?);.*','$2') }}
} else {
$Certs | Select-Object id,
@{n='dns_names';e={ $_.dns_names -join " " }},
@{n='issuer'; e={ $_.issuer -replace '(.*O=")(.*?)".*','$2' }},
not_before, not_after, revoked,
@{n='Info URL';e={ "https://search.censys.io/certificates/" + ($_.cert -replace '(.*sha256=)(.*?);.*','$2') }}
}
}