-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathIMDSSample.ps1
87 lines (79 loc) · 2.66 KB
/
IMDSSample.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
$ImdsServer = "http://169.254.169.254"
$InstanceEndpoint = $ImdsServer + "/metadata/instance"
$AttestedEndpoint = $ImdsServer + "/metadata/attested/document"
$NonceValue = "123456"
# Use of -NoProxy requires use of PowerShell V6 or greater. If you use an older version of PowerShell,
# consider using examples like:
#
# $request = [System.Net.WebRequest]::Create("http://169.254.169.254/metadata/instance?api-version=2019-02-01")
# $request.Proxy = [System.Net.WebProxy]::new()
# $request.Headers.Add("Metadata","True")
# $request.GetResponse()
#
# or:
#
# $Proxy=New-object System.Net.WebProxy
# $WebSession=new-object Microsoft.PowerShell.Commands.WebRequestSession
# $WebSession.Proxy=$Proxy
# Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance?api-version=2021-02-01" -WebSession $WebSession
function Query-InstanceEndpoint
{
$uri = $InstanceEndpoint + "?api-version=2021-02-01"
$result = Invoke-RestMethod -Method GET -NoProxy -Uri $uri -Headers @{"Metadata"="True"}
return $result
}
function Query-AttestedEndpoint
{
$uri = $AttestedEndpoint + "?api-version=2021-02-01&nonce=" + $NonceValue
$result = Invoke-RestMethod -Method GET -NoProxy -Uri $uri -Headers @{"Metadata"="True"}
return $result
}
function Parse-AttestedResponse
{
param
(
[PSObject]$response
)
$signature = $response.signature
Validate-AttestedCertificate $signature
Validate-AttestedData $signature
}
function Validate-AttestedCertificate
{
param
(
[string]$signature
)
$decoded = [System.Convert]::FromBase64String($signature)
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]($decoded)
$chain = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Chain
$result = $chain.Build($cert)
foreach($element in $chain.ChainElements)
{
$element.Certificate | Format-List *
}
}
function Validate-AttestedData
{
param
(
[string]$signature
)
$decoded = [System.Convert]::FromBase64String($signature)
$signedCms = New-Object -TypeName System.Security.Cryptography.Pkcs.SignedCms
$signedCms.Decode($decoded);
$content = [System.Text.Encoding]::UTF8.GetString($signedCms.ContentInfo.Content)
Write-Host "Attested data: " $content
$json = $content | ConvertFrom-Json
$nonce = $json.nonce
if($nonce.Equals($NonceValue))
{
Write-Host "Nonce values match"
}
}
# Make Instance call and print the response
$result = Query-InstanceEndpoint
$result | ConvertTo-JSON -Depth 99
# Make Attested call and parse the response
$result = Query-AttestedEndpoint
Parse-AttestedResponse $result