批处理文件自动提升使用 powershell 并且不破坏参数但调用问题

问题描述 投票:0回答:1

我正在尝试实现

提出的功能

mklement0 在这个答案上

我的目标是将其实现为可重用的批处理子函数

但在那之前,我遇到了一种不一致的行为模式

主要取决于脚本的调用方式,它在哪里以及从哪里调用

如果从文件夹中调用脚本并且它也在文件夹中,则该脚本通常有效。 但是,如果从驱动器的根目录调用它,它可能会失败并出现有关 && 管道的错误。

为了记录行为,我将脚本保存为文件

i:\Test privilege escalation powershell with arguments.bat

和 i:\script\Test 权限提升 powershell with arguments.bat

确切的剧本是

@echo off
setlocal

:: Test whether this invocation is elevated (`net session` only works with elevation).
:: If already running elevated (as admin), continue below.
net session >NUL 2>NUL && goto :elevated

:: If not, reinvoke with elevation.
set args=%*
if defined args set args=%args:^=^^%
if defined args set args=%args:<=^<%
if defined args set args=%args:>=^>%
if defined args set args=%args:&=^&%
if defined args set args=%args:|=^|%
if defined args set "args=%args:"=\"\"%"
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
  " Start-Process -Wait -Verb RunAs -FilePath cmd -ArgumentList \"/c \"\" cd /d \"\"%CD%\"\" ^&^& \"\"%~f0\"\" %args% \"\" \" "
exit /b

:elevated

:: =====================================================
:: Now we are running elevated, in the same working dir., with args passed through.
:: YOUR CODE GOES HERE.

echo First argument is "%~1"
echo Second argument is "%~2"

pause

我尝试从多个位置调用这些脚本 c:\ d:\ i:,从文件夹,从驱动器根目录。我什至尝试了多次,但并不总是得到相同的结果。

可以在此处找到所发生事件的完整日志https://pastebin.com/xCEJKE2f 我不会在这里复制最相关的部分

在普通的 cmd.exe 控制台中,控制台没有特权

C:\>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
C:\>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
C:\>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
All 3 fail to The token '&&' is not a valid statement separator in this version. https://i.imgur.com/5sUHPeB.png
C:\>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
Fails with The system cannot find the path specified.                            https://i.imgur.com/5sUHPeB.png
 
C:\Users\shodan>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
C:\Users\shodan>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
C:\Users\shodan>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
C:\Users\shodan>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
All 4 work https://i.imgur.com/DVGpJFI.png
 
d:\>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
d:\>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
d:\>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
all 3 don't work, "The token '&&' is not a valid statement separator in this version." https://i.imgur.com/60NHWLh.png
d:\>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
does not work The system cannot find the path specified.
 
Later attempt ??? Not the same result ?  d:\ vs D:\ ?!?
D:\>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
D:\>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
D:\>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
D:\>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
All four fail with "The token '&&' is not a valid statement separator in this version."  https://i.imgur.com/c9WcxCp.png
 
d:\share>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
d:\share>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
d:\share>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
all 3 work             https://i.imgur.com/0be7DkQ.png
d:\share>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
The system cannot find the path specified.
 
Later attempt, not the same results ?!?! again  d:\ vs D:\ ?!?
D:\share>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
D:\share>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
D:\share>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
D:\share>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
All four work and elevated properly ! https://i.imgur.com/EtfvRyb.png
 
I:\>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
I:\>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
I:\>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
I:\>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
all don't work, same error, "The token '&&' is not a valid statement separator in this version." https://i.imgur.com/HiJggQ4.png
This result tried twice, second time same result
 
I:\scripts>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
I:\scripts>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
I:\scripts>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
All 3 work
I:\scripts>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
does not work The system cannot find the path specified.
This result tried twice, second time same result
   
 
Double click on I:\Test privilege escalation powershell with arguments.bat
Does not work, console flashes briefly and disappear too fast to see what the error message was
It should pause, but doesn't !
 
Double clicking on I:\scripts\Test privilege escalation powershell with arguments.bat
works https://i.imgur.com/lFMD2MI.png
 
Drag and dropping a bunch of files onto I:\scripts\Test privilege escalation powershell with arguments.bat
works, dropped files are arguments https://i.imgur.com/nUXgWbA.png https://i.imgur.com/PtMT91d.png
 
Drag and dropping files onto 
https://i.imgur.com/AMMPXzf.png
Does not work, console flashes briefly and disappear too fast to see what the error message was
It should pause, but doesn't !
 
In a PRIVILEGE console
 
C:\Windows\system32>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
C:\Windows\system32>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
C:\Windows\system32>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
C:\Windows\system32>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
All 4 work https://i.imgur.com/60owFpJ.png
 
C:\>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
C:\>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
C:\>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
C:\>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
All 4 work  https://i.imgur.com/sgT3EUx.png
 
D:\>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
D:\>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
D:\>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
D:\>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
All 4 work  https://i.imgur.com/TJyNGy4.png
 
I:\>"i:Test privilege escalation powershell with arguments.bat" 1 2 3
I:\>"i:\Test privilege escalation powershell with arguments.bat" 1 2 3
I:\>"i:\scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
I:\>"i:scripts\Test privilege escalation powershell with arguments.bat" 1 2 3
All 4 work  https://i.imgur.com/S1mxGsF.png

所以我的问题是,为什么这个脚本的行为会根据它的调用位置、调用位置和方式(i: ilename.bat vs i:filename.bat)而有所不同。还有这种情况,一切看起来都一样,但结果却不一样。

最后,我的目标是把这个脚本变成一个可重用的子函数,它应该是下面的格式。

@echo off
set TestArguments=parameter1 parameter2 parameter3 value1=true -command "c:\path\ and file.ext" "<>^\/\\^^^^/&^&&|"


Call :IsAdmin IsAdmin

if %IsAdmin%==true echo Admin privileges found
if not %IsAdmin%==true echo No admin privileges found
if not %IsAdmin%==true echo Re-executing script as admin

REM Call :IsInConsole IsInConsole
REM if %IsInConsole%==true echo Script is running in console
REM if not %IsAdmin%==true Call :Elevate %TestArguments%
REM if not %IsAdmin%==true Call :Elevate MyExtraArgument %IsInConsole% %*
if not %IsAdmin%==true Call :Elevate %*

echo After elevation

Call :IsAdmin IsAdmin
echo After elevation Is admin ? %IsAdmin%
echo arguments are %*
echo end of script
pause
:END
GoTo :EOF

REM Execute current script with elevated privileges using UAC invocation
REM Usage Call :Elevate followed by -command "line arguments" c:\test\test.txt
:Elevate
set args=%*
if defined args set args=%args:^=^^%
if defined args set args=%args:<=^<%
if defined args set args=%args:>=^>%
if defined args set args=%args:&=^&%
if defined args set args=%args:|=^|%
if defined args set "args=%args:"=\"\"%"
REM See mklement0's explanation at https://stackoverflow.com/questions/54658352/passing-quoted-arguments-from-batch-file-to-powershell-start-self-elevation/54701990#54701990
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
  " Start-Process -Wait -Verb RunAs -FilePath cmd -ArgumentList \"/c \"\" cd /d \"\"%CD%\"\" ^&^& \"\"%~f0\"\" %args% \"\" \" "
GoTo :EOF

:IsAdmin
  set %1=false
  net session >nul 2>&1
  if %ERRORLEVEL% == 0 set %1=true
GoTo :EOF

:IsInConsole
set %1=false
set "IsRunningInConsole=%cmdcmdline:"=_%"
if "%IsRunningInConsole:cmd.exe=%" == "%IsRunningInConsole%" set %2=true
goto :eof
powershell batch-file escaping quotes elevated-privileges
1个回答
0
投票

当批处理文件恰好从驱动器的 root 目录调用时会出现问题,因为

%CD%
然后扩展为
\
结尾的值,这会破坏 PowerShell 的命令行解析,因为它会干扰逃脱的
"
\"
)跟随它。

实用的解决方法是在以下

\"
之前简单地附加一个空格,它仍然有效,因为
cmd.exe
忽略文件系统路径中的尾随空格:

换句话说:将

%CD%\"
更改为
%CD% \"

我也相应地更新了链接的答案。

© www.soinside.com 2019 - 2024. All rights reserved.