命令执行漏洞
在十几年前,有这样一种情况,在各种测速网站上,只要输入一串命令,就很有可能拿下webshell。几乎随便找一个网站都能这么去搞。
归根结底,就是因为命令执行漏洞。现在,几乎找不到了这种问题了。先推荐一个网站:speedtest.cn。用来测试网速还是不错的。
0x00 漏洞的产生原因
1、代码层过滤不严格,应用程序直接或间接使用了动态执行命令的危险函数,并且这个函数的运行参数是可控的
2、系统的漏洞造成命令注入
0x01 漏洞的本质
应用有时需要调用执行系统命令的函数,当服务器没有严格过滤用户提供的参数时,就可能导致用户提交恶意代码被服务器执行,从而造成命令执行漏洞。
0x02 命令执行漏洞的危害
- 继承web服务器程序权限(web用户权限),去执行系统命令
- 继承web服务器权限,读写文件
- 反弹shell
- 控制整个网站
- 控制整个服务器
0x03 命令执行漏洞的防御
- 尽量少使用执行命令函数或者禁用disable_functions(php.ini)
- 在进入执行命令的函数之前,对参数进行过滤,对敏感字符进行转义
- 参数值尽量使用引号包括,并在拼接前调用addslashe进行转义
- 复习一下:addslashes给单引号、双引号、反斜杠进行转义
0x04 命令执行相关函数
system()
- 说明:能够将字符串作为OS命令执行,自带输出功能
- 测试参考代码
<?php
if(isset($_GET['cmd'])) //检测是否有输入
{
echo "";
system($_GET['cmd']); //传一个参数
}
?>
exec():只输出最后一行数据
- 说明:能够将字符串作为OS命令执行,但是无输出,需要输出执行结果
- 提交的URL:?cmd=whoami
- 测试参考代码
<?php
if(isset($_GET['cmd'])) //检测是否有输入
{
echo "";
exec($_GET['cmd']); //传一个参数
print exec($_GET['cmd']);
}
?>
这里的echo 和print都行
shell_exec()这个函数就不是只输出最后一行了
- 说明:执行命令并以字符串的形式,返回完整的信息,但是函数无回显,需要输出执行结果。
- 测试参考代码
<?php
$test = $_GET['cmd'];
if(isset($test))
{ echo '';
shell_exec($test);
print shell_exec($test);
}
?>
passthru()
- 说明:执行外部命令,与system()类似,但是该函数会直接将结果输出,无需输出执行。
- 测试参考代码[?cmd=ipconfig]
<?php
if(isset($_GET['cmd']))
{
echo "";
passthru($_GET['cmd']);
}
?>
popen()
- 说明:能够执行OS命令,但是该函数并不是返回命令结果,而是返回一个文件指针
- 提交的URL:[?cmd=whoami]
- 单尖号覆盖,双尖号追加
- 测试参考代码
<?php
$cmd=$_GET['cmd'].">>1.txt";
popen($cmd,'r');
?>
- 第一步,传一个我们想要的参数,按下回车的一瞬间,就会在popen.php同级目录下自动生成一个1.txt,里面就是我们想要查询的结果。
- 第二步,再去访问这个1.txt就行了
反引号
- 说明:反引号[``]内的字符串,也会被解析成OS命令,背后调用的是shell_exec()函数
- 测试参考代码
<?php
if(isset($_GET['cmd']))
{
$cmd=$_GET['cmd'];
print `$cmd`;
}
?>
0x05 漏洞的利用
权限问题
OS命令注入漏洞,攻击者直接继承Web用户权限,在服务器上执行任意命令,危害特别大。以下命令均在windows系统下测试成功
1、查看系统文件
?cmd=type c:\windows\system32\drivers\etc\hosts
2、显示当前路径
?cmd=cd
3、显示当前权限
?cmd=whoami
4、写文件
?cmd=echo "<?php phpinfo();?>" > C:\phpStudy\WWW\Commandi\shell.php
#页面没有报错,说明文件写入成功,访问shell.php文件,同理我们可以写入一个一句话木马
DVWA Command Injection Source源码分析
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) { //如果判断出来是windows系统
// Windows
$cmd = shell_exec( 'ping ' . $target ); //直接使用ping命令
}
else {
// *nix 如果是Linux或者Unix系统
$cmd = shell_exec( 'ping -c 4 ' . $target ); //使用ping -c 4
}
// Feedback for the end user
echo "{$cmd}
";
}
?>
相关函数介绍
stristr(string,serch,before_search)
stristr函数搜索字符串在另一字符串中的第一次出现,返回字符串的剩余部分(从匹配点),如果未找到所搜索的字符串,则返回FALSE。参数string规定被搜索的字符串,参数search规定要搜索的字符串(如果该参数是数字,则搜索匹配该数字对应的ASCII值的字符),可选参数before_true为布尔型,默认为"false",如果设置为“true”,函数将返回search参数第一次出现之前的字符串部分。
php_uname(mode) — 返回运行 PHP 的系统的有关信息,默认mode=a。a=snrvm里面的所有模式
s=操作系统名称;n=返回主机名;r=返回版本名;v=返回版本信息;m=返回机器类型
php_uname与linux中uname差不多
0x06 执行多命令执行语法
windows系统
命令格式 | 含义 |
---|---|
Command1 & Command2 | 先后执行1,2,无论1执行是否成功 |
Command1 && Command2 | 先后执行1,2,只有1执行成功才执行2 |
Command1 || Command2 | 先后执行1,2,只有1执行失败才执行2 |
Command1 | Command2 | | 管道符,将C1执行后输出的结果作为输入传递给C2 |
Linux系统
Linux唯一和Windows不一样的就是第一行命令这里,是分号
命令格式 | 含义 |
---|---|
Command1 ; Command2 | 先后执行1,2,无论1执行是否成功 |
Command1 && Command2 | 先后执行1,2,只有1执行成功才执行2 |
Command1 || Command2 | 先后执行1,2,只有1执行失败才执行2 |
Command1 | Command2 | | 管道符,将C1执行后输出的结果作为输入传递给C2 |
0x07 php常见的危险函数
代码执行函数
eval()
assert()
preg_replace()
create_function()
array_map()
call_user_func()
call_user_func_array()
array_filter()
命令执行函数
system()
exec()
popen()
passthru()
shell_exec()
Webshell中的一句话不使用命令执行函数的原因??
因为php代码执行函数包含了命令执行函数。命令执行函数仅仅是调用了系统底层的api而已。
0x08 远程命令执行漏洞
sturts2,phpunit,weblogic等等。。。都是远程命令执行漏洞。
Java结尾,URL后面是.do,.action,就可以用工具来看是不是这个漏洞。