命令执行漏洞
漏洞原理
命令执行漏洞(Command Execution Vulnerability)是指攻击者可以利用该漏洞在服务器上执行任意命令。这种情况通常发生在一个应用程序接受用户输入,并在没有适当验证和清理的情况下,直接将这些输入用作系统命令的一部分。
- 应用程序接受来自用户的输入
- 输入被直接插入到系统命令中
- 系统命令在服务器上执行
漏洞操作
常见系统命令
whoami:查看服务器用户名
ipconfig:查看本机IP地址子网掩码以及默认网关等
dir:查看本目录文件
nslookup:监测网络中DNS服务器是否能正确实现域名解析的命令行工具
ping:检查网络是否连通
cd + 文件夹名: 进入目录
cd… :返回上一级目录
md +文件夹名 :创建文件夹
常用命令拼接符号
1、||
格式:命令1||命令2…命令n
规则:或运算,如果命令1执行失败,执行命令2,如果命令1执行成功,则不执行命令2
2、|
格式:命令1|命令2…命令n
规则:当命令1执行成功时才执行命令2,如果命令1未执行成功则不会执行命令2
3、&&
格式:命令1&&命令2…命令n
规则:命令1和命令2一起执行,如果命令1出错命令2则不执行
4、&
格式:命令1&命令2…命令n
规则:命令1和命令2一起执行,互不影响
关键函数
system( string $command, int &$return_var = ?) : string
system()函数执行 command
参数所指定的命令,并且输出执行结果,使用 system()
函数可以在PHP脚本中调用系统命令
用法和返回值类似的函数还有passthru()
exec( string $command, array &$output = ?, int &$return_var = ?) : string
exec函数作用与system差不多,可以执行命令,但是不回显结果,只返回执行结果的最后一行。加上echo会显示结果
类似的函数有shell_exec()
绕过方法
1.拼接符绕过
在提交的数据后面利用拼接符连接系统命令,例如:见实战
2.空格绕过
见实战
3.base64绕过
Windows 系统并不原生支持 base64
命令。
4.拼接绕过
5.待完善…
实战 DVWA Command Injection
low级别
查看源码 view 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
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>
出现函数:
isset():检测变量是否设置,若变量存在且不为null就返回true,否则返回false。
只有在用户通过POST请求提交了一个名为 “Submit” 的表单字段时,才会执行以下代码块。
php_uname():返回运行php操作系统有关信息,参数为特定的单个字符
• ‘a’:此为默认。包含序列 “s n r v m” 里的所有模式。
• ‘s’:操作系统名称。例如: FreeBSD。
• ‘n’:主机名。例如: localhost.example.com。
• ‘r’:版本名称,例如: 5.1.2-RELEASE。
• ‘v’:版本信息。操作系统之间有很大的不同。
• ‘m’:机器类型。例如:i386
stristr():strstr()函数的忽略大小写版本,查找字符串的首次出现,返回字符串的一部分或false
代码没有任何过滤操作,也就是说代码会将用户提交的参数直接连接到 ping命令后面执行,可利用操作拼接符绕过,例如提交
127.0.0.1|whoami
此时相当于执行
ping 127.0.0.1|whoami
命令1是ping 127.0.0.1 ,成功后执行命令2 whoami,即会在浏览器输出主机信息。
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级别,增加了一个黑名单 $substitutions(相关知识点:关联数组)
出现函数:
str_replace ( mixed $search
, mixed $replace
, mixed $subject
)
该函数返回一个字符串或者数组。该字符串或数组是将 subject
中全部的 search
都被 replace
替换之后的结果
array_keys ( array $array
[, mixed $search_value
] )
返回 input
数组的键名组成的数组。
如果指定了可选参数 search_value
,则只返回该值的键名。否则 input
数组中的所有键名都会被返回。
分析代码,用户提交的数据中,‘&&’和‘;’会被替换成空字符,实现了简单的过滤,但不完全,使用& 或者 || 仍可绕过
high级别
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
其他代码相同,只是完善了黑名单
方法1.发现观察 ‘| ’ 过滤了 | + 空格,使用无空格 ’|‘ 绕过
方法2.使用“||”+空格绕过
漏洞利用:
- 数据泄露:攻击者可以运行任何命令来访问、修改、删除服务器上的数据。
- 服务中断:攻击者可以关闭服务或删除关键文件,导致服务无法运行。
- 服务器入侵:攻击者可以安装恶意软件,或者建立持久的后门访问。
漏洞防御
-
输入验证:确保所有用户输入都经过适当的验证。特别是对于可能被插入到命令中的输入,需要进行严格的验证和清理,最好使用白名单。
-
使用参数化接口:许多编程语言提供了可以防止命令注入的参数化接口。
-
限制命令执行:如果可能,尽量避免在应用程序中执行系统命令。如果必须执行命令,应限制命令的范围,并使用最小权限运行命令。