Как запустить код base64 в powershell с помощью ascii?
Я хотел бы запустить команду mkdir C:\Temp\555
в Powershell через строку в кодировке Base64.
Этот код должен работать
$4 = "bWtkaXIgQzpcVGVtcFw1NTU="
$code = [Text.Encoding]::Utf8.GetString([Convert]::FromBase64String($4))
powershell $code
но если я преобразую $code
в ASCII, как я могу запустить его так, потому что этот не будет работать:
$4 = "bWtkaXIgQzpcVGVtcFw1NTU="
$code = [char]091+[char]084+[char]101+[char]120+[char]116+[char]046+[char]069+[char]110+[char]099+[char]111+[char]100+[char]105+[char]110+[char]103+[char]093+[char]058+[char]058+[char]085+[char]116+[char]102+[char]056+[char]046+[char]071+[char]101+[char]116+[char]083+[char]116+[char]114+[char]105+[char]110+[char]103+[char]040+[char]091+[char]067+[char]111+[char]110+[char]118+[char]101+[char]114+[char]116+[char]093+[char]058+[char]058+[char]070+[char]114+[char]111+[char]109+[char]066+[char]097+[char]115+[char]101+[char]054+[char]052+[char]083+[char]116+[char]114+[char]105+[char]110+[char]103+[char]040+[char]036+[char]052+[char]041+[char]041
powershell $code
потому что последний код не работает, а первый работает, пожалуйста, помогите?
2 ответа
Строка может быть выполнена в виде скрипта с помощью метода класса CommandInvocationIntrinsics InvokeScript
,
powershell $executioncontext.InvokeCommand.InvokeScript($code)
См. InvokeScript Method для получения дополнительной информации.
Примечание. Этот ответ касается распространенных случаев использования; для обсуждения того, что вы пробовали, смотрите нижний раздел.
Примечание. Если вы просто хотите выполнять команды, хранящиеся в строке, в сеансе PowerShell, без необходимости запуска команд в дочернем процессе, используйте Invoke-Expression
Но обратите внимание, что Invoke-Expression
как правило, следует избегать:
Примечание: для наглядности я подставляю команду Get-Date -UFormat "%s"
для вашей оригинальной команды, mkdir "C:\Temp\555"
, Этот Get-Date
команда печатает текущую точку времени как метку времени Unix, то есть целое число, обозначающее секунды с 1 января 1970 года, полночь UTC; например, 1565229614
за Wednesday, August 7, 2019 10:00:13 PM ETD
,
$cmd = 'Get-Date -UFormat "%s"'
Invoke-Expression $cmd # Execute the string $cmd as code.
Если вы управляете построением команд, лучше хранить фрагменты кода как блоки скриптов ( { ... }
внутри сеанса PowerShell:
$cmd = { Get-Date -UFormat "%s" } # create a script block
& $cmd # execute the script block
Как передать сложную команду дочернему процессу PowerShell через его CLI:
- Из- за пределов PowerShell используйте
-EncodedCommand
параметр, который требует кодирования Base64 байтов строки, кодированной UTF16-LE, а не строки, кодированной UTF-8:
$base64Cmd = 'RwBlAHQALQBEAGEAdABlACAALQBVAEYAbwByAG0AYQB0ACAAIgAlAHMAIgA='
powershell -EncodedCommand $base64Cmd # executes: Get-Date -UFormat "%s"
Примечание. Выше предполагается, что Windows PowerShell. Если вы используете PowerShell Core, используйте pwsh
вместо powershell
,
RwBlAH...
является правильно закодированным представлением Base64 Get-Date -UFormat "%s"
- см. ниже, как создать это представление.
- Внутри PowerShell нет необходимости передавать строку в кодировке Base64 через
-EncodedCommand
явно, потому что PowerShell делает это неявно, когда вы просто передаете код для выполнения в виде блока скрипта ({ ... }
):
powershell { Get-Date -UFormat "%s" } # -Command parameter implied
За кулисами выполняется соответствующее кодирование Base64, и закодированная команда передается -EncodedCommand
, следующее:
# The command to execute:
$cmd = 'Get-Date -UFormat "%s"'
# Obtain a Base64-encoded version of the command from the bytes of its
# UTF-16LE encoding.
$base64Cmd = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($cmd))
# Pass the result to the -EncodedCommand parameter:
powershell -EncodedCommand $base64Cmd
Примечание: -inputFormat xml -outputFormat xml
также добавлены для поддержки сериализации CLIXML при вводе и выводе, для поддержки передачи объектов (не только текста) внутрь и наружу с почти точной точностью.
Что касается того, что вы пытались:
Ваша первая команда работает, потому что вы передаете декодированную текстовую версию
mkdir
командоватьpowershell.exe
который неявно связывается с-Command
Параметр и выполняется как команда в новом сеансе PowerShell.
Как в сторону:pwsh
, CLI PowerShell Core, теперь по умолчанию-File
, так-Command
(или же-c
) должно быть использовано явно.Ваша вторая команда не работает, потому что
$code
теперь содержит простой текст команды декодирования Base64 из вашей первой команды.
Эта команда ссылается на переменную$4
, о котором вы создаете новый экземпляр PowerShell, ничего не знает.
Однако вместо того, чтобы пытаться отложить декодирование в Base64-кодированном mkdir
Команда для нового сеанса PowerShell, имеет гораздо больше смысла передавать команду в кодировке Base64 непосредственно в новый сеанс (если новый сеанс даже необходим, см. выше), через -EncodedCommand
,
Тем не мение, -EncodedCommand
требуется кодировка Base64 на основе UTF-16LE, а не UTF-8 - см. выше, как явно создать такую кодировку (если необходимо).
Если вам предоставлена кодировка Base64 на основе UTF-8, вы можете перевести ее в кодировку на основе UTF-16LE следующим образом:
# UTF-8-based Base64-encoding
$4 = "bWtkaXIgQzpcVGVtcFw1NTU="
# Decode to plain text.
$plainTextCode = [Text.Encoding]::Utf8.GetString([Convert]::FromBase64String($4))
# Re-encode to Base64 via UTF-16 ("Unicode"):
$utf16Base64Command = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($plainTextCode))
# Pass to powershell.exe via -EncodedCommand
powershell -EncodedCommand $code