forked from openssh/openssh-portable
-
Notifications
You must be signed in to change notification settings - Fork 371
Expand file tree
/
Copy pathinstall-sshd.ps1
More file actions
175 lines (150 loc) · 7.74 KB
/
install-sshd.ps1
File metadata and controls
175 lines (150 loc) · 7.74 KB
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
# @manojampalam - authored initial script
# @friism - Fixed issue with invalid SDDL on Set-Acl
# @manojampalam - removed ntrights.exe dependency
# @bingbing8 - removed secedit.exe dependency
# @tessgauthier - added permissions check for %programData%/ssh
# @tessgauthier - added update to system path for scp/sftp discoverability
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param ()
Set-StrictMode -Version 2.0
$ErrorActionPreference = 'Stop'
if (!([bool]([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")))
{
throw "You must be running as an administrator, please restart as administrator"
}
$scriptpath = $MyInvocation.MyCommand.Path
$scriptdir = Split-Path $scriptpath
$sshdpath = Join-Path $scriptdir "sshd.exe"
$sshagentpath = Join-Path $scriptdir "ssh-agent.exe"
$etwman = Join-Path $scriptdir "openssh-events.man"
if (-not (Test-Path $sshdpath)) {
throw "sshd.exe is not present in script path"
}
if (Get-Service sshd -ErrorAction SilentlyContinue)
{
Stop-Service sshd
sc.exe delete sshd 1>$null
}
if (Get-Service ssh-agent -ErrorAction SilentlyContinue)
{
Stop-Service ssh-agent
sc.exe delete ssh-agent 1>$null
}
# Unregister etw provider
# PowerShell 7.3+ has new/different native command argument parsing
if ($PSVersiontable.PSVersion -le '7.2.9') {
wevtutil um `"$etwman`"
}
else {
wevtutil um "$etwman"
}
# adjust provider resource path in instrumentation manifest
[XML]$xml = Get-Content $etwman
$xml.instrumentationManifest.instrumentation.events.provider.resourceFileName = "$sshagentpath"
$xml.instrumentationManifest.instrumentation.events.provider.messageFileName = "$sshagentpath"
$streamWriter = $null
$xmlWriter = $null
try {
$streamWriter = new-object System.IO.StreamWriter($etwman)
$xmlWriter = [System.Xml.XmlWriter]::Create($streamWriter)
$xml.Save($xmlWriter)
}
finally {
if($streamWriter) {
$streamWriter.Close()
}
}
# Fix the registry permissions
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\OpenSSHUtils -Force
Enable-Privilege SeRestorePrivilege | out-null
$sshRootRegPath="HKLM:SOFTWARE/Openssh"
if (Test-Path $sshRootRegPath)
{
$sshRootAcl=Get-Acl $sshRootRegPath
# SDDL - FullAcess to System and Builtin/Admins and read only access to Authenticated users
$sshRootAcl.SetSecurityDescriptorSddlForm("O:BAG:SYD:P(A;OICI;KR;;;AU)(A;OICI;KA;;;SY)(A;OICI;KA;;;BA)")
Set-Acl $sshRootRegPath $sshRootAcl
}
$sshAgentRegPath="HKLM:SOFTWARE/Openssh/agent"
if (Test-Path $sshAgentRegPath)
{
$sshAgentAcl=Get-Acl $sshAgentRegPath
# SDDL - FullAcess to System and Builtin/Admins.
$sshAgentAcl.SetSecurityDescriptorSddlForm("O:BAG:SYD:P(A;OICI;KA;;;SY)(A;OICI;KA;;;BA)")
Set-Acl $sshAgentRegPath $sshAgentAcl
}
# Create MitigationOptions registry key if it doesn't exist for RedirectionGuard
$sshdMitigationRegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sshd.exe"
if (-not (Test-Path $sshdMitigationRegPath)) {
New-Item -Path $sshdMitigationRegPath -Force | Out-Null
Write-Host "Created registry key: $sshdMitigationRegPath"
}
# Check if MitigationOptions value exists
$mitigationValue = Get-ItemProperty -Path $sshdMitigationRegPath -Name "MitigationOptions" -ErrorAction SilentlyContinue
if (-not $mitigationValue) {
# Create binary value: 19 bytes with 0x10 at the end (RedirectionGuard mitigation)
$binaryData = [byte[]](0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10)
New-ItemProperty -Path $sshdMitigationRegPath -Name "MitigationOptions" -PropertyType Binary -Value $binaryData -Force | Out-Null
Write-Host "Created registry value for sshd.exe to enable RedirectionGuard"
}
# Create MitigationOptions registry key if it doesn't exist for RedirectionGuard
$agentMitigationRegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ssh-agent.exe"
if (-not (Test-Path $agentMitigationRegPath)) {
New-Item -Path $agentMitigationRegPath -Force | Out-Null
Write-Host "Created registry key: $agentMitigationRegPath"
}
# Check if MitigationOptions value exists
$mitigationValue = Get-ItemProperty -Path $agentMitigationRegPath -Name "MitigationOptions" -ErrorAction SilentlyContinue
if (-not $mitigationValue) {
# Create binary value: 19 bytes with 0x10 at the end (RedirectionGuard mitigation)
$binaryData = [byte[]](0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10)
New-ItemProperty -Path $agentMitigationRegPath -Name "MitigationOptions" -PropertyType Binary -Value $binaryData -Force | Out-Null
Write-Host "Created registry value for ssh-agent.exe to enable RedirectionGuard"
}
#Fix permissions for moduli file
$moduliPath = Join-Path $PSScriptRoot "moduli"
if (Test-Path $moduliPath -PathType Leaf)
{
# if user calls .\install-sshd.ps1 with -confirm, use that
# otherwise, need to preserve legacy behavior
if (-not $PSBoundParameters.ContainsKey('confirm'))
{
$PSBoundParameters.add('confirm', $false)
}
Repair-ModuliFilePermission -FilePath $moduliPath @psBoundParameters
}
# If %programData%/ssh folder already exists, verify and, if necessary and approved by user, fix permissions
$sshProgDataPath = Join-Path $env:ProgramData "ssh"
if (Test-Path $sshProgDataPath)
{
# SSH Folder - owner: System or Admins; full access: System, Admins; read or readandexecute/synchronize permissible: Authenticated Users
Repair-SSHFolderPermission -FilePath $sshProgDataPath @psBoundParameters
# Files in SSH Folder (excluding private key files)
# owner: System or Admins; full access: System, Admins; read/readandexecute/synchronize permissable: Authenticated Users
$privateKeyFiles = @("ssh_host_dsa_key", "ssh_host_ecdsa_key", "ssh_host_ed25519_key", "ssh_host_rsa_key")
Get-ChildItem -Path (Join-Path $sshProgDataPath '*') -Recurse -Exclude ($privateKeyFiles) -Force | ForEach-Object {
Repair-SSHFolderFilePermission -FilePath $_.FullName @psBoundParameters
}
# Private key files - owner: System or Admins; full access: System, Admins
Get-ChildItem -Path (Join-Path $sshProgDataPath '*') -Recurse -Include $privateKeyFiles -Force | ForEach-Object {
Repair-SSHFolderPrivateKeyPermission -FilePath $_.FullName @psBoundParameters
}
}
# Register etw provider
# PowerShell 7.3+ has new/different native command argument parsing
if ($PSVersiontable.PSVersion -le '7.2.9') {
wevtutil im `"$etwman`"
} else {
wevtutil im "$etwman"
}
$agentDesc = "Agent to hold private keys used for public key authentication."
New-Service -Name ssh-agent -DisplayName "OpenSSH Authentication Agent" -BinaryPathName "`"$sshagentpath`"" -Description $agentDesc -StartupType Manual | Out-Null
sc.exe sdset ssh-agent "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RP;;;AU)"
sc.exe privs ssh-agent SeAssignPrimaryTokenPrivilege/SeTcbPrivilege/SeBackupPrivilege/SeRestorePrivilege/SeImpersonatePrivilege
$sshdDesc = "SSH protocol based service to provide secure encrypted communications between two untrusted hosts over an insecure network."
New-Service -Name sshd -DisplayName "OpenSSH SSH Server" -BinaryPathName "`"$sshdpath`"" -Description $sshdDesc -StartupType Manual | Out-Null
sc.exe privs sshd SeAssignPrimaryTokenPrivilege/SeTcbPrivilege/SeBackupPrivilege/SeRestorePrivilege/SeImpersonatePrivilege
Write-Host -ForegroundColor Green "sshd and ssh-agent services successfully installed"
# add folder to system PATH
Add-MachinePath -FilePath $scriptdir @psBoundParameters