[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]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%"
复制代码
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

回复 17# Five66
你是对的,
因为linux shell会进行通配符扩展,
而且在windows上写的C程序接受外部参数会通配符匹配文件,所以想当然了,研究了一下,应当是编译器的feature

TOP

回复 16# buyiyang


   
可以自行弄个exe测试下
或者试试
sort *.txt
notepad *.txt
where *.exe
findstr * a.txt
7z e a.7z *.jpg
python -c "(a:=__import__('sys')) and print(a.argv)" *.* *.txt
这些命令
不管外部还是内部 ,都不是由cmd作为通配符处理的 , 而是由命令或程序自行判断 , 自行决定 ,自行处理的
1

评分人数

TOP

回复 14# Five66


cmd的内部命令如何处理 ? 和 * 确实是由命令决定的
但外部命令带有的含有 ? 和 * 参数是由cmd统一作通配符匹配文件的

TOP

回复 14# Five66

本帖的语义聚焦命令行参数,为此把13楼的关键词作了加色限定,以便大家的讨论才有意义...
另注》for 也是cmd内置的,都是一个 ‘老爹’ 定义解译的 ...

TOP

回复 13# aloha20200628


   
cmd中的 ? 和 * 只是普通字符 , 是否作为通配符是由命令或程序自身决定的
比如 echo * ,cmd不会将 *当成通配符 ,echo命令本身也不会将 *当成通配符
for %%i in (*) 中是 for 命令将 * 当成通配符了(而且无法转义成普通字符)
1

评分人数

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

TOP

本帖最后由 aloha20200628 于 2025-1-19 10:55 编辑

回复 11# WHY

命令行参数中的 ? 和 * 字符被cmd作为通配符处理,类同 for %%i in (*) do ...
1

评分人数

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

TOP

我们要做的是 "尽可能通用" ;
根本不存在什么 "绝对通用" 的代码,明知不可为而为之,不现实也不明智。

TOP

回复 10# aloha20200628


    test.bat 123,456 "1*2" "2^3"

看看会发生什么?
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

仅支持带空格的路径及参数,谈不上"通用";
包含特殊字符的路径(文件名)并不罕见,比如: 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

本帖最后由 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

回复 4# flashercs


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

TOP

回复 5# aloha20200628


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

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

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

返回列表