[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文件操作] 【已解决】批处理提权怎么支持带双引号参数

本帖最后由 2198114498 于 2024-12-31 12:42 编辑

感谢4楼flashercs完美解决
经过测试,A中start必须提供完整路径或者B中使用%~s0才行。

也是因为一知半解,也是抄作业没抄明白,曾经用下面第一种提权,后来想添加参数换用REG QUERY "HKU\S-1-5-19">NUL 2>&1判断,
已经想不起当时在哪抄的有没有%~s0,可能改的过程没注意改没了,现在重新搜到第二种,才注意到都有%~s0
%1 start "" mshta vbscript:createobject("shell.application").shellexecute("""%~0""","::",,"runas",1)(window.close)&exit
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit

以下是原问题:
找到的提权代码都是无参的
请教各位大神,
1、如何支持任意数量参数,特别是参数带双引号的
2、从A批处理start运行B批处理,如果参数包含双引号,则B批处理提权后闪退
谢谢!

下面是我自己写的测试代码,B可以实现自运行或者拖放运行,
但是A调用B,到了提权代码就会退出,请问该怎么修改,先谢了!
B.bat
  1. @echo on&setlocal enabledelayedexpansion
  2. cd /d %~dp0
  3. echo 0=%0
  4. echo *=%*
  5. echo 1=%1
  6. echo 2=%2
  7. echo 3=%3
  8. echo 4=%4
  9. echo 5=%5
  10. echo 6=%6
  11. echo 7=%7
  12. echo 8=%8
  13. echo 9=%9
  14. pause
  15. if not "%~2"=="" set args=%*&goto :@a
  16. set args=%* "abc" "1 23" 4 5
  17. :@a
  18. set args=%args:"=""%
  19. REG QUERY "HKU\S-1-5-19">NUL 2>&1||mshta vbscript:createobject("shell.application").shellexecute("cmd.exe","/c """"%~0"" %args%""",,"runas",1)(window.close)&&pause&&goto :eof
  20. mshta vbscript:Execute("msgbox(""文件不存在: ""):close")
  21. pause&goto :eof
复制代码
A.bat
  1. cd /d %~dp0
  2. set args=1 2 3 4 5 "6 a" "b 7"
  3. start "B" cmd /c ""B.bat" %args%"
复制代码

本帖最后由 aloha20200628 于 2024-12-31 10:49 编辑

回复 1# 2198114498

批处提权可用 vbs/jscript/mshta/powershell 等脚本实现,其中用 powershell 句式较为简洁。
基本流程分两步,先测试当前是否已被提权,否》则开启新进程窗口运行提权的批处脚本,是》则运行已被提权的批处代码...
以下代码是一个 powershell 版式(存为 test.bat 运行),支持脚本路径和命令行参数均可包含空格即有双引号包裹,其中3-9行是开启提权批处脚本的代码,11行以后是被提权批处脚本的代码...
  1. @echo off &setlocal &set "v=%*" &fsutil dirty query %systemdrive%>nul
  2. if %errorlevel% neq 0 (
  3.   echo,申请管理员权限...
  4.   REM 下式针对无命令行参数
  5.   if "%~1"=="" (powershell "start -file '%~f0' -verb runas" &exit/b)
  6.   REM 以下针对有命令行参数》脚本路径和命令行参数均可包含空格即有双引号包裹
  7.   setlocal enabledelayedexpansion &for %%v in (!v!) do (set vl=!vl! """%%~v""")
  8.   set "vl=/c call """%~f0""" !vl!"
  9.   powershell "start -file 'cmd.exe' -arg '!vl!' -verb runas" &exit/b
  10. )
  11. :: 以下是提权之后的批处代码...
  12.   echo,已获取管理员权限
  13.   if "%~1"=="" pause&exit/b
  14.   echo,遍历命令行参数
  15.   for %%v in (%*) do echo,"%%~v"
  16. pause&exit/b
复制代码
测试用例
  1. test.bat 123 "xx yy zz" 789
复制代码
若 test.bat 更名为 "test ps.bat"
  1. "test ps.bat" 123 "xx yy zz" 789
复制代码

TOP

回复 2# aloha20200628


    非常感谢!学习了!
之前写过一些PS脚本,但是因为安全策略禁止,一直用批处理调用,而且加载比较慢,有些事情bat更简洁,所以能用bat的就不用PS。

请问,上面bat的测试代码,不是我写的不对?或者就是bat实现不了?

TOP

  1. @echo on&setlocal enabledelayedexpansion
  2. cd /d %~dp0
  3. echo 0=%0
  4. echo *=%*
  5. echo 1=%1
  6. echo 2=%2
  7. echo 3=%3
  8. echo 4=%4
  9. echo 5=%5
  10. echo 6=%6
  11. echo 7=%7
  12. echo 8=%8
  13. echo 9=%9
  14. pause
  15. set args=%* "abc" "1 23" 4 5
  16. set args=%args:"=""%
  17. echo args=!args!
  18. REG QUERY "HKU\S-1-5-19">NUL 2>&1||mshta vbscript:createobject("shell.application").shellexecute("cmd.exe","/c """"%~s0"" !args!""",,"runas",1)(window.close)&&pause&&goto :eof
  19. mshta vbscript:Execute("msgbox(""文件不存在: ""):close")
  20. pause&goto :eof
复制代码
微信:flashercs
QQ:49908356

TOP

本帖最后由 aloha20200628 于 2024-12-31 10:51 编辑

回复 3# 2198114498

好吧,不用 powershell 就再给一个 jscript 版式(存为 test.bat 运行)支持脚本路径和命令行参数均包含空格即可被双引号包裹
  1. 2>1/* ::
  2. @echo off & fsutil dirty query %systemdrive%>nul
  3. if %errorlevel% neq 0 (
  4.    echo,获取管理员权限...
  5.    (cscript /nologo /e:jscript "%~f0" %*)&exit/b)
  6. :: 以下是提权后的批处脚本代码直到 exit/b 退出...
  7. echo,当前进程已获取管理员权限...查看提权自启后传入的全部命令行原参数
  8. for %%v in (%*) do echo,"%%~v"
  9. pause&exit/b */
  10. v=WSH.arguments, sv='/c call \"'+WSH.scriptfullname+'\" ';
  11. for (n=0,l=v.length; n<l; n++) sv+='\"'+v(n)+'\" ';
  12. WSH.createObject('shell.application').shellExecute('cmd', sv, '', 'runas', 1), WSH.quit();
复制代码
测试用例
  1. test.bat 123 "xx yy zz" 789COPY
复制代码
若 test.bat 更名为 "test js.bat"
  1. "test js.bat" 123 "xx yy zz" 789
复制代码

TOP

回复 5# aloha20200628


    非常感谢!真是办法总比困难多!PS的代码测试过,有参无参通用!

刚4楼给我找出问题了,经过测试,A中start必须提供完整路径或者B中使用%~s0才行。

TOP

回复 4# flashercs


    非常感谢!完美解决!
经过测试,A中start必须提供完整路径或者B中使用%~s0才行。

TOP

本帖最后由 aloha20200628 于 2024-12-31 17:48 编辑

回复 6# 2198114498

   提权批处脚本的一个 ‘潜坑’ 就是处理脚本路径和命令行参数包含空格的问题,更有甚者是两者同时包含空格的问题,网间一些旧码中的 mshta 句式采用 %~s0 短文件名格式(dos时代的遗产)来规避路径空格问题,并非全解,故选用更稳妥且兼容性更好的 powershell 或 jscript 方法仍是推荐的上策(仅供参考),也便于解决脚本路径和命令行参数同时包含空格的问题。
   复查了楼主提供的两个测试代码 a.bat 和 b.bat,前者用来启运被提权的脚本并为其输送命令行参数,后者用来检查被提权后接收的命令行参数,用楼主的测试思路,改写了两段代码如下,分别用 powershell 和 jscript 实现(省略了检测当前是否为提权状态的代码),均可支持被提权脚本的路径和命令行参数同时包含空格即被双引号包裹,楼主可更名 b.bat 的文件名或路径包含空格以便验证,代码中的变量 bF 设定 b.bat 的路径(须为全路径),预设为 c:\test\b.bat 可以自定义...

一。bat+jscript 版本(存为 a.bat 运行》启运被提权的 b.bat)
  1. 2>1/* ::
  2. @echo off &setlocal
  3. if "%~1"=="" (set args=123 "a b c" 789) else (set args=%*)
  4. (cscript /nologo /e:jscript "%~f0" %args%)
  5. exit/b */
  6. bF='c:\\test\\b.bat', v=WSH.arguments, sv='/c call \"'+bF+'\" ';
  7. for (n=0,l=v.length; n<l; n++) sv+='\"'+v(n)+'\" ';
  8. WSH.createObject('shell.application').shellExecute('cmd', sv, '', 'runas', 1), WSH.quit();
复制代码
二。bat+powershell 版本(存为 a.bat 运行》启运被提权的 b.bat)
  1. @echo off &setlocal &set "vl=" &set "bF=c:\test\b.bat"
  2. if "%~1"=="" (set args=123 "a b c" 789) else (set args=%*)
  3. setlocal enabledelayedexpansion
  4. for %%v in (!args!) do (set vl=!vl! """%%~v""")
  5. set "vl=/c call """%bF%""" !vl!"
  6. powershell "start -file 'cmd.exe' -arg '!vl!' -verb runas"
  7. exit/b
复制代码
以下代码存为 b.bat
  1. @echo off &setlocal enabledelayedexpansion
  2. for %%v in (%*) do (set/a "n+=1" &echo,!n!=%%~v)
  3. pause&exit/b
复制代码

TOP

仅支持带空格的路径及参数,谈不上"通用";
包含特殊字符的路径(文件名)并不罕见,比如: D:\Test(1)\Test&1

顶楼 A.bat 可以这样改:
  1. @echo off
  2. set args=1 2 3 4 5 "6 a" "b 7"
  3. start "" cmd /c;"%~dp0B.bat" %args%
复制代码
传递给 B.bat 的参数 %0 为 %~dp0B.bat(绝对路径),而不是 B.bat(相对路径) 。

mshta vbscript:createobject("shell.application").shellexecute("cmd.exe","/c """"%~0"" %args%""",,"runas",1)(window.close)&&pause&&goto :eof

因为提权时的工作路径变成了 %WinDir%\System32,
如果是相对路径,在 %WinDir%\System32 里面肯定找不到 B.bat
1

评分人数

    • 77七: 感谢分享技术 + 1

TOP


5楼代码是在 jscript 语境中处理命令行参数,可以兼容被双引号包裹的如 &<|>() 等特殊字符,测试用例如下
  1. test.bat 123 "(a) & <b> |c" 789
复制代码
若 test.bat 更名为 "test js.bat"
  1. "test js.bat" 123 "(a) & <b> |c" 789
复制代码

TOP

返回列表