本文仅作为技术讨论及分享,严禁用于任何非法用途。
本文已在Freebuf发布,但文章经Freebuf编辑改动导致有小部分错误,故在这里改正并重新发布。
原文链接: https://www.freebuf.com/vuls/185380.html
前言
最近为甲方做渗透测试发现了一个远程命令执行漏洞,可以通过构造恶意参数传递执行bash命令,本文回顾一下漏洞的挖掘过程。
发现
- 通过
nessus
扫描器的Sitemap
模块,发现了可疑目录: - 根据
sitemap
的目录信息,打开URL:http://x.x.x.x:28076/file/
,发现存在未授权访问漏洞: - 逐个查看里面的文件,找到了一些比较有意思的JSP:
- 蒙了一下
dirFiles.jsp
的参数,发现使用path
作为参数名可列出目录、文件信息,URL:http://x.x.x.x:28076/file/dirFiles.jsp?path=.
- 同样的方法,发现
show.jsp
存在任意文件读取漏洞,URL:http://x.x.x.x:28076/file/show.jsp?path=/etc/passwd
- 结合上面的目录信息和任意文件读取漏洞,对JSP文件简单审计一下,发现
logContentNewest.jsp
会调用一个bash
脚本,便猜想能否使用它构造命令执行:
测试
logContentNewest.jsp
正常执行是这样的,可自定义path
参数的值,如/etc/passwd
,来查找这个文件里面的内容:- 分析
logContentNewest.jsp
和被调用的sh脚本,得知path
参数最终会传入sh脚本的FILE_PATH
变量,然后调用下面的判断逻辑。从下面代码我们可以看到,函数的功能是判断FILE_PATH
变量的值是否存在,而这个变量的值目前是可控的 - 最初想通过添加双引号闭合if条件判断参数注入命令,没有成功
1
payload: /etc/passwd" ];ls;then echo 1;fi;if [ -e "123.txt;
- 从上图可以看到,payload的双引号不见了,在自己的Linux测试一下,发现bash在这种情况下会过滤双引号,因此排除了存在过滤双引号的可能
- 经过多次测试,最终可用反引号
`
或者$()
进行命令执行,如ifconfig
1
payload:"`ifconfig`"
- 命令结果的回显是因为判断不存在
FILA_PATH
文件名的文件后,会把变量值返回,其源码如下:拓展知识: Linux bash中可以使用反引号1
echo "the file($FILE_PATH) dose not exist!"
`
或者$()
等方式将bash命令的执行结果保存到变量中,如FILE_PATH=$(ifconfig)
- 命令执行结果显示不完整,只能看到返回的第一行的结果,没关系,可以简单优化一下:拓展知识:
1
payload:"`ifconfig |xargs`"
xargs
可以将stdin中以空格或换行符进行分隔的数据,形成以空格分隔的参数(arguments),传递给其他命令。因为以空格作为分隔符,所以有一些文件名或者其他意义的名词内含有空格的时候,xargs
可能会误判。简单来说,xargs
是给其他命令传递参数的一个过滤器,是构建单行命令的重要组件之一。 但是这里仅仅只是通过xargs
的特性让它把多行内容转换成一行来更好地显示结果,当然也可以使用其他方法来实现。 - 再看看nmap内网扫描的结果,同样的漏洞组件在内网中还发现了很多…
小结
漏洞是由于程序调用bash脚本传参时没有做过滤,通过$(cmd)这样的方式来执行命令并将结果存入变量中,在脚本判断文件不存在时会返回文件名,造成了回显。
漏洞修复方法
严格控制文件名参数值,先判断文件名或文件路径是否合法可修复漏洞。