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

[其他] 批处理变量值中含有特殊符号的讨论

声明:
1、讨论中的问题并不是本人发现的,而是参考了https://www.thesecurityfactory.be/command-injection-windows.html,大家可以看一下该网址的内容(不过都是英文的,本人英语一般般,大概看懂6、7成而已^^),如果大家还有什么新的发现,欢迎大家帮忙补充。
2、该文中讨论的问题,是希望大家能够在编写批处理脚本时引起注意,而不是让大家利用其中的漏洞做一些违法的事情,这一点尤其要申明一下。
3、该讨论中的一些技术点,本人就不过多展开(其实都是些基础知识,不懂的话就上网搜查一下)
在批处理脚本中,经常会使用到变量,也会为变量进行赋值等操作。
如果变量的值含有一些特殊的符号,比如&、|等,在使用时会出现意想不到的结果。

首先,我先讲两个小知识点,因为下面讨论的问题用到,但我不过多的展开来讲,具体的内容请自己上网搜索。
第一,"&"、"&&",以及" |"和"||"的作用。
命令1&命令2                执行命令1后再执行命令2
命令1&&命令2                执行命令1成功才执行命令2
命令1|命令2                将执行命令1的结果传递给命令2
命令1||命令2                执行命令1失败才执行命令2
第二,设置变量时,可以用"^"符号去将上述讲到的单个特殊符号(如"&","|")转义成字面上的含义,而不带有特殊作用。
例如,set VAR=TEST^&DIR 就是将变量VAR设置为TEST&DIR,
        如果没有^,则这条命令会理解成set VAR=TEST & DIR,即先设置VAR的变量为TEST,再执行DIR命令
      set VAR=TEST^&^&DIR 就是将变量VAR设置为TEST&DIR,
        如果没有^,则这条命令会理解成set VAR=TEST && DIR,即设置VAR的变量为TEST成功后才执行DIR命令


这里本人就拿"&"进行举例,其他特殊符号(&&,|,||)可以自己尝试一下,效果差不多。
……………………………………
在命令行中输入:
  1. SET VAR=TEST^&PING 127.0.0.1
  2. 紧接着输入:
  3. ECHO %VAR%
  4. 结果为:
  5. TEST
  6. 正在 Ping 127.0.0.1 具有 32 字节的数据:
  7. 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64
  8. 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64
  9. 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64
  10. 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64
  11. 127.0.0.1 的 Ping 统计信息:
  12.     数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
  13. 往返行程的估计时间(以毫秒为单位):
  14.     最短 = 0ms,最长 = 0ms,平均 = 0ms
  15. 或者输入:
  16. SET VAR1=%VAR%
  17. 结果为:
  18. 正在 Ping 127.0.0.1 具有 32 字节的数据:
  19. 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64
  20. 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64
  21. 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64
  22. 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64
  23. 127.0.0.1 的 Ping 统计信息:
  24.     数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
  25. 往返行程的估计时间(以毫秒为单位):
  26.     最短 = 0ms,最长 = 0ms,平均 = 0ms
复制代码
其结果是不是跟自己预想的不一样。
下面,我们就来分析一下。
首先,SET VAR=TEST^&PING 127.0.0.1这个命令将VAR的值设置为TEST&PING 127.0.0.1
再执行ECHO %VAR%命令时,命令行解析器会先把%VAR%用变量值(如果有设置,否则就按原来的字面意思)代替,
结果展开来就是ECHO TEST&PING 127.0.0.1,然后命令行解析器才会对该行进行解释,这样就会将解释为执行ECHO TEST后,再执行PING 127.0.0.1
同理,执行SET VAR1=%VAR%命令时,命令行解析器也是先把%VAR%用变量值(如果有设置,否则就按原来的字面意思)代替,
结果展开来就是SET VAR1=TEST&PING 127.0.0.1,然后命令行解析器才会对该行进行解释,这样就会将解释为执行SET VAR1=TEST后,再执行PING

127.0.0.1
大家可以以此类推。

由于这样的原因,很容易被黑客抓住该漏洞进行攻击。
在批处理当中,经常会用到这两个内置的环境变量,%CD%和%__CD__%。
这两个都表示当前目录的完整路径,不同的是%__CD__%最后会紧跟着反斜杠"\",
而%CD%除了根目录外,最后都不紧跟着反斜杠"\"。

设想一下,在一个有多人共享的文件服务器,有人故意创建一个特殊目录如下:
MD "mydir&malware.exe"
malware.exe是一个病毒程序,位于该目录下
然后管理员可能会用一些批处理对每个目录进行遍历,去执行一些任务,
这些批处理会以管理员的权限进入当前目录,同时为了保存当前目录的路径,会有这样一句命令SET CurrentPath=%CD%,
通过上面所讲,你就知道这句话就会类似扩展成SET CurrentPath=\\fileServer1\Share\user1\mydir&malware.exe,
这样,批处理就会不小心执行malware.exe这个病毒程序。

补充一下:
我参考上面介绍的网址https://www.thesecurityfactory.be/command-injection-windows.html
创建了一个特殊目录如下:md "TEST&PING 127.0.0.1" ,然后进入到这个目录中,用ECHO %CD%和SET CurrentPath=%CD%,
发现它照常输出:TEST&PING 127.0.0.1整句字符串,和将 CurrentPath 设置为TEST&PING 127.0.0.1整句字符串,
而不会去执行PING 127.0.0.1。
这些操作都是在我的XP和win7系统上测试过,可是,我在那个网址上看到试验的结果是与我测试的情况却不相同,
我猜想微软后来可能打了补丁吧。具体情况,我希望大家谁有比较旧的系统上测试一下,看一看结果怎样?
但是,我发现问题仍然存在。这些直接对内置环境变量操作ECHO %CD%和SET CurrentPath=%CD%没有多大问题,
但是如果我们将%CD%的值赋值给别的变量,如SET CURRENDIR=%CD%, 然后执行ECHO %CURRENDIR%和SET CurrentPath=%CURRENDIR%时,
仍然会有上述问题发生,大家可以自己测试一下。
因为一些旧的文件服务器,还有很多公司还在使用,可能没有打补丁吧,仍然会被一些别有用心的人利用,大家要注意一下!

接下来,我们如何避免这种情况呢?
比较简单的方法,就是在引用变量时加上双引号,如:
  1. SET CurrentPath="%CD%"
复制代码
但是,这个方法不是万能的,如果变量的值本身含有双引号就会失效,例如:
  1. SET B=T"&calc&
  2. SET C="%B%"
复制代码
大家测试一下,会发现其会启动计算器程序(calc)
注意:这点并不适用于%CD%,因为文件和目录名都不能包含双引号。

更多的相关知识点,大家还可以参考以下网址:
http://www.robvanderwoude.com/ba ... tedcdexploit.php#CD
1

评分人数

转义也可以set "var=TEST&DIR"或者set var="TEST&DIR",后者可根据需求决定是否保留双引号;既然知道是预处理使然,那么延迟下变量亦可;至于路径,通常都建议带上双引号
  1. setlocal enabledelayedexpansion
  2. set "var=TEST&DIR"
  3. echo;!var!
复制代码

TOP

返回列表