赞
踩
命令执行(Command Injection)指在某些开发需求中,需要引入对系统本地命令的支持来完成某些特定的功能。当开发未对用户传入的参数进行严格的校验、过滤时,则很有可能会产生命令注入。攻击者使用命令注入来执行系统终端命令,直接获取服务器控制权限。
在开发过程中,开发人员可能需要对文件进行新建、移动、修改、删除或执行其他系统命令。Java的Runtime类可以提供调用系统命令的功能。
1、攻击者能够篡改程序执行的命令:攻击者直接控制了所执行的命令。
2、攻击者能够篡改命令的执行环境:攻击者间接控制了所执行的命令。
常见的参数编码
字符 | 功能描述 | Unix | Windows |
---|---|---|---|
| | 管道:连接上个指令的标准输出,做为下个指令的标准输入 | \ | |
; | 连续指令服务 | \; | ^; |
& | 后台运行 | \& | ^& |
$ | 变量替换 | \$ | ^$ |
> | 重定向输入 | \> | ^> |
< | 目标文件内容发送到命令中 | \< | ^< |
` | 返回当前执行结果 | \` | ^` |
\ | 做为连接符号使用,或转义用 | \ | ^\ |
! | 执行上一条shell命令 | \! | ^! |
命令执行支持使用连接符来执行多条语句,常见的连接符有“|”,“||”,“&”,“&&”
符号 | 含义 |
---|---|
| | 前面的命令输出结果作为后面的命令的输入内容 |
|| | 前面的命令执行失败后才执行后面的命令 |
& | 前面的命令执行后继续执行后面的命令 |
&& | 前面的命令执行成功后才执行后面的命令 |
例如命令“ls | less” ls 是查看当前目录文件;
less查看文件内容,less命令可以分页显示任意命令的输入,并将该命令的结果发送到标准输出。(按q退出)
输入 ls | less 后
|| 连接符是当前面命令执行失败后才执行后面的命令
从图片中可以看到,命令 cd redis-2.8.17 || ls 连接符前面的命令执行成功,后面的命令就不再执行了。
桌面上没有123这个文件夹,所以我们cd到123这个目录下使得连接符前的命令执行失败。连接符后面跟个ls。命令为“cd 123 || ls” 先执行了连接符前的命令,然后又执行了连接符后面的命令。所以错误信息与ls信息都输出了出来。
&连接符是连接符前的命令执行成功后继续执行后面的
&&连接符是当连接符前面的命令执行成功后才执行后面的命令
可以桌面上没有123这个路径,所以首先 cd 123 && ls,连接符前的命令失败,然后连接符后面的命令不在执行。
桌面有redis-2.8.17这个目录,所以连接符前的命令将会执行成功,看到输出结果显示两个命令均执行成功。
对于Java环境中的命令注入,连接符的使用存在一些局限。例如使用ping命令来诊断网络。其中url参数为用户可控,当攻击者输入“www.baidu.com&ipconfig”拼接处的系统命令为“ping www.baidu.com&ipconfig”,该命令在命令行终端可以成功执行。然而在Java运行环境下,却执行失败。在该Java程序处理中,“ping www.baidu.com&ipfocnif”被当做一个完整的字符串而非两个命令。因此不会存在漏洞。
由于我这现在只有JDK6的API手册,所以就先已JDK6的为准吧。
这里是对Runtime类的一个介绍。下面将看一下API手册对exec()的解释。
API上的意思是单独打开一个进程执行指定的命令,这个方法还有多个重载方法。
通过API里的可以看到要实行的命令可以通过字符串和数组的方式传入。
当传入的参数为字符串的时,会先经过StringTokening的处理,主要是针对空格及换行符等空白字符进行处理,后续会分割出一个cmdarray数组保存命令参数,cmdarray数组下标值为0的元素为所要执行的命令。
尽量不要执行外部传入的命令。
使用自定义函数或者函数库来替代外部命令的功能。
白名单保护
如果命令的参数有特征性的建议使用白名单对用户输入的参数进行校验过滤,从而进行保护。
黑名单保护
1、将常用参数编码做为黑名单过滤
2、一些特殊字符也需要做为黑名单校验,如\r\n\t\f以及\u0000 00截断等。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。