Merge pull request #5818 from mitchellh/issue-5790-password-in-cleartext

provisioner/shell: remove plaintext auth from Windows powershell
This commit is contained in:
Mitchell Hashimoto 2015-07-06 15:21:47 -06:00
commit bd0626672b
3 changed files with 23 additions and 27 deletions

View File

@ -134,12 +134,7 @@ module VagrantPlugins
}.merge(opts || {})
opts[:good_exit] = Array(opts[:good_exit])
if opts[:elevated]
guest_script_path = create_elevated_shell_script(command)
command = "powershell -executionpolicy bypass -file #{guest_script_path}"
end
command = wrap_in_scheduled_task(command) if opts[:elevated]
output = shell.send(opts[:shell], command, &block)
execution_output(output, opts)
end
@ -187,19 +182,15 @@ module VagrantPlugins
)
end
# Creates and uploads a PowerShell script which wraps the specified
# command in a scheduled task. The scheduled task allows commands to
# run on the guest as a true local admin without any of the restrictions
# that WinRM puts in place.
# Creates and uploads a PowerShell script which wraps a command in a
# scheduled task. The scheduled task allows commands to run on the guest
# as a true local admin without any of the restrictions that WinRM puts
# in place.
#
# @return The path to elevated_shell.ps1 on the guest
def create_elevated_shell_script(command)
# @return The wrapper command to execute
def wrap_in_scheduled_task(command)
path = File.expand_path("../scripts/elevated_shell.ps1", __FILE__)
script = Vagrant::Util::TemplateRenderer.render(path, options: {
username: shell.username,
password: shell.password,
command: command.gsub("\"", "`\""),
})
script = Vagrant::Util::TemplateRenderer.render(path)
guest_script_path = "c:/tmp/vagrant-elevated-shell.ps1"
file = Tempfile.new(["vagrant-elevated-shell", "ps1"])
begin
@ -211,7 +202,15 @@ module VagrantPlugins
file.close
file.unlink
end
guest_script_path
# convert to double byte unicode string then base64 encode
# just like PowerShell -EncodedCommand expects
wrapped_encoded_command = Base64.strict_encode64(
"#{command}; exit $LASTEXITCODE".encode('UTF-16LE', 'UTF-8'))
"powershell -executionpolicy bypass -file \"#{guest_script_path}\" " +
"-username \"#{shell.username}\" -password \"#{shell.password}\" " +
"-encoded_command \"#{wrapped_encoded_command}\""
end
# Handles the raw WinRM shell result and converts it to a

View File

@ -1,6 +1,4 @@
$command = "<%= options[:command] %>" + '; exit $LASTEXITCODE'
$user = '<%= options[:username] %>'
$password = '<%= options[:password] %>'
param([String]$username, [String]$password, [String]$encoded_command)
$task_name = "WinRM_Elevated_Shell"
$out_file = "$env:SystemRoot\Temp\WinRM_Elevated_Shell.log"
@ -14,7 +12,7 @@ $task_xml = @'
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<Principals>
<Principal id="Author">
<UserId>{user}</UserId>
<UserId>{username}</UserId>
<LogonType>Password</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
@ -47,19 +45,17 @@ $task_xml = @'
</Task>
'@
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encoded_command = [Convert]::ToBase64String($bytes)
$arguments = "/c powershell.exe -EncodedCommand $encoded_command &gt; $out_file 2&gt;&amp;1"
$task_xml = $task_xml.Replace("{arguments}", $arguments)
$task_xml = $task_xml.Replace("{user}", $user)
$task_xml = $task_xml.Replace("{username}", $username)
$schedule = New-Object -ComObject "Schedule.Service"
$schedule.Connect()
$task = $schedule.NewTask($null)
$task.XmlText = $task_xml
$folder = $schedule.GetFolder("\")
$folder.RegisterTaskDefinition($task_name, $task, 6, $user, $password, 1, $null) | Out-Null
$folder.RegisterTaskDefinition($task_name, $task, 6, $username, $password, 1, $null) | Out-Null
$registered_task = $folder.GetTask("\$task_name")
$registered_task.Run($null) | Out-Null

View File

@ -55,7 +55,8 @@ describe VagrantPlugins::CommunicatorWinRM::Communicator do
it "wraps command in elevated shell script when elevated is true" do
expect(shell).to receive(:upload).with(kind_of(String), "c:/tmp/vagrant-elevated-shell.ps1")
expect(shell).to receive(:powershell) do |cmd|
expect(cmd).to eq("powershell -executionpolicy bypass -file c:/tmp/vagrant-elevated-shell.ps1")
expect(cmd).to eq("powershell -executionpolicy bypass -file \"c:/tmp/vagrant-elevated-shell.ps1\" " +
"-username \"vagrant\" -password \"password\" -encoded_command \"ZABpAHIAOwAgAGUAeABpAHQAIAAkAEwAQQBTAFQARQBYAEkAVABDAE8ARABFAA==\"")
end.and_return({ exitcode: 0 })
expect(subject.execute("dir", { elevated: true })).to eq(0)
end