命令执行漏洞: 命令执行漏洞是指可以随意执行系统命令,属于高危漏洞之一,也属于代码执行范围内。
当应用程序将不安全的用户提供的数据(表单,cookie,HTTP标头等)传递给系统shell时,可能会发生命令注入攻击。在此攻击中,攻击者提供的操作系统命令通常以易受攻击的应用程序的权限执行。命令注入攻击主要是由于输入验证不足。
环境 : 使用物理机(win10)访问搭建了DVWA的虚拟机(win7 x86),虚拟机的IP为 192.168.157.137
界面:
在输入框中输入想要测试的IP地址,发送给服务器,由服务器将ping后的结果返回给客户端并显示
Low
Low级别源码:
<?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 ); ke
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>
分析: 从源码可以看到,服务器直接得到用户输入的ip,在ip前拼接ping命令,放到服务器的shell里运行,没有任何的过滤
攻击思路: windows和Linux中有很多命令连接符,将攻击者想要运行的命令与之前的ping命令进行拼接,可以做到任意代码的执行。
命令拼接符
- &
& 在bat中使用
; 在bash中使用
顺序执行多条语句,不管命令是否执行成功
- &&
顺序执行多条语句,当碰到执行出错的命令后将不执行后面的命令
- ||
顺序执行多条命令,当碰到执行正确的命令,将不执行后面的命令
- |
管道命令,将上一个命令的输出当做下一个命令的输入
命令注入
在连接符后加上任意命令
添加用户:
注意: 若没有修改dvwaPage.inc.php文件的编码,这里会遇到乱码问题
解决方法: 在.\phpStudy\PHPTutorial\WWW\DVWA-master\dvwa\includes下将dvwaPage.inc.php中的所有utf-8替换为gb2312,返回物理机刷新页面.
Medium
Medium源码
<?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>";
}
?>
分析: 与Low级别源码相比较,只是将’&&‘和’;‘两个命令连接符过滤,但是命令连接符还有’||’,’|'等未过滤,仍然可以任意代码执行。如果非要用&&,可以使用&;&连接两条命令
命令注入
High
High源码
<?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>";
}
?>
分析: 看这个源码,看似将所有的连接符都过滤了,但是细心一点就会发现,
在管道符后有一个空格,所以在管道符后不加空格仍然可以使用管道符来进行命令注入
命令注入
Impossible
Impossible源码
<?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();
?>
分析: 无懈可击,检查token是否一致,避免CSRF攻击,将输入的IP用’.‘分割为四个部分,检查每一个部分是否为纯数字,如果都是数字,再将每个部分再用’.'连接执行。