-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathASN2IP.ps1
224 lines (195 loc) · 10.1 KB
/
ASN2IP.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# Finds all AS numbers associated with an organization name and returns a deduplicated list of IPv4 and IPv6 subnets owned controlled by each AS number in a text file called asn_ip_ranges.txt
param([string]$ORGANIZATION_NAME = "microsoft")
$env:ASN_ANALYTICS = $null
<#
.SYNOPSIS
Returns a list of strings representing all AS Numbers owned by an organization.
It queries the BGPView API to get the AS Numbers associated with the specified organization name.
Takes an optional param of {url} representing the organization name in a ARIN WHOIS record.
If no {url} param is provided, the organization name defaults to "microsoft".
#>
function Global:Get-ASNInfo {
param (
[switch]$Passthru,
[Parameter(Position = 0, Mandatory = $true)]
$ORGANIZATION_NAME = $global:ORGANIZATION_NAME
)
$url = "https://api.bgpview.io/search?query_term=$ORGANIZATION_NAME"
try {
$headers = @{
"Content-Type" = "application/json"
"User-Agent" = "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/112.0.0.0 safari/537.36 edg/112.0.1722.48"
"sec-ch-ua" = '"microsoft edge";v="112", "not:a-brand";v="99"'
"sec-ch-ua-mobile" = "?0"
"sec-ch-ua-platform" = "windows"
"upgrade-insecure-requests" = "1"
}
$response = Invoke-WebRequest -Uri $url -Method Get -Headers $headers -ErrorAction Stop
}
catch {
Write-Host "Request Error: Failed to retrieve information for $ORGANIZATION_NAME" -ForegroundColor Red
throw
}
Write-Host "Getting AS Numbers........." -NoNewline -ForegroundColor Yellow
$responseContent = ($response).Content
if ($response.StatusCode -eq "200") {
$asnInfo = ConvertFrom-Json $responseContent
#$asnInfo = Get-Content .\msft_asns_bgpview.json -Raw | ConvertFrom-Json
$asns = $AsnInfo.data.asns
$asnValues = @()
$data = @("Name,CountryCode,Description,ASN`n")
foreach ($asn in $asns) {
$asnValues += $asn | Select-Object asn | Select-Object -ExpandProperty asn
$data += "$($asn.name -replace ","),$($asn.country_code -replace ","),$($asn.description -replace ","),$($asn | Select-Object asn | Select-Object -ExpandProperty asn)`n"
}
$env:ASN_ANALYTICS = $data
$okFormatted = "{0,-8}" -f "Ok"
$asnsCountFormatted = "{0,4}" -f $asns.Count
Write-Host $okFormatted -NoNewline -ForegroundColor Green
Write-Host "(" -NoNewline -ForegroundColor Yellow
Write-Host $asnsCountFormatted -NoNewline -ForegroundColor Green
Write-Host ")" -ForegroundColor Yellow
}
else { Write-Host "Function Error: $($response.status) - $($response.status_message)" -ForegroundColor Red; return }
return $asnValues | Sort-Object
}
<#
.SYNOPSIS
Returns a list of strings representing all IP prefixes of a provided AS number.
It queries the RIPE NCC API to get the announced prefixes for the given AS number.
Takes an mandatory param of {asn} representing an Autonomous System (AS) number.
#>
function Global:Get-ASNPrefixes {
param (
[Parameter(Position = 0, Mandatory = $true)]
[ValidateNotNullOrEmpty()]
$ASN
)
$url = "https://stat.ripe.net/data/announced-prefixes/data.json?resource=$ASN"
$headers = @{
"Content-Type" = "application/json"
"User-Agent" = "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/112.0.0.0 safari/537.36 edg/112.0.1722.48"
"sec-ch-ua" = '"microsoft edge";v="112", "not:a-brand";v="99"'
"sec-ch-ua-mobile" = "?0"
"sec-ch-ua-platform" = "windows"
"upgrade-insecure-requests" = "1"
}
try {
$response = Invoke-WebRequest -Uri $url -Method Get -Headers $headers | Select-Object -ExpandProperty Content
}
catch {
Write-Error "Error: Failed to get response from $url"
throw
}
Write-Host "Getting AS Prefixes for...." -NoNewline -ForegroundColor Yellow
$asnPrefixInfo = $response | ConvertFrom-Json
if ($asnPrefixInfo.status -eq "ok") {
$prefixes = $asnPrefixInfo.data.prefixes
$prefixValues = @()
foreach ($prefix in $prefixes) { $prefixValues += $prefix.prefix }
}
else {
Write-Host "Error: $($asnPrefixInfo.status) - $($asnPrefixInfo.status_message)" -ForegroundColor Red
throw "Failed to get prefixes for ASN $ASN"
}
# $y = if ($null -eq $prefixValues[-1]) {0} else { $prefixValues[-1].ToString().Length }
# $z = if ($prefixValues[-1] -eq $null) { '0' } else { $prefixValues[-1].ToString().Length }
$ASNFormatted = "{0,-8}" -f $ASN
$prefixCountFormatted = "{0,4}" -f $prefixValues.Count
Write-Host "$ASNFormatted" -noNewLine -ForegroundColor Green
Write-Host "(" -NoNewline -ForegroundColor Yellow
Write-Host $prefixCountFormatted -NoNewline -ForegroundColor Green
Write-Host ")" -ForegroundColor Yellow
return $prefixValues
}
<#
.SYNOPSIS
Writes analytics to the console and as a text file named asn_analytics.txt.
Takes an mandatory param of {asn_prefixes} representing IP prefixes of one or many Autonomous System (AS) numbers.
#>
function Write-ASNAnalytics {
param (
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
$ASN_PREFIXES
)
Write-Host $Global:env:ASN_ANALYTICS
$UniqueCountryCodesCount = ($env:ASN_ANALYTICS | ConvertFrom-Csv -Delimiter ',' | Select-Object CountryCode | Select-Object -ExpandProperty CountryCode | Sort-Object -Unique).count
$UniqueASN = ($env:ASN_ANALYTICS | ConvertFrom-Csv -Delimiter ',' | Select-Object ASN | Select-Object -ExpandProperty ASN | Sort-Object { [int]$_ }) -join ','
$UniqueASNCount = ($env:ASN_ANALYTICS | ConvertFrom-Csv -Delimiter ',' | Select-Object ASN | Select-Object -ExpandProperty ASN | Sort-Object -Unique).count
$UniqueNames = ($env:ASN_ANALYTICS | ConvertFrom-Csv -Delimiter ',' | Select-Object Name | Select-Object -ExpandProperty Name | Sort-Object) -join ','
$UniqueNamesCount = ($env:ASN_ANALYTICS | ConvertFrom-Csv -Delimiter ',' | Select-Object Name | Select-Object -ExpandProperty Name | Sort-Object -Unique).count
$UniqueDescriptions = ($env:ASN_ANALYTICS | ConvertFrom-Csv -Delimiter ',' | Select-Object Description | Select-Object -ExpandProperty Description | Sort-Object) -join ','
$UniqueDescriptionsCount = ($env:ASN_ANALYTICS | ConvertFrom-Csv -Delimiter ',' | Select-Object Description | Select-Object -ExpandProperty Description | Sort-Object -Unique).count
$UniquePrefixCount = ($ASN_PREFIXES | Get-Unique | Measure-Object).Count
Write-Host ([string]::new('-' * ($host.UI.RawUI.BufferSize.Width - 1)))
Write-Host "UniqueCountryCodesCount: " -NoNewline -ForegroundColor Yellow
Write-Host $UniqueCountryCodesCount
Write-Host "UniqueASN: " -NoNewline -ForegroundColor Yellow
Write-Host $UniqueASN
Write-Host "UniqueASNCount: " -NoNewline -ForegroundColor Yellow
Write-Host $UniqueASNCount
Write-Host "UniqueNames: " -NoNewline -ForegroundColor Yellow
Write-Host $UniqueNames
Write-Host "UniqueNamesCount: " -NoNewline -ForegroundColor Yellow
Write-Host $UniqueNamesCount
Write-Host "UniqueDescriptions: " -NoNewline -ForegroundColor Yellow
Write-Host $UniqueDescriptions
Write-Host "UniqueDescriptionsCount: " -NoNewline -ForegroundColor Yellow
Write-Host $UniqueDescriptionsCount
#Write-Host "UniquePrefixes: $UniquePrefixes"
Write-Host "UniquePrefixCount: " -NoNewline -ForegroundColor Yellow
Write-Host $UniquePrefixCount
Write-Host ([string]::new('-' * ($host.UI.RawUI.BufferSize.Width - 1)))
$output = "
UniqueCountryCodesCount: $UniqueCountryCodesCount`n
UniqueASN: $UniqueASN`n
UniqueASNCount: $UniqueASNCount`n
UniqueNamesCount: $UniqueNamesCount`n
UniqueDescriptions: $UniqueDescriptions`n
UniqueDescriptionsCount: $UniqueDescriptionsCount`n
UniquePrefixes: UniquePrefixes`n
UniquePrefixCount $UniquePrefixCount`n
"
Write-Host "Exporting to: $PWD\asn_analytics.txt" -ForegroundColor Green
$output | Set-Content "$PWD\asn_analytics.txt"
}
<#
.SYNOPSIS
Runs with default vaules
#>
function Run {
param (
[Parameter(Mandatory = $false)]
$organizationName = "microsoft"
)
try {
$ASNumbers = Get-ASNInfo -ORGANIZATION_NAME $organizationName
$ASNPrefixes = @()
$ASNumbers | Sort-Object | ForEach-Object {
try {
$ASNPrefixes += Get-ASNPrefixes -asn $_
}
catch {
Write-Host "Failed to get prefixes for ASN $_. Error message: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}
}
$DeduplicatedASNPrefixes = $ASNPrefixes | Sort-Object -Unique
if ($ASNPrefixes.Count -ne $DeduplicatedASNPrefixes.Count) {
Write-Host "WARNING: $($ASNPrefixes.Count - $DeduplicatedASNPrefixes.Count) duplicate prefixes detected" -ForegroundColor Red
Write-Host "This can occur due to various reasons, such as misconfiguration, lack of coordination, or even malicious intent (e.g., BGP hijacking)" -ForegroundColor Red
}
Write-Host "`nExporting deduplicated ASN Prefixes to: " -ForegroundColor Green
Write-Host "$(Get-Location) asn_ip_ranges.txt" -ForegroundColor Green
$ASNPrefixes | Sort-Object -Unique | Set-Content "asn_ip_ranges.txt"
Write-Host "Output Analytics...." -ForegroundColor Yellow
Write-ASNAnalytics -ASN_PREFIXES $ASNPrefixes
}
catch {
Write-Host "Failed to run the script. Error message: $($_.Exception.Message)" -ForegroundColor Red
return
}
}
# -------------------------------------------------------------------------------------------------------
Run -organizationName $ORGANIZATION_NAME