#powershell
#powershell
Вопрос:
У меня есть приведенный ниже скрипт PowerShell (myscript.ps1), в котором я запрашиваю имя пользователя и пароль. В зависимости от имени пользователя и пароля он копирует файл в определенное место назначения.
$credentials = Get-Credential
if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1")
{ Copy-Item "test1.pdf" "testtest1.pdf"; }
else
{ Copy-Item "test2.pdf" "testtest2.pdf"; }
Требование: я хочу сделать этот файл защищенным, чтобы никто не мог его редактировать и видеть имя пользователя и пароль.
PS2EXE
Я нашел решение, найденное здесь, которое преобразует сценарий PowerShell в .exe
файл. При первоначальном запуске сценария с помощью PowerShell появляется диалоговое окно, позволяющее ввести имя пользователя и пароль:
После создания .exe и при его запуске диалоговое окно учетных данных больше не отображается. Вместо этого на консоли появляется надпись «Учетные данные:»
Я не знаю, почему? Я хочу, чтобы форма учетных данных по-прежнему отображалась при запуске exe. Какие-нибудь мысли, пожалуйста?
Комментарии:
1. Вы не можете защитить скрипт. Но вы можете сохранить uname и пароль в зашифрованном файле и прочитать их во время выполнения.
2. @RyanBemrose не могли бы вы прислать мне ссылку, как это можно сделать, пожалуйста?
3. Это звучит небезопасно, в этом случае скрипту потребуется жестко заданный ключ шифрования, что так же плохо, как и наличие пароля. Почему бы просто не применить ACL к файлу сценария?
4. В этой статье показано, как хранить зашифрованные пароли в диспетчере учетных данных Windows или в защищенной строке. Вы можете найти в Интернете «безопасный пароль powershell» для других руководств по хранению паролей в зашифрованном файле.
5. @Burt_Harris Можно ли применить ACL, который позволяет выполнить файл, но не читать его?
Ответ №1:
Вопрос: Почему EXE запрашивает «Учетные данные»?
Это не ответ на реальный вопрос и основано на догадках о PS2EXE, но я надеюсь, что это полезно для устранения некоторой путаницы.
После краткого просмотра страницы PS2EXE, на которую дана ссылка выше, кажется, что эта утилита кодирует скрипт в Base64 и связывает его с облегченным (?) пользовательским хостом PowerShell. При запуске, я полагаю, EXE запускает хост, декодирует скрипт и запускает его.
Проблема в том, что Get-Credential
командлет выполняется на узле PS, который, вероятно, не может взаимодействовать с рабочим столом. То есть он не может отправить запрос GUI для ввода учетных данных. Поэтому ему необходимо запросить свойство Credential в командной строке, объясняя, почему вы видите такое поведение.
Обходной путь с помощью Read-Host?
Вместо того, чтобы пытаться использовать Get-Credential
запрос имени пользователя и пароля, вы могли бы использовать то, что, похоже, делает PS2EXE, и просто использовать Read-Host
:
$UserName = Read-Host "Enter username"
$Password = Read-Host "Enter password" -AsSecureString
$Credentials = New-Object System.Management.Automation.PSCredential $UserName,$Password
if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1")
{ ... }
Использование -AsSecureString
скроет пароль на экране. Переменная $Password будет иметь тип System.Security.SecureString
, который можно использовать для создания объекта PSCredential, как показано.
Вам нужно было бы протестировать это, но, похоже, вы можете читать из командной строки, но не из приглашения GUI.
И просто для ясности: ничто из этого и близко не подходит к передовой практике обеспечения безопасности. Если вам требуется проверка подлинности / авторизация для этих действий, сделайте шаг назад и посмотрите на проблему еще раз.
Обходной путь с двумя сценариями?
Похоже, что PS2EXE не поддерживает -AsSecureString
так же, как обычный PowerShell, то есть он не скрывает символы. Возможным обходным путем для этого было бы собрать имя пользователя и пароль от пользователя в одном скрипте, а затем передать их в скрипт, преобразованный в PS2EXE, для обработки.
Запуск-MyScript.ps1:
$Credentials = Get-Credential
amp; MyScript.exe $Credentials.Username $Credentials.Password
MyScript.exe (скрыто с помощью PS2EXE):
param($Username,$Password)
$Credentials = New-Object System.Management.Automation.PSCredential $Username,$Password
if ($Credentials.Username -eq "user1" -and
$Credentials.GetNetworkCredential().password -eq "pass1")
{
...
}
Пользователь запускает Launch-MyScript.ps1 и завершает запрос пароля. Затем исполняемый файл запускается автоматически с именем пользователя и паролем, переданными в качестве аргументов. Обратите внимание, что, как показано выше, пароль представляет собой защищенную строку. Протестируйте это; я не использую PS2EXE, так что на данный момент это теоретическое решение.
Если вы не можете передать $Password по конвейеру в виде защищенного строкового объекта, вы можете преобразовать его в текст с помощью ConvertFrom-SecureString
в первом скрипте, затем преобразовать его обратно с помощью ConvertTo-SecureString
во втором.
Комментарии:
1. спасибо за объяснение. Итак, что мне делать, когда в командной строке появится свойство Credential?
2. Если запросы командной строки приемлемы, то вы могли бы запрашивать имя пользователя и пароль по отдельности с помощью
Read-Host
и вообще отказаться от любых попыток использования объекта PSCredential.3. не могли бы вы показать мне, как, пожалуйста? поскольку я не знаком с этим. Также нет способа преобразовать его в .exe и появляется ли форма Get-Credential?
4. Обновлено по ответу. Мне действительно кажется, что мы идем по неверному пути, чтобы решить то, что вы в конечном итоге пытаетесь сделать.
5. Большое вам спасибо. Я сделал это, но теперь я пытаюсь замаскировать пароль, но это не работает, используя
$Password = Read-Host -assecurestring "Enter password"
какие-либо мысли?
Ответ №2:
Согласно этой статье http://windowsitpro.com/powershell/protect-your-powershell-scripts сначала вам следует установить для политики выполнения ur значение AllSigned с помощью Set-ExecutionPolicy AllSigned, затем создать сертификат с помощью командлета makecert.
Затем вы можете подписать отдельный скрипт с помощью командлета Set-AuthenticodeSignature или использовать файл .pfx для подписи скрипта, который кажется еще более безопасным.
Надеюсь, это немного поможет.
Комментарии:
1. Я думаю, что вопрос заключается в скрытии содержимого скрипта. Подписание сценария определяет выполнение сценария, а не то, сможет ли кто-либо прочитать содержимое файла.