1.Command Injection 命令注入
命令注入(Command Injection)漏洞也称为远程命令/代码执行漏洞(RCE,Remote Command/Code Exec),指应用程序的某些功能需要调用可以执行系统命令的函数,如果这些函数或者函数的参数能被用户控制,就可能通过命令连接符将恶意命令拼接到正常的函数中,从而随意执行系统命令,属于高危漏洞之一。
命令注入是滥用应用web应用程序的行为从而实现在操作系统上执行命令,在执行命令时将获得与操作系统上应用程序相同的权限。
例如,在以user1的用户身份运行的Web服务器上执行命令注入,将在对应的操作系统用户user1权限下执行命令,从而获得用户user1所拥有的系统权限。
在Web应用中,有时候会用到一些命令执行的函数,如php中system、exec、shell_exec等,当对 用户输入的命令没有进行限制或者过滤不严导致用户可以执行任意命令时,就会造成命令执行漏洞。比如PHP中的eval()函数,可以将函数中的参数当做PHP代码来执行,如果这些函数的参数控制不严格,可能会被利用,造成任意代码执行。
例如,使用ping命令测试IP,正常输入一个IP或者域名会返回一个正常的返回结果。当输入恶意构造的语句www.baidu.com && netstat -an,会把后面的语句也给执行了。
具体的操作一样在pikachu靶场中已经复现
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 );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
$html .= "<pre>{$cmd}</pre>";
}
?>
获得一个ip,通过判断系统实现一个ping命令的执行,无任何过滤功能,可以直接利用以下命令
A; B //A不论正确与否都会执行B
A&B //A后台运行,A和B同时执行
A&&B //A执行成功后才会执行B
A|B //A执行的输出结果作为B命令的参数,A不论正确与否,都会执行B
A||B //A执行失败后才会执行B命令
medium等级
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Set blacklist
$substitutions = array(
'&&' => '',
';' => '',
);
// Remove any of the characters 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
$html .= "<pre>{$cmd}</pre>";
}
?>
medium等级的代码相比较于上一级增加了一个字符过滤功能
将&&和;通过str_replace函数进行过滤
我们可以利用其他管道符进行绕过,例如|,||,&符号
high等级
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = trim($_REQUEST[ 'ip' ]);
// Set blacklist
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
// Remove any of the characters 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
$html .= "<pre>{$cmd}</pre>";
}
?>
这段代码进行了更为严格的过滤,通过trim函数,用来去除字符串首尾处的空白字符(或者其他字符),增加了更多黑名单字符替换规则。
// Set blacklist
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
但是仔细观察,它的黑名单中的| 过滤,在|符号后面还有一个空格,我们可以选择使用如下payload进行绕过
127.0.0.1 |ipconfig
在|符号前面加一个空格进行绕过
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
$html .= "<pre>{$cmd}</pre>";
}
else {
// Ops. Let the user name theres a mistake
$html .= '<pre>ERROR: You have entered an invalid IP.</pre>';
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
这段代码采用了如下几种安全防护措施:
1.token机制:同之前的暴力破解一样,使用了token机制(基于token的身份验证),由于token值,每次交互都是随机的,客户端和服务端都为随机值。
2.stripslashes()函数:过滤字符串中的反斜杠
3.explode()函数:explode() 函数使用一个字符串分割另一个字符串,并返回由字符串组成的数组。就是将ip地址用.符号进行分割,便于检测分割后的内容是否为数字
4.is_numeric() 函数:用于检测变量是否为数字或数字字符串
检测到ip地址合法才进行ping命令,否则返回无效ip